1、概述💥
最近研究了一下FFmpeg开发,功能实在是太强大了,网上ffmpeg3、4的文章还是很多的,但是学习嘛,最新的还是不能放过,就选了一个最新的ffmpeg n5.1.2版本,和3、4版本api变化还是挺大的;
在这个Demo里主要使用Qt + FFmpeg开发一个【简易录屏软件】,这里主要使用的是【软解码】,需要使用硬解码的可以看之前的文章;
为了便于学习,这里只是录制视频图像,没有引入音频等信息;
由于录制的视频图像格式和保存的图像格式不一定相同,所以中间需要进行图像格式转换,这里使用的是FFmpeg自带的sws_scale(),听说libyuv性能更强,后续在研究研究。
开发环境说明
-
系统:Windows10、Ubuntu20.04
-
Qt版本:V5.12.5
-
编译器:MSVC2017-64、GCC/G++64
-
FFmpeg版本:n5.1.2 (注意:如果版本不对可能程序无法运行)
2、实现效果💨
抓取桌面图像转码后保存到本地视频文件中;
支持各种常见视频文件类型;
支持Windows、Linux录屏功能;
支持全屏录制功能、录制指定区域功能;
默认将录制视频保存到系统的视频文件夹下;
主要功能分为录屏线程、录屏解码、图像像素转换、编码保存4部分。
【学习地址】:FFmpeg/WebRTC/RTMP/NDK/Android音视频流媒体高级开发
【文章福利】:免费领取更多音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击1079654574加群领取哦~
3、FFmpeg录屏代码流程
-
白色部分: 主要为抓取桌面图像解码流程;
-
绿色部分: 将桌面图像转码/编码保存到视频文件。
4、主要代码
啥也不说了,直接上代码,一切有注释
4.1 videodecode.h文件
/******************************************************************************
* @文件名 videodecode.h
* @功能 视频解码类,在这个类中调用ffmpeg打开捕获桌面图像进行解码
*
* @开发者 mhf
* @邮箱 1603291350@qq.com
* @时间 2022/09/15
* @备注
*****************************************************************************/
#ifndef VIDEODECODE_H
#define VIDEODECODE_H
#include <QString>
#include <QSize>
#include <qfile.h>
#include <QPoint>
struct AVFormatContext;
struct AVCodecContext;
struct AVRational;
struct AVPacket;
struct AVFrame;
struct SwsContext;
struct AVBufferRef;
struct AVInputFormat;
struct AVStream;
class QImage;
class VideoDecode
{
public:
VideoDecode();
~VideoDecode();
bool open(const QString& url = QString()); // 打开媒体文件,或者流媒体rtmp、strp、http
AVFrame* read(); // 读取视频图像
void close(); // 关闭
bool isEnd(); // 是否读取完成
AVCodecContext* getCodecContext(){return m_codecContext;}
QPoint avgFrameRate(){return m_avgFrameRate;}
private:
void initFFmpeg(); // 初始化ffmpeg库(整个程序中只需加载一次)
void showError(int err); // 显示ffmpeg执行错误时的错误信息
qreal rationalToDouble(AVRational* rational); // 将AVRational转换为double
void clear(); // 清空读取缓冲
void free(); // 释放
private:
const AVInputFormat* m_inputFormat = nullptr;
AVFormatContext* m_formatContext = nullptr; // 解封装上下文
AVCodecContext* m_codecContext = nullptr; // 解码器上下文
AVPacket* m_packet = nullptr; // 数据包
AVFrame* m_frame = nullptr; // 解码后的视频帧
int m_videoIndex = 0; // 视频流索引
qint64 m_totalTime = 0; // 视频总时长
qint64 m_totalFrames = 0; // 视频总帧数
qint64 m_obtainFrames = 0; // 视频当前获取到的帧数
qreal m_frameRate = 0; // 视频帧率
QSize m_size; // 视频分辨率大小
char* m_error = nullptr; // 保存异常信息
bool m_end = false; // 视频读取完成
QPoint m_avgFrameRate;
};
#endif // VIDEODECODE_H
4.2 videodecode.cpp文件
#include "videodecode.h"
#include <QDebug>
#include <QImage>
#include <QMutex>
#include <qdatetime.h>
extern "C" {