首页 » 互联网 » Qt/C++音视频开拓55-加密保存到文件并解密播放_视频_控件

Qt/C++音视频开拓55-加密保存到文件并解密播放_视频_控件

南宫静远 2024-12-26 17:12:48 0

扫一扫用手机浏览

文章目录 [+]

查阅资料得知,加密和未加密的文件,便是在头部数据中stbl下新增加了3个box。

senc:sample specific encryption data,特定加密数据样本。
saio:sample auxiliary information offsets,样本赞助信息偏移量。
saiz:sample auxiliary information sizes,样本赞助信息大小。
二、效果图

Qt/C++音视频开拓55-加密保存到文件并解密播放_视频_控件 Qt/C++音视频开拓55-加密保存到文件并解密播放_视频_控件 互联网

三、体验地址海内站点:https://gitee.com/feiyangqingyun国际站点:https://github.com/feiyangqingyun个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652体验地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_video_demo。
四、功能特点1. 根本功能支持各种音频视频文件格式,比如mp3、wav、mp4、asf、rm、rmvb、mkv等。
支持本地摄像头设备,可指定分辨率、帧率。
支持各种视频流格式,比如rtp、rtsp、rtmp、http等。
本地音视频文件和网络音视频文件,自动识别文件长度、播放进度、音量大小、静音状态等。
文件可以指定播放位置、调节音量大小、设置静音状态等。
支持倍速播放文件,可选0.5倍、1.0倍、2.5倍、5.0倍等速率,相称于慢放和快放。
支持开始播放、停滞播放、停息播放、连续播放。
支持抓拍截图,可指定文件路径,可选抓拍完成是否自动显示预览。
支持录像存储,手动开始录像、停滞录像,部分内核支持停息录像后连续录像,跳过不须要录像的部分。
支持无感知切换循环播放、自动重连等机制。
供应播放成功、播放完成、收到解码图片、收到抓拍图片、视频尺寸变革、录像状态变革等旗子暗记
多线程处理,一个解码一个线程,不卡主界面。
2. 特色功能同时支持多种解码内核,包括qmedia内核(Qt4/Qt5/Qt6)、ffmpeg内核(ffmpeg2/ffmpeg3/ffmpeg4/ffmpeg5)、vlc内核(vlc2/vlc3)、mpv内核(mpv1/mp2)、海康sdk、easyplayer内核等。
非常完善的多重基类设计,新增一种解码内核只须要实现极少的代码量,就可以运用整套机制。
同时支持多种画面显示策略,自动调度(原始分辨率小于显示控件尺寸则按照原始分辨率大小显示,否则等比缩放)、等比缩放(永久等比缩放)、拉伸添补(永久拉伸添补)。
所有内核和所有视频显示模式下都支持三种画面显示策略。
同时支持多种视频显示模式,句柄模式(传入控件句柄交给对方绘制掌握)、绘制模式(回调拿到数据后转成QImage用QPainter绘制)、GPU模式(回调拿到数据后转成yuv用QOpenglWidget绘制)。
支持多种硬件加速类型,ffmpeg可选dxva2、d3d11va等,mpv可选auto、dxva2、d3d11va,vlc可选any、dxva2、d3d11va。
不同的系统环境有不同的类型选择,比如linux系统有vaapi、vdpau,macos系统有videotoolbox。
解码线程和显示窗体分离,可指定任意解码内核挂载到任意显示窗体,动态切换。
支持共享解码线程,默认开启并且自动处理,当识别到相同的视频地址,共享一个解码线程,在网络视频环境中可以大大节约网络流量以及对方设备的推流压力。
海内顶尖视频厂商均采取此策略。
这样只要拉一起视频流就可以共享到几十个几百个通道展示。
自动识别视频旋转角度并绘制,比如手机上拍摄的视频一样平常是旋转了90度的,播放的时候要自动旋转处理,不然默认是倒着的。
自动识别视频流播放过程等分辨率的变革,在视频控件上自动调度尺寸。
比如摄像机可以在利用过程中动态配置分辨率,当分辨率改动后对应视频控件也要做出同步反应。
音视频文件无感知自动切换循环播放,不会涌现切换期间黑屏等肉眼可见的切换痕迹。
视频控件同时支持任意解码内核、任意画面显示策略、任意视频显示模式。
视频控件悬浮条同时支持句柄、绘制、GPU三种模式,非绝对坐标移来移去。
本地摄像头设备支持指定设备名称、分辨率、帧率进行播放。
录像文件同时支持打开的视频文件、本地摄像头、网络视频流等。
瞬间相应打开和关闭,无论是打开不存在的视频或者网络流,探测设备是否存在,读取中的超时等待,收到关闭指令立即中断之前的操作并相应。
支持打开各种图片文件,支持本地音视频文件拖曳播放。
视频控件悬浮条自带开始和停滞录像切换、声音静音切换、抓拍截图、关闭视频等功能。
音频组件支持声音波形值数据解析,可以根据该值绘制波形曲线和柱状声音条,默认供应了声音振幅旗子暗记。
标签和图形信息支持三种绘制办法,绘制到遮罩层、绘制到图片、源头绘制(对应信息可以存储到文件)。
各组件中极其详细的打印信息提示,尤其是报错信息提示,封装的统一打印格式。
针对现场繁芜的设备环境测试极其方便有用,相称于精确定位到详细哪个通道哪个步骤出错。
代码框架和构造优化到最优,性能刁悍,持续迭代更新升级。
源码支持Qt4、Qt5、Qt6,兼容所有版本。
3. 视频控件可动态添加任意多个osd标签信息,标签信息包括名字、是否可见、字号大小、文本笔墨、文本质彩、标签图片、标签坐标、标签格式(文本、日期、韶光、日期韶光、图片)、标签位置(左上角、左下角、右上角、右下角、居中、自定义坐标)。
可动态添加任意多个图形信息,这个非常有用,比如人工智能算法解析后的图形区域信息直接发给视频控件即可。
图形信息支持任意形状,直接绘制在原始图片上,采取绝对坐标。
图形信息包括名字、边框大小、边框颜色、背景颜色、矩形区域、路径凑集、点坐标凑集等。
每个图形信息都可指定三种区域中的一种或者多种,指定了的都会绘制。
内置悬浮条控件,悬浮条位置支持顶部、底部、左侧、右侧。
悬浮条控件参数包括边距、间距、背景透明度、背景颜色、文本质彩、按下颜色、位置、按钮图标代码凑集、按钮名称标识凑集、按钮提示信息凑集。
悬浮条控件一排工具按钮可自定义,通过构造体参数设置,图标可选图形字体还是自定义图片。
悬浮条按钮内部实现了录像切换、抓拍截图、静音切换、关闭视频等功能,也可以自行在源码中增加自己对应的功能。
悬浮条按钮对应实现了功能的按钮,有对应图标切换处理,比如录像按钮按下后会切换到正在录像中的图标,声音按钮切换后变成静音图标,再次切换还原。
悬浮条按钮单击后都用名称唯一标识作为旗子暗记发出,可以自行关联相应处理。
悬浮条空缺区域可以显示提示信息,默认显示当前视频分辨率大小,可以增加帧率、码流大小等信息。
视频控件参数包括边框大小、边框颜色、焦点颜色、背景颜色(默认透明)、笔墨颜色(默认全局笔墨颜色)、添补颜色(视频外的空缺处添补玄色)、背景笔墨、背景图片(如果设置了图片优先取图片)、是否拷贝图片、缩放显示模式(自动调度、等比缩放、拉伸添补)、视频显示模式(句柄、绘制、GPU)、启用悬浮条、悬浮条尺寸(横向为高度、纵向为宽度)、悬浮条位置(顶部、底部、左侧、右侧)。
五、干系代码

bool FFmpegSave::initStream(){ AVDictionary options = NULL; QByteArray fileData = fileName.toUtf8(); const char url = fileData.data(); //既可以是保存到文件也可以是推流(对应格式要区分) const char format = "mp4"; if (videoIndexIn < 0 && audioCodecName == "mp3") { format = "mp3"; } if (fileName.startsWith("rtmp://")) { format = "flv"; } else if (fileName.startsWith("rtsp://")) { format = "rtsp"; av_dict_set(&options, "stimeout", "3000000", 0); av_dict_set(&options, "rtsp_transport", "tcp", 0); } else if (fileName.startsWith("udp://")) { format = "mpegts"; } //如果存在秘钥则启用加密 QByteArray cryptoKey = this->property("cryptoKey").toByteArray(); if (!cryptoKey.isEmpty()) { av_dict_set(&options, "encryption_scheme", "cenc-aes-ctr", 0); av_dict_set(&options, "encryption_key", cryptoKey.constData(), 0); av_dict_set(&options, "encryption_kid", cryptoKey.constData(), 0); } //开辟一个格式高下文用来处理视频流输出(末端url不填则rtsp推流失落败) int result = avformat_alloc_output_context2(&formatCtx, NULL, format, url); if (result < 0) { debug(result, "创建格式", ""); return false; } //创建输出视频流 if (!this->initVideoStream()) { goto end; } //创建输出音频流 if (!this->initAudioStream()) { goto end; } //打开输出文件 if (!(formatCtx->oformat->flags & AVFMT_NOFILE)) { result = avio_open(&formatCtx->pb, url, AVIO_FLAG_WRITE); if (result < 0) { debug(result, "打开输出", ""); goto end; } } //写入文件开始符 result = avformat_write_header(formatCtx, &options); if (result < 0) { debug(result, "写文件头", ""); goto end; } return true;end: //关闭开释并清理文件 this->close(); this->deleteFile(fileName); return false;}void FFmpegThread::initOption(){ //设置缓存大小(1080p可将值调大/现在很多摄像机是2k可能须要调大/一样平常2k是1080p的四倍) av_dict_set(&options, "buffer_size", "8192000", 0); //设置超时断开连接韶光(单位微秒/3000000表示3秒) av_dict_set(&options, "stimeout", "3000000", 0); //设置最大时延(单位微秒/1000000表示1秒) av_dict_set(&options, "max_delay", "1000000", 0); //自动开启线程数 av_dict_set(&options, "threads", "auto", 0); //通信协议采取tcp还是udp(udp优点是无连接/在网线拔掉往后十几秒钟重新插上还能连续吸收/缺陷是网络不好的情形下会丢包花屏) if (transport != "auto") { av_dict_set(&options, "rtsp_transport", transport.toUtf8().constData(), 0); } //开启无缓存(rtmp等视频流不建议开启) //av_dict_set(&options, "fflags", "nobuffer", 0); //av_dict_set(&options, "fflags", "discardcorrupt", 0); //有些视频网站根据这个头部过滤不让ffmpeg访问须要仿照成其他的 //av_dict_set(&options, "user_agent", "libmpv", 0); av_dict_set(&options, "user_agent", "Mozilla", 0); //增加rtp/sdp支持(后面创造不要加) if (videoUrl.endsWith(".sdp")) { //av_dict_set(&options, "protocol_whitelist", "file,rtp,udp", 0); } //设置分辨率帧率等参数 if (videoType == VideoType_Camera || videoType == VideoType_Desktop) { //设置分辨率 if (bufferSize != "0x0") { av_dict_set(&options, "video_size", bufferSize.toUtf8().constData(), 0); } //设置帧率 if (frameRate > 0) { av_dict_set(&options, "framerate", QString::number(frameRate).toUtf8().constData(), 0); } //设置坐标XY以及是否采集鼠标指针 if (videoType == VideoType_Desktop) { //av_dict_set(&options, "draw_mouse", "0", 0); //av_dict_set(&options, "show_region", "1", 0); int offsetX = this->property("offsetX").toInt(); int offsetY = this->property("offsetY").toInt();#ifdef Q_OS_WIN //windows上通过设置offset_x/offset_y来设置偏移值 av_dict_set(&options, "offset_x", QString::number(offsetX).toUtf8().constData(), 0); av_dict_set(&options, "offset_y", QString::number(offsetY).toUtf8().constData(), 0);#else //linux系统通过设备名称带上偏移值传入 videoUrl += QString("+%1,%2").arg(offsetX).arg(offsetY);#endif } //设置输入格式(详细要看设置是否支持) //后面改成了统一转成标准yuv420以是不用设置也没有任何影响 //av_dict_set(&options, "input_format", "mjpeg", 0); } //如果设置了秘钥则须要启用解密 if (!secretKey.isEmpty()) { QByteArray cryptoKey = this->property("cryptoKey").toByteArray(); av_dict_set(&options, "decryption_key", cryptoKey.constData(), 0); }}

Qt/C++音视频开拓55-加密保存到文件并解密播放_视频_控件 Qt/C++音视频开拓55-加密保存到文件并解密播放_视频_控件 互联网
(图片来自网络侵删)
标签:

相关文章

CSS3边线之美,探索视觉效果的无限可能

随着互联网技术的飞速发展,网页设计越来越注重视觉效果。CSS3边线作为一种重要的视觉元素,不仅能够丰富页面布局,还能提升用户体验。...

互联网 2024-12-28 阅读0 评论0

CSSA细线,引领时尚潮流的装饰元素

随着社会的发展,人们对于时尚的追求越来越高。在这个追求个性、追求品味的时代,装饰元素在时尚领域扮演着越来越重要的角色。CSSA细线...

互联网 2024-12-28 阅读0 评论0

CSSP标签,网页设计中不可或缺的基石

随着互联网的飞速发展,网页设计已成为当今社会的重要技能之一。在网页设计中,CSS(层叠样式表)扮演着至关重要的角色。其中,P标签作...

互联网 2024-12-28 阅读0 评论0

CSS分页器,设计与实现的优雅艺术

在信息爆炸的今天,内容丰富的网站和应用程序无处不在。为了方便用户浏览大量数据,分页器成为网页设计中不可或缺的元素。CSS分页器,作...

互联网 2024-12-28 阅读1 评论0

CSS包含块,介绍网页布局背后的秘密

在网页设计中,CSS(层叠样式表)扮演着至关重要的角色。它不仅决定了网页的样式和外观,还影响着布局的合理性和用户体验。其中,CSS...

互联网 2024-12-28 阅读1 评论0