一、前言
跌跌撞撞摸爬滚打一步步迭代完善到今天,这个视频监控控件的设计,在现阶段水平上个人认为是做的最棒的(稍微自恋一下),理论上来说应该可以用5年不用推翻重写,推翻重写当然也是程序员爱干的事情,这个就要考验个人的功底,设计的好框架搭建的好,可以很多年不用变,只需要在现有框架小修小补即可,最多就是继承基类实现一些特殊性的功能,设计的不好,可能每个月都要重写,这种不断的迭代也是无法避免的,毕竟需求一直在变化,当现有的框架无法满足老板或者用户的需求的时候,就必须大动干戈的推翻重来了,纵观Qt的发展史,基本上也是这样的,Qt4时代一个大版本,Qt5时代又是一个大版本,到了Qt6又是一个大版本,互相不兼容,而且很多模块的结构都变了,甚至类名都改了,可能是为了表达的更贴切。不过近期Qt的版本彪的着实厉害,这点需要批评一下。
极致设计功能点:
- 支持多种解码内核,比如ffmpeg/vlc/mpv/qtav/qmedia/各种厂家sdk等。
- 参数灵活多变,两大类结构体,一种窗体相关参数WidgetPara,一种视频处理相关参数VideoPara。
- 同时支持句柄(vlc/mpv/厂家SDK都提供了句柄方式)、绘制(回调拿到视频原始数据通过painter绘制)、GPU(采集到视频数据用opengl绘制yuv/nv12/rgb)三种视频显示模式。
- 具备常规基础接口,开始播放、暂停播放、继续播放、停止播放、音量大小、静音切换、抓拍图片、开始录像、暂停录像、停止录像。
- 具备常规信号接口,文件时长、播放进度、音量变化、静音状态、抓图完成、收到图片、播放开始、播放结束等信号。
- 支持音视频文件(mp3、wav、mp4、asf、rm、rmvb、mkv等)、视频流(rtsp、rtmp、http、rtp等)、本地摄像机、桌面等。
- 共享解码线程,打开同地址直接复用解码,不用重复解码,极大降低CPU占用,多路完全实时同步。
- 使用极其简单,定义结构体参数后直接open打开即可,几行代码就能正常使用。
二、效果图
三、体验地址
四、功能特点
1. 基础功能
2. 特色功能
3. 视频控件
五、相关代码
1. 将内核相关文件 core_audio、core_video、core_videobase、core_videoffmpeg 拷贝放到对应目录。
2. 在你的项目的pro文件引入上面的组件并增加对应内核定义。../表示上级目录。
DEFINES += ffmpeg videoffmpeg ffmpeg4
include($$PWD/../core_audio/core_audio.pri)
include($$PWD/../core_video/core_video.pri)
include($$PWD/../core_videobase/core_videobase.pri)
include($$PWD/../core_videoffmpeg/core_videoffmpeg.pri)
3. 使用代码
#include "mainwindow.h"
#include "videowidgetx.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
VideoWidget w;
w.resize(800, 600);
VideoPara para = w.getVideoPara();
para.videoCore = VideoCore_FFmpeg;
w.setVideoPara(para);
w.show();
w.open("f:/mp4/push/1.mp4");
return a.exec();
}
public slots:
//开始播放
virtual void play();
//停止播放
virtual void stop();
//暂停播放
virtual void pause();
//继续播放
virtual void next();
//抓拍截图
virtual void snap(const QString &snapName = QString());
//截图完成
virtual void snapFinsh(const QImage &image);
//开始录制
virtual void recordStart(const QString &fileName);
//暂停录制
virtual void recordPause();
//停止录制
virtual void recordStop();
//写入视频数据到文件
void writeVideoData(int width, int height, quint8 *dataY, quint8 *dataU, quint8 *dataV);
//写入音频数据到文件
void writeAudioData(const char *data, qint64 len);
void writeAudioData(const QByteArray &data);
//设置标签信息集合
virtual void setOsdInfo(const QList &listOsd);
//设置图形信息集合
virtual void setGraphInfo(const QList &listGraph);
signals:
//播放成功
void receivePlayStart(int time);
//播放结束
void receivePlayFinsh();
//播放失败
void receivePlayError(int error);
//收到一张图片
void receiveImage(const QImage &image, int time);
//抓拍一张图片
void snapImage(const QImage &image, const QString &snapName);
//视频尺寸变化
void receiveSizeChanged();
//录制状态变化
void recorderStateChanged(const RecorderState &state, const QString &file);
//收到一帧rgb视频数据
void receiveFrame(int width, int height, quint8 *dataRGB, int type);
//收到一帧yuv视频数据
void receiveFrame(int width, int height, quint8 *dataY, quint8 *dataU, quint8 *dataV, quint32 linesizeY, quint32 linesizeU, quint32 linesizeV);
//收到一帧nv12视频数据
void receiveFrame(int width, int height, quint8 *dataY, quint8 *dataUV, quint32 linesizeY, quint32 linesizeUV);
//音量大小
void receiveVolume(int volume);
//静音状态
void receiveMuted(bool muted);
//音频数据振幅
void receiveLevel(qreal leftLevel, qreal rightLevel);
//视频实时码率
void receiveKbps(qreal kbps, int frameRate);