《二十三》Qt 简单小项目---视频播放器

QT 使用QMediaPlayer实现的简易视频播放器

效果如下:

功能点
  1. 播放指定视频
  2. 点击屏幕暂停/播放
  3. 开始/暂停/重置视频
  4. 拖拽到指定位置播放

类介绍

  • 需要在配置文件中加入Multimedia, MultimediaWidgets这俩个库。
  • Multimedia:提供了一套用于处理音频、视频、摄像头和广播数据的API。
  • MultimediaWidgets:提供了一些与多媒体相关的图形界面组件。
  • QVideoProbe是Qt多媒体模块中的一个类,它用于监控视频流的输出。这个类允许你接收视频帧的数据,而不需要直接与视频输出设备交互。
  • QMediaPlayer 使用生产者-消费者模型来处理媒体内容。它从媒体源(如文件或网络流)获取数据,然后通过播放控制接口(如播放、暂停、停止)和播放状态接口(如当前播放位置、总时长)来控制媒体内容的播放。
  • 使用 QMediaPlayer时,通常需要将其与一个或多个媒体输出组件结合使用,例如QVideoWidget用于视频播放,QAudioOutput用于音频播放。

注意:在Qt6 中使用QMediaPlayer时,使用的是setSource函数设置视频资源,而Qt5中并没有这个函数,使用的是setMedia函数。而且有个非常坑的地方,Qt6 设置完QVideoWidget直接使用没有问题,而Qt5就会存在问题。

信息栏会报错:

cpp 复制代码
DirectShowPlayerService::doRender: Unresolved error code 0x80040266 

在window上需安装LAV解码器的,并放在Qt的安装目录下
在Linux上个人验证并不需要安装

解决办法:QT无法播放视频:报错:DirectShowPlayerService::doRender: Unresolved error code 0x80040266-CSDN博客

代码介绍

我们需要在pro文件中先添加:

随后我们添加一个C++类,基类选择QVideoWidget,来定义一些鼠标和键盘事件:

复制代码
qmyselfvideo.h
cpp 复制代码
#include<QVideoWidget>
#include<QObject>
#include<QWidget>
#include<QMediaPlayer>

#include<QKeyEvent>
#include<QMouseEvent>

class QMySelfVideo : public QVideoWidget
{
public:
    QMySelfVideo(QWidget *parent=nullptr);

    void SetMediaPlayer(QMediaPlayer *player);

private:
    QMediaPlayer  *theplayer;

protected:
    void keyPressEvent(QKeyEvent *event);//键盘按键事件,当按键按下esc退出全屏
    void mousePressEvent(QMouseEvent *event);//鼠标按键时间,点击暂停和播放
};

qmyselfvideo.cpp

cpp 复制代码
#include "qmyselfvideo.h"

QMySelfVideo::QMySelfVideo(QWidget *parent):QVideoWidget(parent)
{

}

void QMySelfVideo::SetMediaPlayer(QMediaPlayer *player)
{
    //设置播放器操作
    theplayer=player;
}

void QMySelfVideo::keyPressEvent(QKeyEvent *event)//当播放器为全屏的时候,我们按下esc就可以退出全屏
{
    if((event->key()==Qt::Key_Escape)&&(isFullScreen())){
        setFullScreen(false);
        event->accept();
        QVideoWidget::keyPressEvent(event);
    }
}

void QMySelfVideo::mousePressEvent(QMouseEvent *event)//按下左键设置播放和暂停
{
    if(event->button()==Qt::LeftButton){
        if(theplayer->state()==QMediaPlayer::PlayingState){
            theplayer->pause();
        }else{
            theplayer->play();
        }
    }
    QVideoWidget::mousePressEvent(event);
}

注意:我们要对graphicsView进行提升,提升的类名就是我们刚刚创建的C++类名,因为它的基类就是QVideoWidget。

代码初始化定义:

cpp 复制代码
#include <QMainWindow>
#include"qmyselfvideo.h"
#include<QMediaPlayer>
#include<QMediaPlaylist>
#include<QVideoWidget>
#include<QFileDialog>

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;//播放器
    QString drtTime;//视频文件长度
    QString posTime;//播放视频的当前位置

private slots:
    void OnStateButtonChanged(QMediaPlayer::State state);//控制按钮状态
    void OndrtTimeChanged(qint64 drt);//视频文件时间长度,更新变化
    void OnposTimeChanged(qint64 pos);//播放视频当前位置时间更新变化
}

定义我们所需要的量,以及一些我们需要的槽函数来处理一些变化。

代码功能分析:

cpp 复制代码
#include "mainwindow.h"
#include "ui_mainwindow.h"

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

    player=new QMediaPlayer(this);
    player->setNotifyInterval(1000);
    player->setVideoOutput(ui->graphicsView);//视频显示组件

    ui->graphicsView->SetMediaPlayer(player);//设置显示组件的关联播放器
}

初始化,没什么好说的。

根据state的状态,来更新播放,暂停,停止按钮的状态:

cpp 复制代码
void MainWindow::OnStateButtonChanged(QMediaPlayer::State state)
{
    ui->pushButton_play->setEnabled(!(state==QMediaPlayer::PlayingState));
    ui->pushButton_pause->setEnabled(state==QMediaPlayer::PlayingState);
    ui->pushButton_stop->setEnabled(state==QMediaPlayer::PlayingState);
}

根据视频的长度来显示时长,格式:已经播放的时长/总时长 。时间是:分:秒。将设置好的时长显示在我们添加的label中显示

cpp 复制代码
void MainWindow::OndrtTimeChanged(qint64 drt)
{
    ui->horizontalSlide_speedr->setMaximum(drt);

    int sec=drt/1000;//总时长
    int min=sec/60;//分
    sec=sec%60;//秒

    drtTime=QString::asprintf("%d:%d",min,sec);
    ui->label_speed->setText(posTime+"|"+drtTime);
}

void MainWindow::OnposTimeChanged(qint64 pos)
{
    if(ui->horizontalSlide_speedr->isSliderDown()){
        return;//如果正在拖动滑动条,则直接退出
    }
    ui->horizontalSlide_speedr->setSliderPosition(pos);

    int sec=pos/1000;
    int min=sec/60;
    sec=sec%60;

    posTime=QString::asprintf("%d:%d",min,sec);
    ui->label_speed->setText(posTime+"|"+drtTime);
}

槽函数链接:

cpp 复制代码
connect(player,SIGNAL(stateChanged(QMediaPlayer::State)),this,SLOT(OnStateButtonChanged(QMediaPlayer::State)));
    connect(player,SIGNAL(positionChanged(qint64)),this,SLOT(OnposTimeChanged(qint64)));
    connect(player,SIGNAL(durationChanged(qint64)),this,SLOT(OndrtTimeChanged(qint64)));

根据状态改变来连接相应的槽函数 。

按钮滑动条槽函数 :

cpp 复制代码
    void on_pushButton_open_clicked();//打开文件
    void on_pushButton_play_clicked();//播放
    void on_pushButton_pause_clicked();//暂停
    void on_pushButton_stop_clicked();//停止
    void on_pushButton_Volumn_clicked();//声音
    void on_horizontalSlider_Volumn_valueChanged(int value);//声音滑动条
    void on_horizontalSlide_speedr_valueChanged(int value);//进度条

对于open:

cpp 复制代码
void MainWindow::on_pushButton_open_clicked()
{
    QString currentpath=QDir::homePath();//获得系统当前目录
    QString dlgtitle="请选择视频文件";
    QString filter="所有文件(*.*);;mp4文件(*.mp4)";//文件过滤器
    QString strfile=QFileDialog::getOpenFileName(this,dlgtitle,currentpath,filter);

    if(strfile.isEmpty()){
        return;
    }
    QFileInfo fileinfo(strfile);
    ui->label_name->setText(fileinfo.fileName());
    player->setMedia(QUrl::fromLocalFile(strfile));//设置播放文件
    player->play();
}

我们首先获取文件的位置路径,在设置文件过滤器来获取我们所需要的MP4文件格式,最后设置播放文件进行播放。

其他开始,暂停等一些按钮槽函数:

cpp 复制代码
void MainWindow::on_pushButton_play_clicked()
{
    player->play();
}

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

void MainWindow::on_pushButton_stop_clicked()
{
    player->stop();
}

void MainWindow::on_pushButton_Volumn_clicked()
{
    bool bmute=player->isMuted();
    player->setMuted(!bmute);
    //根据是否静音来显示音量图标
    if(bmute){
        ui->pushButton_Volumn->setIcon(QIcon(":/icon/sound.png"));
    }else{
        ui->pushButton_Volumn->setIcon(QIcon(":/icon/mute.png"));
    }
}

void MainWindow::on_horizontalSlider_Volumn_valueChanged(int value)
{
    player->setVolume(value);
}

void MainWindow::on_horizontalSlide_speedr_valueChanged(int value)
{
    player->setPosition(value);
}

总结:

只是一个简单视频播放器,博主能力有限还在学习当中。大家可自行尝试修改改进。

相关推荐
道不尽世间的沧桑17 分钟前
第17篇:网络请求与Axios集成
开发语言·前端·javascript
久绊A25 分钟前
Python 基本语法的详细解释
开发语言·windows·python
软件黑马王子4 小时前
C#初级教程(4)——流程控制:从基础到实践
开发语言·c#
cpp_learners4 小时前
QT 引入Quazip和Zlib源码工程到项目中,无需编译成库,跨平台,压缩进度
qt·zlib·加密压缩·quazip
闲猫4 小时前
go orm GORM
开发语言·后端·golang
李白同学5 小时前
【C语言】结构体内存对齐问题
c语言·开发语言
黑子哥呢?7 小时前
安装Bash completion解决tab不能补全问题
开发语言·bash
青龙小码农7 小时前
yum报错:bash: /usr/bin/yum: /usr/bin/python: 坏的解释器:没有那个文件或目录
开发语言·python·bash·liunx
大数据追光猿7 小时前
Python应用算法之贪心算法理解和实践
大数据·开发语言·人工智能·python·深度学习·算法·贪心算法
彳卸风8 小时前
Unable to parse timestamp value: “20250220135445“, expected format is
开发语言