QT+ffmpeg+多线程的视频播放器
一、简述
视频播放器实质是快速的播放图片,一般情况下,人的眼睛一秒可以扫过25帧图片,这样看起来有视频播放的效果。有的人可能会想到通过把视频全部解码完,然后把解码后得到所有的图片保存下来再开始播放,那么问题来了,如果这个视频非常的大(有好几百兆),就会导致播放器都打开了迟迟没有响应的情况,使得体验感大大下降。
因此,我们可以进行边解码边播放,才有时效性,所以就引入了线程实现并发,界面是主线程,解码是子线程(详见我的博客:多线程的简单使用,这里不做过多阐述),下面就来实现边解码视频边在窗口播放的效果。
二、基本实现思路
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓
三、核心代码
视频的解码和多线程封装成的类fdecode,fdecode继承QThread,重写虚函数run
1、解码线程类fdecode.cpp:
QImage desImage = QImage((uchar*)buffer,codec->width,codec->height,
QImage::Format_RGB32,nullptr,nullptr);//RGB像素数据
//每解码一帧图像给显示窗口发送一个显示图像的信号
emit sendImage(desImage);//触发信号
msleep(25);//播放倍速设置,可以通过延时来调
void fdecode::registerFFmpeg()
{
av_register_all();//注册所有组件
}
void fdecode::run()//里面执行的是整个解码的流程
{
this->registerFFmpeg();
this->fileName = "Warcraft3_End.avi";
this->openVideoStream(this->fileName);
}
2、播放界面类playwidget.cpp:
#include "playwidget.h"
playWidget::playWidget()
{
this->resize(800,368);
//先创建解码线程对象
this->fdec = new fdecode();
connect(fdec,SIGNAL(sendImage(QImage)),this,SLOT(receiveImage(QImage)));//注意sendImage和receiveImage的参数
//启动解码线程
fdec->start();
}
void playWidget::paintEvent(QPaintEvent *)
{
QPainter painter(this);
if(!this->img.isNull())
{
painter.drawImage(QRect(0,0,800,368),this->img);
}
}
void playWidget::receiveImage(QImage img)
{
this->img = img;
this->update();
}
3、main.cpp
详细思路:
1、得到的每一帧RGB图像怎么处理?
每解码一帧图像给播放界面发送一个显示图像的信号
2、解码得到的图片怎么在播放界面显示?
使用信号和槽的机制(.h文件中一定要加Q_OBJECT)信号不需要实现,槽要实现
在解码这边得到一张图片就发送一个信号,播放界面收到信号就显示图片
信号写在解码线程类fdecode里,信号的参数要大于等于槽函数的参数
3、信号在哪触发?
解码线程类fdecode中解码生成一帧图片的时候(用emit触发)
4、在哪接收信号?
播放界面类中定义槽(public slots)用来接收信号
5、在播放界面接收图片要关联信号和槽,在哪里关联呢?
在播放界面的构造函数里面用connect
6、在播放界面构造函数里进行创建解码线程对象、启动解码线程(启动时就会调用run函数)、关联信号和槽
connect四个参数:信号发送者(解码线程对象)、发什么信号、 谁接收信号 、做什么事情
7、界面上接收的图片一直在变,怎么办?
接收到一张图片要保存到播放界面类中(定义QImage类成员接收),然后再绘制图片(重绘事件void paintEvent(QPaintEvent *);)
8、什么时候触发QPaintEvent?
不会一直调用,receiveImage中接收一张图片后,调用更新函数update触发
注意:
(1) 发信号的是谁,signal就在谁的.h中声明,接收的是谁,槽函数就在谁的.h中声明 (2) connect 在创建了新线程后执行,之后执行线程的start函数
如果你对音视频开发感兴趣,觉得文章对您有帮助,别忘了点赞、收藏哦!或者对本文的一些阐述有自己的看法,有任何问题,欢迎在下方评论区与我讨论!
本文福利, 免费领取C++音视频学习资料包、技术视频,内容包括(音视频开发,面试题,FFmpeg ,webRTC ,rtmp ,hls ,rtsp ,ffplay ,srs)↓↓↓↓↓↓见下面↓↓文章底部点击免费领取↓↓
相关文章
- Qt是什么?Qt简介(非常全面)
- qtabwidget切换tab_qt tablewidget
- QT多线程实战_Qt多线程开发项目
- C/C++ Qt StringListModel 字符串列表映射组件
- C/C++ Qt 基础通用组件的应用
- Qt的信号是私有还是公有
- Linux下Qt静态库编译与链接(linuxqt静态库)
- Qt QComboBox下拉框及用法(详解版)
- 调试Linux下Qt的调试实践指南(linux下qt)
- Linux安装Qt的步骤指导(linux怎么安装qt)
- Qt 静态编译在 Linux 的实践(qt静态编译linux)
- Qt for Linux:下载与安装指南(qt下载linux)
- Qt与Oracle的完美结合(qtoracle)
- Qt编程实现MySQL数据库调用(qt调用MySQL数据库)
- 在linux系统上安装qt安装包(qt安装包linux)
- Building Complex Database Applications Made Easy with Linux QT and SQL(linuxqtsql)
- 入门Linux下Qt编程,掌握技巧!(linux下qt编程入门)
- 轻松实现QT直连Microsoft SQL Server(qt直连mssql)
- Qt如何编译Oracle数据库驱动(qt编译oracle驱动)