Qt-FFmpeg开发-保存视频流裸流

本文介绍如何使用Qt和FFmpeg n5.1.2版本开发一个视频播放器,支持播放本地和网络视频流,并实现保存视频流裸流到本地的功能。通过软解码处理视频,不进行重新编码,降低资源占用。详细讲解了代码流程和关键部分的代码示例。

1、概述📸

  • 最近研究了一下FFmpeg开发,功能实在是太强大了,网上ffmpeg3、4的文章还是很多的,但是学习嘛,最新的还是不能放过,就选了一个最新的ffmpeg n5.1.2版本,和3、4版本api变化还是挺大的;

  • 在这个Demo里主要使用Qt + FFmpeg开发一个简单的【视频播放器】,支持【保存视频流裸流】功能,这里主要使用的是【软解码】,需要使用硬解码的可以看之前的文章;

  • 同时为了尽可能的简单,这里没有进行音频解码和播放,只是单独的进行视频解码播放;

  • 再日常开发中,经常有将播放的网络视频流图像保存到本地视频文件中的需求,但是如果将图像重新编码保存则会非常消耗CPU资源,裸流数据一般是H264格式的数据,这里其实可以直接将网络视频流未解码的AVPacket直接保存到视频文件中,不需要编码,可大大降低资源占用;

  • 并且直接保存裸流的代码流程不重新编码/转码保存的流程简单许多。

开发环境说明

  • 系统:Windows10、Ubuntu20.04

  • Qt版本:V5.12.5

  • 编译器:MSVC2017-64、GCC/G++64

  • FFmpeg版本:n5.1.2 (注意:如果版本不对可能程序无法运行)

2、实现效果💽

  1. ffmpeg音视频库【软解码】实现的视频播放器;

  2. 支持打开本地视频文件(如mp4、mov、avi等)、网络视频流(rtsp、rtmp、http等);

  3. 支持视频匀速播放;

  4. 采用QPainter进行显示,支持自适应窗口缩放;

  5. 视频播放支持实时开始/关闭、暂停/继续播放;

  6. 视频解码、线程控制、显示各部分功能分离,低耦合度。

  7. 采用最新的5.1.2版本ffmpeg库进行开发,超详细注释信息,将所有踩过的坑、解决办法、注意事项都得很写清楚。

  8. 在使用ffmpeg打开网络视频流时,如果是【h264裸流可以直接保存为本地文件】,不需要进行编码操作。

3、FFmpeg保存裸流代码流程💡

  • 白色部分: 主要为打开读取网络视频流、解码流程;

  • 绿色部分: 主要是打开输出文件,将裸流保存到文件的流程。

 【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发

【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~

4、主要代码🔍

啥也不说了,直接上代码,一切有注释

4.1 videodecode.h文件

/******************************************************************************
 * @文件名     videodecode.h
 * @功能       视频解码类,在这个类中调用ffmpeg打开视频进行解码,并且打开输出文件,将h264裸流保存
 *
 * @开发者     mhf
 * @邮箱       1603291350@qq.com
 * @时间       2022/09/15
 * @备注
 *****************************************************************************/
#ifndef VIDEODECODE_H
#define VIDEODECODE_H
​
#include <QString>
#include <QSize>
​
struct AVFormatContext;
struct AVCodecContext;
struct AVRational;
struct AVPacket;
struct AVFrame;
struct SwsContext;
struct AVBufferRef;
struct AVStream;
class QImage;
​
class VideoDecode
{
public:
    VideoDecode();
    ~VideoDecode();
​
    bool open(const QString& url = QString());    // 打开媒体文件,或者流媒体rtmp、strp、http
    QImage read();                               // 读取视频图像
    void close();                                 // 关闭
    bool isEnd();                                 // 是否读取完成
    const qint64& pts();                          // 获取当前帧显示时间
​
private:
    void initFFmpeg();                            // 初始化ffmpeg库(整个程序中只需加载一次)
    void showError(int err);                      // 显示ffmpeg执行错误时的错误信息
    qreal rationalToDouble(AVRational* rational); // 将AVRational转换为double
    void clear();                                 // 清空读取缓冲
    void free();                                  // 释放
    bool openSave();                              // 打开输出文件并初始化
​
private:
    AVFormatContext* m_formatContext = nullptr;   // 解封装上下文
    AVCodecContext*  m_codecContext  = nullptr;   // 解码器上下文
    SwsContext*      m_swsContext    = nullptr;   // 图像转换上下文
    AVPacket* m_packet = nullptr;                 // 数据包
    AVFrame*  m_frame  = nullptr;                 // 解码后的视频帧
    int    m_videoIndex   = 0;                    // 视频流索引
    qint64 m_totalTime    = 0;              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值