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);
}
相关推荐
Dxy12393102161 小时前
JS发送请求的方法详解
开发语言·javascript·ecmascript
sw1213891 小时前
C++中的代理模式实战
开发语言·c++·算法
難釋懷1 小时前
Lua语法入门-条件控制、函数
开发语言·junit·lua
桌面运维家1 小时前
Win10打印机共享故障排查:权限与网络配置详解
开发语言·网络·php
Sunshine for you2 小时前
实时操作系统中的C++
开发语言·c++·算法
史蒂芬_丁2 小时前
C++深度拷贝例子
java·开发语言·c++
Knight_AL3 小时前
Nacos 启动问题 Failed to create database ’D:\nacos\nacos\data\derby-data’
开发语言·数据库·python
leiming63 小时前
CAN 通信协议学习讲义(带图文 + C 语言代码)
c语言·开发语言·学习
xht08324 小时前
PHP vs C语言:核心差异全解析
c语言·开发语言·php
yoothey4 小时前
Java字节流与字符流核心笔记(问答+考点复盘)
java·开发语言·笔记