《二十三》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);
}

总结:

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

相关推荐
feifeigo1234 分钟前
python从环境变量和配置文件中获取配置参数
开发语言·python·adb
轩宇^_^4 分钟前
C语言结构体与联合体详解
c语言·开发语言
waterHBO8 分钟前
python 爬虫,爬取某乎某个用户的全部内容 + 写个阅读 app,慢慢读。
开发语言·爬虫·python
ahhhhaaaa-13 分钟前
【AI图像生成网站&Golang】部署图像生成服务(阿里云ACK+GPU实例)
开发语言·数据仓库·人工智能·后端·阿里云·golang
一只编程菜鸟19 分钟前
Java + easyexcel 新旧数据对比,单元格值标红
java·开发语言
笨笨马甲42 分钟前
扩展模块--QWebEngine功能及架构解析
qt·架构
fs哆哆1 小时前
在VB.net中,用正则表达式方法清除干扰符号方法
开发语言·正则表达式·c#·.net
嵌入式@秋刀鱼1 小时前
《 第三章-招式初成》 C++修炼生涯笔记(基础篇)程序流程结构
linux·开发语言·数据结构·c++·笔记·visual studio code
温温top1 小时前
java中合并音频
java·音视频
shenyan~1 小时前
关于 WASM: WASM + JS 混合逆向流程
开发语言·javascript·wasm