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);
}
相关推荐
ALex_zry8 分钟前
内核开发者的视角:C与Rust在系统编程中的哲学与实践
c语言·开发语言·rust
u***45168 分钟前
Windows安装Rust环境(详细教程)
开发语言·windows·rust
友友马9 分钟前
『QT』窗口 (二) - 深入剖析 QDialog 对话框机制与内存管理
开发语言·qt
TracyCoder12310 分钟前
Java后端Redis客户端选型指南
java·开发语言·redis
筱砚.13 分钟前
【C++——文件操作案例】
开发语言·c++
Zfox_19 分钟前
【Go】 协程和 channel
开发语言·后端·golang
向上_5035829134 分钟前
Android之kotlin学习
开发语言·学习·kotlin
木易 士心35 分钟前
Kotlin vs Swift:现代移动开发的“双子星”全面对比
开发语言·kotlin·swift
I_ltt_Itw,37 分钟前
Python协程学习笔记
开发语言·网络·python
大雨淅淅38 分钟前
【编程语言】Kotlin:从新手到大神的进阶之路
android·开发语言·kotlin