QT 6.6.0 + FFmpeg + SDL2实现音频视频播放(改进)

B站视频讲解

GitHub源码下载地址

目录

实现思路

链队列实现

第一步:构建结构体数据结构

第二步:初始化链队列

第三步:向链队列中加入数据

第四步:从队列中取出数据 


初学案例教程
QT6.6.0实现打开电脑摄像头或其他的外接摄像头(实现拍照功能)
QT6.6.0实现简单的录音器
QT6.6.0实现一个简单的视频和音频播放器
QT6.6.0实现简单的视频录制(包含语音录制)器
QT6.6.0关于QMediaMetaData功能以及列子说明使用方法
QT6.6.0实现QtCamera功能(拍照,录像以及图像和视频的相关配置)
T6.6.0实现更好的视频播放器(前期改进)
QT6.6.0实现图表如饼图,柱状图,散点图以及盒图等的基本使用
QT6.6.0实现客户端Socket编程以及socket测试软件通信
QT6.6.0 实现服务端Server和多个客户端Client通信以及socket测试软件通信
QT6.6.0 实现QNetworkAccessManager的基本应用以及其拓展使用
QT6.6.0 实现服务端Server和多个客户端Client互相发送文件信息
QT6.6.0和QT6.0以下的版本实现FTP文件上传和下载(过程详解)
QT6.6.0实现QNetworkInterface网络接口,QHostAddress网络地址IP以及域名解析等相关信息查询。
QT6.6.0基于QTcpSocket和QTcpServer实现多个客户端群聊
QT6.6.0实现基于UDP协议的简单通信(过程详解)
QT 6.6.0基于UDP协议实现广播和多播机制(过程详解)
QT 6.6.0基于UDP协议实现群聊功能(过程详解)
QT 6.6.0中OpenCV两种环境的配置方法以及基本使用例子
QT 6.6.0 中基于OpenCV的图像变换以及基于鼠标点击移动事件的图像绘制
QT 6.6.0 基于OpenCV对图像进行旋转,缩放和裁剪等操作
QT 6.6.0 基于OpenCV实现图像风格的改变(add和subtract)
PyTorch 训练之后的网络模型.pth转.onnx文件并对图像进行预测
QT 6.6.0 基于OpenCV加载.pth模型文件转换之后的ONNX模型文件,并且实现图像分类
QT 6.6.0 基于OpenCV中的cv::dnn::ClassificationModel实现图像分类
yolov5目标检测和QT 6.6.0 基于OpenCV加载yolov5.onnx模型文件实现目标检测
FCN图像分割和QT 6.6.0 加载分割FCN_Resnet50.ONNX模型文件进行图像分割(过程详解)
QT 6.6.0 中基于SDL2库实现WAV音频格式的播放(过程详解)
QT 6.6.0 中SDL2库的基本使用以及利用SDL2库创建的界面实现音频播放(过程详解)
QT 6.6.0 中基于SDL2,SDL2_ttf,SDL2_image,SDL2_mixer实现音频播放器(改进版)
QT 6.6.0 + SDL2 + SDL2_mixer实现音频播放器(改进)
QT 6.6.0 中基于FFmpeg + SDL2 + SDL2_mixer实现音频录音(过程详解)
QT 6.6.0 + FFmpeg + SDL2实现MP4视频播放(过程详解)
QT 6.6.0 + FFmpeg + SDL2实现视频播放器(视频和音频同时播放-改进)

        第一篇关于FFmpeg + SDL2实现视频播放的博文仅仅只是实现了视频的播放,并没有实现音频的播放;第二篇关于FFmpeg + SDL2实现视频播放的博文是在第一篇的基础上进行改进实现了音视频的播放;而这篇博文还是关于FFmpeg + SDL2实现视频播放,到这里,可能会有小伙伴会问了,怎么还是音视频播放呢?有什么改进吗?

        如果看了第二篇关于FFmpeg + SDL2实现视频播放博文的小伙伴应该知道,那篇博文中我们最终确实是实现了音视频播放,并且其中使用了多线程 + 互斥量 + 条件变量,但是也有小伙伴应该发现了如果要把该功能拓展到比如实现暂停,快进等功能的话,不容易。因此,本文是基于前面的博文进行改进,使用链队列来保存音频数据,参考了链接1 和 链接2 。

以下是这次实现的整体思路:

实现思路

  1. 创建窗口和渲染器,用于视频文件的选择,播放以及程序关闭
  2. 选择视频MP4文件
  3. 根据打开的视频文件,得到视频流和音频流其对应的流索引号,用于后面视频帧和音频数据读取时所用
  4. 找到对应的视频流和音频流索引号的同时,分别找到对应的视频和音频解码信息
  5. 读取视频数据,并判断当前的数据为视频帧数据还是音频数据
    1.  如果为视频帧数据,
      1.  视频帧解码(视频帧的缩放和转换操作)
      2.  实时更新视频帧
    2. 如果为音频数据
      1.  读取音频数据(根据音频流索引号判断当前是否为音频数据)
      2. 向链队列中加入音频数据
        1.  加锁Mutex
        2.  将音频数据加入链队列中
        3.  发送信号通知
        4.  解锁Mutex
      3.  从链队列中取出音频数据
        1.  加锁Mutex
        2. 判断链队列中是否有数据可取
        3. 如果有数据集可取,即可取出并进行音频数据解码
        4. 如果没有数据可取,则等待信号通知
        5. 解锁Mutex
  6.    视频播放完成之后,关闭播放窗口,可以继续选择播放或者选择其他视频文件播放
  7. 关闭主线程窗口,完全结束视频播放。

注:上面的改进是否比之前变得更加复杂了,主要是因为便于后期进行功能上的拓展。

链队列实现

        如果对链队列已经忘记或者不是很清楚的小伙伴,建议先去了解一下,然后下面我将画一个用于本文的链队列结构:

第一步:构建结构体数据结构

typedef struct Packet {
    AVPacket av_packet; //记录节点的数据
    struct Packet* next; //指向下一个节点
    int serial; //暂时未用到
} Packet;

struct PacketQueue {
    Packet * first_pkt,*last_pkt; //分别用于指向链队列的头部和尾部
    int nb_packets; //记录节点的个数
    int size; //记录当前已经加入到链队列中节点的所有数据
    SDL_mutex * mutex; //用于互斥加锁
    SDL_cond * cond; //用于等待信号通知和发送信号
};

第二步:初始化链队列

第三步:向链队列中加入数据

注:每一行的注释都已经写出来了,向链队列中加入加入数据是从指向最后一个节点开始加入的,取出数据是从链队列的头部开始的,因为加入数据的顺序是从头部开始的。

第四步:从队列中取出数据 

注:取出数据的过程从头部开始,节点数减一,注意取出头部的数据之后记得释放节点的资源。

QT 6.6.0 + FFmpeg+SDL2实现音频视频播放

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值