最终效果

播放截图

videplayer.h


#ifndef VIDEPLAYER_H
#define VIDEPLAYER_H

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

QT_BEGIN_NAMESPACE
namespace Ui { class VidePlayer; }
QT_END_NAMESPACE

class VidePlayer : public QMainWindow
{
    Q_OBJECT

public:
    explicit VidePlayer(QWidget *parent = nullptr);
    ~VidePlayer() override;

private slots:
    void openfile();
    // void playPause();
    // void playStop();
    void positionChanged(qint64 pos);
    void durationChanged(qint64 duration);
    // void setPostion(int postion);

private:
    Ui::VidePlayer *ui;

    QMediaPlayer* player;
    QAudioOutput* audioOutput;
    QVideoWidget* videoWidget;

    bool isSliderPressed;
    bool isPlaying;
};
#endif // VIDEPLAYER_H

videplayer.cpp


#include "videplayer.h"
#include "ui_videplayer.h"
#include <QDebug>
#include <QFile>

VidePlayer::VidePlayer(QWidget *parent)
    : QMainWindow(parent), ui(new Ui::VidePlayer), isPlaying(false), isSliderPressed(false)
{
    ui->setupUi(this);

    // 创建播放器对象
    player = new QMediaPlayer(this);

    // 音频输出
    audioOutput = new QAudioOutput(this);
    player->setAudioOutput(audioOutput);

    // 视频窗口
    videoWidget = new QVideoWidget(this);


    // 放入 UI 的 widget_video 中
    QVBoxLayout* layout = new QVBoxLayout(ui->widget_video);

    layout->setContentsMargins(0,0,0,0);

    layout->addWidget(videoWidget);

    // 设置视频输出
    player->setVideoOutput(videoWidget);

    // 默认音量
    // audioOutput->setVolume(0.5);
    ui->horizontalSlider_volume->setValue(50);
    connect(ui->horizontalSlider_volume, &QSlider::valueChanged, this, [=](int value) {
                audioOutput->setVolume(
                    value / 100.0 );
            });

    ui->pushButton_add->setIcon(QIcon(".\\icons\\add.png"));
    ui->pushButton_play->setIcon(QIcon(".\\icons\\play.png"));
    ui->pushButton_pause->setIcon(QIcon(".\\icons\\pause.png"));
    ui->pushButton_stop->setIcon(QIcon(".\\icons\\stop.png"));
    ui->pushButton_sound->setIcon(QIcon(".\\icons\\vol.png"));

    connect(ui->pushButton_add, &QPushButton::clicked, this, &VidePlayer::openfile);
    connect(ui->pushButton_play, &QPushButton::clicked, player, &QMediaPlayer::play);
    connect(ui->pushButton_pause, &QPushButton::clicked, player, &QMediaPlayer::pause);
    connect(ui->pushButton_stop, &QPushButton::clicked, player, &QMediaPlayer::stop);

    // connect(player, &QMediaPlayer::positionChanged, this, &VidePlayer::positionChanged);
    // connect(ui->horizontalSlider_pos, &QSlider::sliderMoved, this, &VidePlayer::setPostion);
    // 播放位置变化
    connect(player, &QMediaPlayer::positionChanged, this, &VidePlayer::positionChanged);

    // 视频总时长变化
    connect(player, &QMediaPlayer::durationChanged, this, &VidePlayer::durationChanged);

    // 用户按下 slider
    connect(ui->horizontalSlider_pos, &QSlider::sliderPressed, this, [=]() {
                isSliderPressed = true;
            });

    // 用户释放 slider
    connect(ui->horizontalSlider_pos, &QSlider::sliderReleased, this, [=]() {
                isSliderPressed = false;

                player->setPosition(
                    ui->horizontalSlider_pos->value() * 1000 );
            });
    // 播放失败
    connect(player, &QMediaPlayer::errorOccurred, this,
            [=](QMediaPlayer::Error error, const QString &errorString) {
                qDebug() << error << errorString;
            });
}

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

void VidePlayer::openfile()
{
    QString fileName =
        QFileDialog::getOpenFileName(this, "选择视频", "", "Video Files (*.mp4 *.avi *.mkv)");

    if(fileName.isEmpty())
        return;

    player->setSource(QUrl::fromLocalFile(fileName));

    player->play();

    QFileInfo fileInfo(fileName);
    QString name = fileInfo.completeBaseName();
    ui->label_cur_media->setText(name);

    isPlaying = true;
}

// void VidePlayer::playPause()
// {
//     if(isPlaying)
//     {
//         player->pause();
//     }
//     else
//     {
//         player->play();
//     }

//     isPlaying = !isPlaying;
// }

// void VidePlayer::playStop()
// {
//     player->stop();
// }

void VidePlayer::positionChanged(qint64 pos)
{
    // 用户正在拖动时
    // 不自动更新 slider
    if(isSliderPressed) return;

    ui->horizontalSlider_pos->setValue(pos / 1000);
    int sec = pos / 1000;
    int min = sec / 60;
    sec = sec % 60;

    ui->label_pos->setText(
        QString("%1:%2")
            .arg(min, 2, 10, QChar('0'))
            .arg(sec, 2, 10, QChar('0'))
        );
}

void VidePlayer::durationChanged(qint64 duration)
{
    ui->horizontalSlider_pos->setRange(0, duration / 1000);
}

// void VidePlayer::setPostion(int postion)
// {
//     player->setPosition(postion);
// }