Qt-视频播放器

一、概述

本项目使用 QMediaPlayerQAudioOutput 分离的音频架构采用 QVideoWidget 作为视频输出组件,为Qt6风格语法。项目结构简单,适合初学者或想熟悉Qt6新风格的程序员。

仓库:https://github.com/orpheanlive/Qt-video.git

二、内容

.h

cpp 复制代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMediaPlayer>
#include <QAudioOutput>
#include <QVideoWidget>

QT_BEGIN_NAMESPACE
namespace Ui {
class MainWindow;
}
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QMediaPlayer *player;
    QAudioOutput *audioOutput;
    QString drtTime;
    QString posTime;

private slots:
    void onPlaybackStateChanged(QMediaPlayer::PlaybackState state);
    void onDurationChanged(qint64 duration);
    void onPositionChanged(qint64 position);
    void onMediaStatusChanged(QMediaPlayer::MediaStatus status);
    void onErrorOccurred(QMediaPlayer::Error error, const QString &errorString);

    void on_file_clicked();
    void on_play_clicked();
    void on_pause_clicked();
    void on_stop_clicked();
    void on_sound_clicked();
    void onVolumeSliderChanged(int value);
    void onProgressSliderReleased();
};
#endif // MAINWINDOW_H

.cpp

cpp 复制代码
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QFileDialog>
#include <QDir>
#include <QFileInfo>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 初始化媒体播放器
    player = new QMediaPlayer(this);
    audioOutput = new QAudioOutput(this);
    player->setAudioOutput(audioOutput);

    // 设置视频输出到UI中的videoWidget
    player->setVideoOutput(ui->videoWidget);

    // 连接信号槽
    connect(player, &QMediaPlayer::playbackStateChanged, this, &MainWindow::onPlaybackStateChanged);
    connect(player, &QMediaPlayer::durationChanged, this, &MainWindow::onDurationChanged);
    connect(player, &QMediaPlayer::positionChanged, this, &MainWindow::onPositionChanged);
    connect(player, &QMediaPlayer::mediaStatusChanged, this, &MainWindow::onMediaStatusChanged);
    connect(player, &QMediaPlayer::errorOccurred, this, &MainWindow::onErrorOccurred);

    // 设置初始音量
    audioOutput->setVolume(0.7);

    // 初始化按钮状态
    ui->play->setEnabled(true);
    ui->pause->setEnabled(false);
    ui->stop->setEnabled(false);

    qDebug() << "Media player initialized successfully";
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::onPlaybackStateChanged(QMediaPlayer::PlaybackState state)
{
    qDebug() << "Playback state:" << state;

    switch (state) {
    case QMediaPlayer::StoppedState:
        ui->play->setEnabled(true);
        ui->pause->setEnabled(false);
        ui->stop->setEnabled(false);
        break;
    case QMediaPlayer::PlayingState:
        ui->play->setEnabled(false);
        ui->pause->setEnabled(true);
        ui->stop->setEnabled(true);
        break;
    case QMediaPlayer::PausedState:
        ui->play->setEnabled(true);
        ui->pause->setEnabled(false);
        ui->stop->setEnabled(true);
        break;
    default:
        break;
    }
}

void MainWindow::onDurationChanged(qint64 duration)
{
    qDebug() << "Duration changed:" << duration;
    ui->progressSlider->setRange(0, duration);

    int sec = duration / 1000;
    int min = sec / 60;
    sec = sec % 60;
    int hour = min / 60;
    min = min % 60;

    if (hour > 0) {
        drtTime = QString::asprintf("%02d:%02d:%02d", hour, min, sec);
    } else {
        drtTime = QString::asprintf("%02d:%02d", min, sec);
    }

    ui->timeLabel->setText(posTime + " / " + drtTime);
}

void MainWindow::onPositionChanged(qint64 position)
{
    if (!ui->progressSlider->isSliderDown()) {
        ui->progressSlider->setValue(position);
    }

    int sec = position / 1000;
    int min = sec / 60;
    sec = sec % 60;
    int hour = min / 60;
    min = min % 60;

    if (hour > 0) {
        posTime = QString::asprintf("%02d:%02d:%02d", hour, min, sec);
    } else {
        posTime = QString::asprintf("%02d:%02d", min, sec);
    }

    ui->timeLabel->setText(posTime + " / " + drtTime);
}

void MainWindow::onMediaStatusChanged(QMediaPlayer::MediaStatus status)
{
    qDebug() << "Media status:" << status;
}

void MainWindow::onErrorOccurred(QMediaPlayer::Error error, const QString &errorString)
{
    qDebug() << "Media player error:" << error << errorString;
    ui->fileNameLabel->setText("错误: " + errorString);
}

void MainWindow::on_file_clicked()
{
    QString currentpath = QDir::currentPath();
    QString dlgtitle = "请选择视频文件";
    QString filter = "视频文件 (*.mp4 *.avi *.mkv *.mov *.wmv *.flv);;"
                     "所有文件 (*.*)";

    QString strfile = QFileDialog::getOpenFileName(this, dlgtitle, currentpath, filter);

    if (strfile.isEmpty()) {
        qDebug() << "No file selected";
        return;
    }

    QFileInfo fileinfo(strfile);
    QString fileName = fileinfo.fileName();
    ui->fileNameLabel->setText("文件: " + fileName);

    qDebug() << "Selected file:" << strfile;

    // 停止当前播放
    player->stop();

    // 设置媒体源
    QUrl fileUrl = QUrl::fromLocalFile(strfile);
    player->setSource(fileUrl);

    qDebug() << "Setting source to:" << fileUrl;



}

void MainWindow::on_play_clicked()
{

        player->play();

}

void MainWindow::on_pause_clicked()
{
    player->pause();
}

void MainWindow::on_stop_clicked()
{
    player->stop();
    ui->progressSlider->setValue(0);
    posTime = "00:00";
    ui->timeLabel->setText(posTime + " / " + drtTime);
}

void MainWindow::on_sound_clicked()
{
    bool muted = audioOutput->isMuted();
    audioOutput->setMuted(!muted);

    // 更新按钮文本
    if (audioOutput->isMuted()) {
        ui->sound->setText("静音");
    } else {
        ui->sound->setText("声音");
    }
}

void MainWindow::onVolumeSliderChanged(int value)
{
    float volume = value / 100.0f;
    audioOutput->setVolume(volume);

    // 自动静音/取消静音
    if (value == 0 && !audioOutput->isMuted()) {
        audioOutput->setMuted(true);
        ui->sound->setText("静音");
    } else if (value > 0 && audioOutput->isMuted()) {
        audioOutput->setMuted(false);
        ui->sound->setText("声音");
    }
}

void MainWindow::onProgressSliderReleased()
{
    qint64 position = ui->progressSlider->value();
    player->setPosition(position);
}
相关推荐
程序员buddha2 小时前
C语言数组详解
c语言·开发语言·算法
又是忙碌的一天2 小时前
Java IO流
java·开发语言
fish_study_csdn2 小时前
Python内存管理机制
开发语言·python·c python
ghie90904 小时前
MATLAB/Simulink水箱水位控制系统实现
开发语言·算法·matlab
cs麦子4 小时前
C语言--详解--指针--上
c语言·开发语言
像风一样自由20204 小时前
Go语言入门指南-从零开始的奇妙之旅
开发语言·后端·golang
IT阳晨。5 小时前
【QT开发】交叉编译QT程序在ARMLinux平台上运行
c++·qt·交叉编译·armlinux·代码移植
CoderYanger5 小时前
前端基础——CSS练习项目:百度热榜实现
开发语言·前端·css·百度·html·1024程序员节
虾..6 小时前
C++ 哈希
开发语言·c++·哈希算法