QT:基于QMediaPlayer制作的视频播放器(最下方有整合包,可直接运行)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: QMediaPlayer是Qt多媒体模块中的一个核心类,它提供了播放音频和视频内容的功能。这个类的设计旨在简化跨平台的媒体播放,使得开发者能够在多种操作系统(如Linux、Windows、macOS及移动平台)上轻松集成多媒体播放能力到他们的应用中,而无需关心底层实现细节。以下是关于QMediaPlayer的一些关键点:

目录

QT版本:5.11.1

视频播放器成效:

视频播放器功能:

QMediaPlayer介绍:

功能特性

MainWindow.h:

MainWindow.cpp:

ui设计:

缺点:

整合资源包地址:


QT版本:5.11.1

视频播放器成效:

image.gif 编辑

视频播放器功能:

       1. 支持外地导入文件,外地拖拽文件到列表中

       2. 支持一键静音,一键返回上次音量

       3. 支持空格暂停播放,ESC关闭窗口

       4. 支持拖放进度条控制视频速度

       5. 支持倍速播放

       6. 支持一键清空列表

       7. 支持快进10S,快退10S

       8. 支持一键放大缩小

       9. 支持点击列表元素播放视频

因为QMediaPlayer需要解码器去解析视频,而QT并不自带,所以我们需要去下载一下。

百度网盘:

链接:https://pan.baidu.com/s/1EoGhiNDOGkwaiJzjuY1zNw?pwd=qwer
提取码:qwer

GitHub:

Releases · Nevcairiel/LAVFilters (github.com)

image.gif 编辑

安装在自己的QT目录下即可

image.gif 编辑

QMediaPlayer介绍:

QMediaPlayer是Qt多媒体模块中的一个核心类,它提供了播放音频和视频内容的功能。这个类的设计旨在简化跨平台的媒体播放,使得开发者能够在多种操作系统(如Linux、Windows、macOS及移动平台)上轻松集成多媒体播放能力到他们的应用中,而无需关心底层实现细节。以下是关于QMediaPlayer的一些关键点:

功能特性

  • 媒体播放:支持播放各种音频和视频文件格式,支持的格式依赖于底层操作系统提供的解码器。例如,在Linux下通常使用GStreamer,Windows下使用DirectShow,Android和iOS则分别使用它们各自的多媒体框架。
  • 流媒体播放:除了本地文件,QMediaPlayer还能够播放网络流媒体资源,如HTTP直播流(HLS)、RTSP流等。
  • 状态管理:QMediaPlayer提供了多种状态枚举,如PlayingPausedStopped等,以及媒体状态(如LoadingMediaBufferingMediaStalledMedia),允许开发者监控播放器的当前状态。
  • 信号与槽:QMediaPlayer发出多种信号,如stateChanged()mediaStatusChanged(),开发者可以通过连接这些信号到自定义的槽函数,实现对播放事件的响应和控制。
  • 视频输出:为了显示视频内容,QMediaPlayer可以与QVideoWidget、QOpenGLWidget或自定义的QAbstractVideoSurface结合使用。
  • 音频输出:音频可以通过默认音频输出播放,也可以通过QAudioOutput类进行更细致的控制,比如调整音量、选择音频输出设备等。
  • 播放列表管理:虽然QMediaPlayer本身不直接管理播放列表,但它可以与QMimeData和QMediaPlaylist等类协作,实现播放列表功能。
  • 资源与缓冲:支持媒体资源的加载、缓冲管理以及错误处理,可以通过属性和信号监测缓冲进度和错误状态。

      我们还需要一个播放视频的组件,类似于被投屏的幕布,正是QVideoWidget,他可以接收QMediaPlayer解析的视频流。这里对于他仅仅只作用了接收的功能,在此就不细讲,大家有时间可以去了解一下。

MainWindow.h:

 

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWidgets>
#include <QSlider>
#include <QMouseEvent>
#include <QFileDialog>
#include <QMediaPlayer>
#include <QVideoWidget>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    void MediaInit();
    void dragEnterEvent(QDragEnterEvent *event);
    void dragLeaveEvent(QDragLeaveEvent *event);
    void dragMoveEvent(QDragMoveEvent *event);
    void dropEvent(QDropEvent *event);
    ~MainWindow();
private slots:
    void on_actionimport_file_triggered();
    void on_Begin_clicked();
    void onItemDoubleClicked(QListWidgetItem * item);
    void showListWidgetMenuSlot(QPoint);
    void deleteAllData();
    void GetDuration(qint64);
    void upDateSlider(qint64);
    void slot_PlayError(QMediaPlayer::Error);
    void on_back_clicked();
    void on_advance_clicked();
    void ChangeVoice(int);
    void MoveVideo(int);
    void on_fullScreen_clicked();
    void on_volumeData_clicked();
    void on_action_h_Help_triggered();
    void keyPressEvent(QKeyEvent *event);
    void on_Speed_currentIndexChanged(const QString &arg1);
private:
    Ui::MainWindow *ui;
    QMediaPlayer *Player;
    QVideoWidget *videoWidget;
    QListWidget *DataList;
    QMenu *Menu;
    QAction *deleteAll;
    QString totalFormatTime;
    QString currentFormatTime;
    int back_volume = 0;
    int flag_back_volume = 0;
};
#endif // MAINWINDOW_H

image.gif

MainWindow.cpp:

#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //初始化
    this->MediaInit();
}
MainWindow::~MainWindow()
{
    delete ui;
}
// 初始化函数
void MainWindow::MediaInit() {
    this->setWindowTitle("乌龟牌播放器");
    this->setWindowIcon(QPixmap(":/Icon/Icon/tortoiseTitleIcon.png"));
    // 初始化变量
    Player = new QMediaPlayer(this);
    videoWidget = new QVideoWidget(this);
    DataList = new QListWidget(this);
    Menu = new QMenu(this);
    deleteAll = new QAction("删除全部", this);
    // 功能性设置
    DataList->setContextMenuPolicy(Qt::CustomContextMenu);
    Menu->addAction(deleteAll);
    ui->videoSlider->setSingleStep(0);
    ui->Begin->setDisabled(true);
    ui->back->setDisabled(true);
    ui->advance->setDisabled(true);
    this->setAcceptDrops(true);
    // ui布局
    this->DataList->setStyleSheet("QListView {  font: 25 9pt Microsoft YaHei;border: 15px solid white;border-radius: 10px;}"
                                  "QListView::item {height: 60px;}"
                                  "QListView::item:hover {background-color: transparent;padding: 10px;border-left: 3px solid rgb(130, 130, 130);}"
                                  "QListView::item:selected { background-color: transparent;color: black;padding: 10px;border-left: 3px solid black;}");
    ui->horizontalLayout->addWidget(videoWidget,10);
    ui->horizontalLayout->addWidget(DataList,0);
    ui->fullScreen->setIcon(QPixmap(":/Icon/Icon/magnify.png"));
    ui->fullScreen->setIconSize(QSize(20,20));
    ui->Begin->setIcon(QPixmap(":/Icon/Icon/begin.png"));
    ui->Begin->setIconSize(QSize(20,20));
    ui->back->setIcon(QPixmap(":/Icon/Icon/back.png"));
    ui->back->setIconSize(QSize(20,20));
    ui->advance->setIcon(QPixmap(":/Icon/Icon/advance.png"));
    ui->advance->setIconSize(QSize(20,20));
    ui->volumeData->setIcon(QPixmap(":/Icon/Icon/volumeHigh.png"));
    ui->volumeData->setIconSize(QSize(20,20));
    // 信号
    connect(DataList, &QListWidget::itemDoubleClicked, this, &MainWindow::onItemDoubleClicked);
    connect(DataList, SIGNAL(customContextMenuRequested(QPoint)),this, SLOT(showListWidgetMenuSlot(QPoint)));
    connect(deleteAll,SIGNAL(triggered()),this,SLOT(deleteAllData()));
    connect(Player, SIGNAL(durationChanged(qint64)), this, SLOT(GetDuration(qint64)));
    connect(Player, SIGNAL(positionChanged(qint64)), this, SLOT(upDateSlider(qint64)));
    connect(Player, SIGNAL(error(QMediaPlayer::Error)),this,SLOT(slot_PlayError(QMediaPlayer::Error)));
    connect(ui->volumeSlider, SIGNAL(valueChanged(int)), this, SLOT(ChangeVoice(int)));
    connect(ui->videoSlider, SIGNAL(sliderMoved(int)), this, SLOT(MoveVideo(int)));
}
void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    event->accept();
}
void MainWindow::dragLeaveEvent(QDragLeaveEvent *event)
{
    event->accept();
}
void MainWindow::dragMoveEvent(QDragMoveEvent *event)
{
    event->accept();
}
void MainWindow::dropEvent(QDropEvent *event)
{
    QString name;
    QList<QUrl> urls;
    QList<QUrl>::Iterator i;
    urls = event->mimeData()->urls();
    for(i = urls.begin(); i != urls.end(); ++i) {
        name = i->path();
        this->DataList->addItem(name);
    }
    Player->setMedia(QUrl::fromLocalFile(name));
    Player->setVideoOutput(videoWidget);
    Player->play();
}
// 错误提示
void MainWindow::slot_PlayError(QMediaPlayer::Error error) {
    QString text;
    if(QMediaPlayer::NoError==error)
    {
        text="正常解码!";
    }
    else if(QMediaPlayer::ResourceError==error)
    {
        text="媒体资源无法解析。";
    }
    else if(QMediaPlayer::FormatError==error)
    {
        text="不支持该媒体资源的格式,没有解码器!";
    }
    else if(QMediaPlayer::NetworkError==error)
    {
        text="发生网络错误。";
    }
    else if(QMediaPlayer::AccessDeniedError==error)
    {
        text="没有适当的权限来播放媒体资源。";
    }
    else if(QMediaPlayer::ServiceMissingError==error)
    {
        text="没有找到有效的播放服务,播放无法继续。";
    }
    QMessageBox::critical(this,"播放器提示",text,QMessageBox::Ok,QMessageBox::Ok);
}
// 更新进度条
void MainWindow::upDateSlider(qint64 position) {
    ui->Begin->setDisabled(false);
    ui->back->setDisabled(false);
    ui->advance->setDisabled(false);
    if(ui->videoSlider->isSliderDown()) {
        return;
    }
    double num_p = position;
    double num_d = Player->duration();
    ui->videoSlider->setSliderPosition(100 * num_p / num_d);
    QTime currentTime(0, 0, 0, 0);
    currentTime = currentTime.addMSecs(position);
    currentFormatTime = currentTime.toString("mm:ss");
    ui->BeginTime->setText(currentFormatTime);
}
// 获取视频时间信息
void MainWindow::GetDuration(qint64 duration) {
    QTime totalTime = QTime(0, 0, 0, 0);
    totalTime = totalTime.addMSecs(duration);
    totalFormatTime = totalTime.toString("mm:ss");
    ui->EndTime->setText(totalFormatTime);
}
void MainWindow::showListWidgetMenuSlot(QPoint) {
    Menu->exec(QCursor::pos());
}
// 清空列表
void MainWindow::deleteAllData() {
    DataList->clear();
    Player->stop();
    ui->Begin->setIcon(QPixmap(":/Icon/Icon/begin.png"));
    ui->Begin->setIconSize(QSize(20,20));
}
// 导入
void MainWindow::on_actionimport_file_triggered()
{
    QString strCurrentPath = QDir::homePath();
    QString stdDlgTitle = "请选择视频文件";
    QString strFilter = "MP4 File(*.mp4);;All File(*.*)";
    QString strAllFiles = QFileDialog::getOpenFileName(this, stdDlgTitle,
                                                       strCurrentPath,strFilter);
    if(strAllFiles.isEmpty()) {
        QMessageBox::information(this,"错误","打开视频文件失败,请重新检查",QMessageBox::Yes|QMessageBox::No);
        return;
    }
    QFileInfo fileInfos(strAllFiles);
    qDebug() << "File info: " << fileInfos.fileName() << ", path: " << fileInfos.filePath();
    DataList->addItem(fileInfos.filePath());
    Player->setMedia(QUrl::fromLocalFile(strAllFiles));
    Player->setVideoOutput(videoWidget);
    Player->play();
}
// 双击
void MainWindow::onItemDoubleClicked(QListWidgetItem * item) {
    QString itemStr = item->text();
    Player->setMedia(QUrl::fromLocalFile(itemStr));
    Player->setVideoOutput(videoWidget);
    Player->play();
}
// 开始/暂停
void MainWindow::on_Begin_clicked()
{
    if(Player->state() ==  QMediaPlayer::PlayingState) {
        ui->Begin->setIcon(QPixmap(":/Icon/Icon/begin.png"));
        Player->pause();
    } else {
        ui->Begin->setIcon(QPixmap(":/Icon/Icon/pause.png"));
        Player->play();
    }
}
// 回退
void MainWindow::on_back_clicked()
{
    qint64 currentpos = Player->position();
    Player->setPosition(currentpos - 10000);//在原来的基础上前进10s
}
// 前进
void MainWindow::on_advance_clicked()
{
    qint64 currentpos = Player->position();
    Player->setPosition(currentpos + 10000);//在原来的基础上前进10s
}
// 全屏
void MainWindow::on_fullScreen_clicked()
{
    if(this->isFullScreen()) {
        this->showNormal();
        ui->fullScreen->setIcon(QPixmap(":/Icon/Icon/magnify.png"));
    } else {
        this->showFullScreen();
        ui->fullScreen->setIcon(QPixmap(":/Icon/Icon/lessen.png"));
    }
}
// 倍速
void MainWindow::on_Speed_currentIndexChanged(const QString &arg1)
{
    Player->setPlaybackRate(arg1.toDouble());
}
// 一键静音
void MainWindow::on_volumeData_clicked()
{
    if(++flag_back_volume % 2 != 0) {
        back_volume = ui->volumeValue->text().toInt();
    }
    if(ui->volumeValue->text().toInt() != 0) {
        ui->volumeSlider->setValue(0);
        Player->setVolume(0);
        ui->volumeValue->setText(QString::number(0));
        ui->volumeData->setIcon(QPixmap(":/Icon/Icon/volumeCross.png"));
    } else {
        ui->volumeSlider->setValue(back_volume);
        Player->setVolume(back_volume);
        ui->volumeValue->setText(QString::number(back_volume));
        ui->volumeData->setIcon(QPixmap(":/Icon/Icon/volumeHigh.png"));
    }
}
// 更新音量
void MainWindow::ChangeVoice(int volumeData) {
    Player->setVolume(volumeData);
    ui->volumeValue->setText(QString::number(volumeData));
    if(volumeData == 0) {
        ui->volumeData->setIcon(QPixmap(":/Icon/Icon/volumeCross.png"));
    } else {
        ui->volumeData->setIcon(QPixmap(":/Icon/Icon/volumeHigh.png"));
    }
}
//更新视频进度
void MainWindow::MoveVideo(int videoData) {
    double num_d = Player->duration();
    Player->setPosition(videoData * 1000 * (num_d / 100000));
}
// 捕获键盘事件
void MainWindow::keyPressEvent(QKeyEvent *event) {
    qDebug() << event->key();
    switch (event->key()) {
    case Qt::Key_Escape:
        if(!this->isFullScreen()) {
            QMessageBox:: StandardButton result= QMessageBox::information(this, "information", "是否要关闭窗口?",QMessageBox::Yes|QMessageBox::No);
            if(result == QMessageBox::Yes) {
                this->close();
            }
        } else {
            on_fullScreen_clicked();
        }
        break;
    case Qt::Key_Space:
        on_Begin_clicked();
        break;
    default:
        break;
    }
}
void MainWindow::on_action_h_Help_triggered()
{
    QDesktopServices::openUrl(QUrl(QString("https://blog.csdn.net/LKHzzzzz?spm=1000.2115.3001.5343")));
}

image.gif

ui设计:

image.gif 编辑

缺点:

       我在最后的时候想实现一个鼠标预览并显示当前画面帧的功能,但是毕竟是QMediaPlayer解析的视频帧,而且QSlider并没有鼠标停留的这个信号,所以这两个类都需要我们去重写,虽然QMediaPlayer非常方便,但是在功能发展上确是有着不小的限制,如果我们使用一些协议类似于ffmpeg这种去解析感觉会更好,在解析速度优化上也可以更近一步。

整合资源包地址:

       微信关注嵌入式工程之家回复乌龟牌播放器即可获得整合包哦~

相关文章
|
6月前
【Qt 学习笔记】使用QtCreator创建及运行项目 | 项目初始代码解释
【Qt 学习笔记】使用QtCreator创建及运行项目 | 项目初始代码解释
962 1
|
6月前
|
存储 C语言 Windows
音视频使用qt测试ffmpeg接口时无法运行
音视频使用qt测试ffmpeg接口时无法运行
112 0
|
3月前
|
安全 C++ Windows
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
|
6月前
|
编译器
QT creator开发环境下 界面更改后运行程序不能实时更新或者在源文件添加该控件后无法编译的问题
在使用QT Creator开发界面的过程中,偶尔会出现添加控件后,运行程序后,界面控件无法更新的情况,或者在源文件使用该控件却出现无法编译的情况,使用QT Creator 4.8.2也会出现这个情况,也不知道这种情况会不会在以后有所改善。
276 0
|
4月前
|
Linux 开发者 iOS开发
QT:基于QMediaPlayer制作的视频播放器(最下方有整合包,可直接运行)
QMediaPlayer是Qt多媒体模块中的一个核心类,它提供了播放音频和视频内容的功能。这个类的设计旨在简化跨平台的媒体播放,使得开发者能够在多种操作系统(如Linux、Windows、macOS及移动平台)上轻松集成多媒体播放能力到他们的应用中,而无需关心底层实现细节。以下是关于QMediaPlayer的一些关键点:
|
安全 测试技术 C++
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
最近用到了gRPC,配置了很长时间,分享一下配置过程。先来看一下我准备的文件包(资源我放在最后)
Windows下C++使用gRPC(Qt和VS,含文件包和使用方法)
|
6月前
|
SQL 安全 数据库连接
【Qt运行流程详解】从启动到事件循环的深入解读
【Qt运行流程详解】从启动到事件循环的深入解读
472 3
|
4月前
|
数据安全/隐私保护 C++ 计算机视觉
Qt(C++)开发一款图片防盗用水印制作小工具
文本水印是一种常用的防盗用手段,可以将文本信息嵌入到图片、视频等文件中,用于识别和证明文件的版权归属。在数字化和网络化的时代,大量的原创作品容易被不法分子盗用或侵犯版权,因此加入文本水印成为了保护原创作品和维护知识产权的必要手段。 通常情况下,文本水印可以包含版权声明、制作者姓名、日期、网址等信息,以帮助识别文件的来源和版权归属。同时,为了增强防盗用效果,文本水印通常会采用字体、颜色、角度等多种组合方式,使得水印难以被删除或篡改,有效地降低了盗用意愿和风险。 开发人员可以使用图像处理技术和编程语言实现文本水印的功能,例如使用Qt的QPainter类进行文本绘制操作,将文本信息嵌入到图片中,
178 1
Qt(C++)开发一款图片防盗用水印制作小工具
|
3月前
|
监控 C++ 容器
【qt】MDI多文档界面开发
【qt】MDI多文档界面开发
87 0
|
2月前
|
开发工具 C++
qt开发技巧与三个问题点
本文介绍了三个Qt开发中的常见问题及其解决方法,并提供了一些实用的开发技巧。

推荐镜像

更多