一、前言

录像功能是视频监控系统的常用功能,就是将打开的视频流或者视频文件重新保存成MP4文件,当然也可以保存成其他格式,一般默认用MP4比较好,比较标准一些,MP4格式的兼容性最好,基本上没有说那台电脑不能播放MP4文件,所以就保存成这种最常用的视频文件格式就好了。

vlc的录像功能是内置封装好的,在打开文件的前面设置相应的命令参数即可,如果只是要求整个过程保存成一个视频文件,这个很好办,网上方法一大堆,只要调用libvlc_media_add_option函数设置:sout=#duplicate{dst=file{dst=d:/1.mp4},dst=display}即可,最开始用的是:sout=#stream_out_duplicate{dst=display,dst=std{access=file,mux=%1,dst=%2}}参数,后面换成vlc3以后发现不支持了,查阅相关资料后发现要用duplicate,可能vlc3开始不支持stream_out_duplicate只支持duplicate吧。

保存成单个视频文件,这个没有任何问题和难度,但是视频监控领域中经常需要的是定时保存成单个文件,比如30分钟一个视频文件,这样方便检索,而且也不会看起来一个视频文件很大很大,毕竟视频监控是7*24小时运行的,那这个文件不知道多大,vlc要动态保存多个文件,这就需要模拟执行录像、停止录像的功能来实现,主要的流程就是通过var_CreateGetString函数拿到录像文件存储路径变量,然后var_SetString设置该变量,最后调用var_ToggleBool来模拟单击了录像,停止录像只需要再次执行一次即可,所以要存储成多个视频文件,只需要动态改变录像文件存储路径这个变量即可。

二、功能特点

  1. 多线程实时播放视频流和本地视频。
  2. 支持windows+linux+mac,支持vlc2和vlc3。
  3. 多线程显示图像,不卡主界面。
  4. 自动重连网络摄像头。
  5. 可设置边框大小即偏移量和边框颜色。
  6. 可设置是否绘制OSD标签即标签文本或图片和标签位置。
  7. 可设置两种OSD位置和风格。
  8. 可设置是否保存到文件以及文件名。
  9. 可直接拖曳文件到vlcwidget控件播放。
  10. 支持h265视频流+rtmp等常见视频流。
  11. 可暂停播放和继续播放。
  12. 支持回调模式和句柄两种模式。
  13. 支持线程读取进度等信息和事件回调两种处理模式。
  14. 自动将当前播放位置和音量大小是否静音以信号发出去。
  15. 提供接口设置播放位置和音量及设置静音。
  16. 支持存储单个视频文件和定时存储视频文件。
  17. 自定义顶部悬浮条,发送单击信号通知,可设置是否启用。

三、效果图

四、相关站点

  1. 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
  2. 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
  3. 个人主页:https://blog.csdn.net/feiyangqingyun
  4. 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
  5. 体验地址:https://blog.csdn.net/feiyangqingyun/article/details/97565652

五、核心代码

void VlcThread::initSave()
{
if (!saveFile) {
return;
} if (saveInterval == 0) {
saveOne(fileName);
}
} void VlcThread::saveOne(const QString &fileName)
{
QString temp = url.toUpper();
QString mux = "ts";
if (temp.endsWith("MP4") || temp.endsWith("MOV")) {
mux = "mp4";
} //旧格式 :sout=#stream_out_duplicate{dst=display,dst=std{access=file,mux=%1,dst=%2}}
//新格式 :sout=#duplicate{dst=file{dst=d:/1.mp4},dst=display}
//vlc3开始不支持stream_out_duplicate只支持duplicate
QString option = QString(":sout=#duplicate{dst=display,dst=std{access=file,mux=%1,dst=%2}}").arg(mux).arg(fileName);
setOption(option);
} void VlcThread::saveVideo()
{
//只有启用了保存文件才保存,这里不要加拓展名,会自动生成
//文件会在到了间隔后生成
QMutexLocker locker(&mutex);
if (saveFile) {
//重新设置文件名称
QString dirName = QString("%1/%2").arg(savePath).arg(QDATE);
newDir(dirName);
fileName = QString("%1/%2_%3").arg(dirName).arg(fileFlag).arg(STRDATETIME);
saveVideo(fileName);
}
} void VlcThread::saveVideo(const QString &fileName)
{
//除了第一次不要执行外,其他都执行,因为第一次需要先启动存储
if (!first) {
stopSave(vlcPlayer);
} first = false;
startSave(vlcPlayer, fileName);
} //录像用函数
static input_thread_t *libvlc_get_input_thread(libvlc_media_player_t *vlcPlayer)
{
input_thread_t *input = NULL;
if (vlcPlayer != NULL) {
input = vlcPlayer->input.p_thread;
if (input) {
vlc_object_hold(input);
}
} return input;
} //开始录像
static void startSave(libvlc_media_player_t *vlcPlayer, const QString &fileName = "")
{
input_thread_t *input = libvlc_get_input_thread(vlcPlayer);
if (input == NULL) {
return;
} #ifdef vlc3
// 传过来的是带文件名的路径,需要去掉后面的文件名
QStringList list = fileName.split("/");
QStringList paths;
int count = list.count() - 1;
for (int i = 0; i < count; i++) {
paths << list.at(i);
} QString path = paths.join("/");
QString name = list.last(); var_CreateGetString(input, "input-record-path");
var_SetString(input, "input-record-path", path.toUtf8().data());
//var_CreateGetString(input, "sout-record-dst-prefix");
//var_SetString(input, "sout-record-dst-prefix", name.toUtf8().data());
//var_CreateGetString(input, "record-video-name");
//var_SetString(input, "record-video-name", name.toUtf8().data());
#else
var_CreateGetString(input, "input-record-path");
var_SetString(input, "input-record-path", fileName.toUtf8().constData());
//var_SetString(input, "sout-record-dst-prefix", fileName.toUtf8().constData());
#endif var_ToggleBool(input, "record");
vlc_object_release(input);
} //停止录像
static void stopSave(libvlc_media_player_t *vlcPlayer)
{
input_thread_t *input = libvlc_get_input_thread(vlcPlayer);
if (input == NULL) {
return;
} var_ToggleBool(input, "record");
vlc_object_release(input);
}

Qt音视频开发3-vlc录像存储的更多相关文章

  1. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  2. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  3. Android 音视频开发(七): 音视频录制流程总结

    在前面我们学习和使用了AudioRecord.AudioTrack.Camera.MediaExtractor.MediaMuxer API.MediaCodec. 学习和使用了上述的API之后,相信 ...

  4. Python音视频开发:消除抖音短视频Logo的图形化工具实现

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解>节介绍了怎么通过Python+Moviepy+OpenCV实现 ...

  5. Python音视频开发:消除抖音短视频Logo和去电视台标

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 对于带Logo(如抖音Logo.电视台标)的视频,有三种方案进行Logo消除: 直接将对应区域用对应图像替换: 直接将对应区域模糊化: 通过变换将要 ...

  6. Moviepy音视频开发:视频转gif动画或jpg图片exe图形化工具开发案例

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 老猿之所以学习和研究Moviepy的使用,是因为需要一个将视频转成动画的工具,当时在网上到处搜索查找免费使用工具,结果找了很多自称免费的工具,但转完 ...

  7. moviepy音视频开发:使用credits1给视频加片头片尾字幕

    ☞ ░ 前往老猿Python博文目录 ░ 一.概述 在<moviepy音视频剪辑:视频基类VideoClip子类DataVideoClip.UpdatedVideoClip.ImageClip. ...

  8. moviepy音视频开发:音频剪辑基类AudioClip

    ☞ ░ 前往老猿Python博文目录 ░ 一.背景知识介绍 1.1.声音三要素: 音调:人耳对声音高低的感觉称为音调(也叫音频).音调主要与声波的频率有关.声波的频率高,则音调也高. 音量:也就是响度 ...

  9. Android 音视频开发(一):PCM 格式音频的播放与采集

    什么是 PCM 格式 声音从模拟信号转化为数字信号的技术,经过采样.量化.编码三个过程将模拟信号数字化. 采样 顾名思义,对模拟信号采集样本,该过程是从时间上对信号进行数字化,例如每秒采集 44100 ...

  10. 【秒懂音视频开发】02_Windows开发环境搭建

    音视频开发库的选择 每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如: iOS:AVFoundation.AudioUnit等 Android:MediaPlayer.Med ...

随机推荐

  1. 通过自定义字符串内插处理程序(InterpolatedStringHandler)和CallerArgumentExpression特性来实现一个好玩的场景

    背景知识介绍 什么是自定义字符串内插处理程序? 简单来讲就是自定义一个高性能的字符串拼接程序 通过 $"{a}{b}"的方式. 什么是CallerArgumentExpressio ...

  2. Nuxt.js 应用中的 app:templates 事件钩子详解

    title: Nuxt.js 应用中的 app:templates 事件钩子详解 date: 2024/10/18 updated: 2024/10/18 author: cmdragon excer ...

  3. Windows安全中心在手动删除威胁文件后无法处理,一直显示有威胁

    从网络上找到了一个简单靠谱的解决方案,与众位分享: 找到C:\ProgramData\Microsoft\Windows Defender\Scans\History\Service\Detectio ...

  4. jeecg平台相关01-vue2迁移到vue3

    01-vue2迁移到vue3 嵌套: datasource: master: url: jdbc:mysql://127.0.0.1:3306/jeecg-boot-vue3?characterEnc ...

  5. Linux 基础-文本处理命令

    概述 find 文件查找 grep 文本搜索 参考资料 概述 Linux 下使用 Shell 处理文本时最常用的工具有: find.grep.xargs.sort.uniq.tr.cut.paste. ...

  6. house of banana

    条件: 1.任意地址写一个堆地址 2.触发exit函数 3.能泄露堆地址和基地址 原理: 伪造 fini_array 赋值用到的结构体 从而控制程序exit时的程序执行流 ld.so 中存在 _rtl ...

  7. 一款WPF开发的B站视频下载开源项目

    更多开源项目请查看:一个专注推荐优秀.Net开源项目的榜单 今天给推荐一款C#开发的.界面简洁的哔哩哔哩视频下载工具. 项目简介 这是一款基于WPF开发的,B站下载工具,操作界面简洁,支持多线程下载. ...

  8. 基于 Github 平台的 .NET 开源项目模板 - 发布与归档 相关

    CHANGELOG.md 案例 ## [1.0.1.2] - 2023-03-10 ### myproject2 _ 1.0.1: - 初步版本 简单实现 还未优化 - fix warning ## ...

  9. 解决Delphi应用程序向桌面资源管理拖放问题 win10,winxp,win2003测试成功

    解决Delphi应用程序向桌面资源管理拖放问题 win10,winxp,win2003测试成功 如果是实体拖动,是比较好解决的. 如果是虚拟应用程序数据,拖动到本机桌面或资源管理器目录下,获取目录路径 ...

  10. Windows 使用 Intel(R) Arc(TM) GPU 推理ONNX 模型

    这不刚换了一个笔记本电脑,Thinkpad T14P,带有Intel ARC GPU,今天我们来尝试用这个GPU来推理ONNX模型. 环境安装 查阅了相关文档,最好使用py310环境,其他版本可能存在 ...