Qt音视频开发5-vlc事件订阅
时间:2022-07-22
本文章向大家介绍Qt音视频开发5-vlc事件订阅,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、前言
事件订阅可以拿到文件长度、播放进度、播放状态改变等信息,vlc的事件订阅机制封装的比较友好,只需要先创建一个事件管理器,然后逐个订阅自己感兴趣的需要的事件,不感兴趣的可以不要订阅,只有订阅了的事件才能在事件回调中拿到,所以如果在事件回调中发现一些事件没有拿到,首先要检查下到底订阅了没有,所有事件的枚举在libvlc_events.h头文件中可以查阅到,都用的是通俗易懂的全英文单词描述,有过基本英语能力的开发人员都能看懂。
在调用libvlc_event_attach订阅事件的时候,第三个参数指定事件回调函数,第四个参数传入用户数据,一般是用来传入类的指针,这样在事件回调的时候,可以直接拿到并转换为类指针,然后使用类中的方法,在对Qt4-Qt5的兼容过程中发现,Qt5中的信号是public的,所以可以直接在回调函数中emit发送信号,而Qt4中的信号是protected的,没法直接emit,所以需要做一个通用的中转函数,用来重新分发信号,通过参数type来控制类型,QVariantList来传入参数集合。
二、功能特点
- 多线程实时播放视频流和本地视频。
- 支持windows+linux+mac,支持vlc2和vlc3。
- 多线程显示图像,不卡主界面。
- 自动重连网络摄像头。
- 可设置边框大小即偏移量和边框颜色。
- 可设置是否绘制OSD标签即标签文本或图片和标签位置。
- 可设置两种OSD位置和风格。
- 可设置是否保存到文件以及文件名。
- 可直接拖曳文件到vlcwidget控件播放。
- 支持h265视频流+rtmp等常见视频流。
- 可暂停播放和继续播放。
- 支持回调模式和句柄两种模式。
- 支持线程读取进度等信息和事件回调两种处理模式。
- 自动将当前播放位置和音量大小是否静音以信号发出去。
- 提供接口设置播放位置和音量及设置静音。
- 支持存储单个视频文件和定时存储视频文件。
- 自定义顶部悬浮条,发送单击信号通知,可设置是否启用。
三、效果图
四、相关站点
- 国内站点:https://gitee.com/feiyangqingyun/QWidgetDemo
- 国际站点:https://github.com/feiyangqingyun/QWidgetDemo
- 个人主页:https://blog.csdn.net/feiyangqingyun
- 知乎主页:https://www.zhihu.com/people/feiyangqingyun/
- 体验地址:https://blog.csdn.net/feiyangqingyun/article/details/97565652
五、核心代码
//事件回调
static void handleEvents(const libvlc_event_t *event, void *userData)
{
VlcThread *thread = (VlcThread *)userData;
switch (event->type) {
case libvlc_MediaPlayerLengthChanged: {
quint64 length = event->u.media_player_length_changed.new_length;
if (length > 0) {
thread->doEvent(1, QVariantList() << length);
qDebug() << TIMEMS << "文件总长: " << length;
}
}
break;
case libvlc_MediaPlayerTimeChanged: {
quint64 position = event->u.media_player_time_changed.new_time;
if (position > 0) {
thread->doEvent(2, QVariantList() << position);
//qDebug() << TIMEMS << "当前时间: " << position;
}
}
break;
case libvlc_MediaPlayerPositionChanged: {
float position = event->u.media_player_position_changed.new_position;
if (position > 0) {
//qDebug() << TIMEMS << "当前进度: " << position;
}
}
break;
case libvlc_MediaParsedChanged:
qDebug() << TIMEMS << "媒体信息: " << event->u.media_parsed_changed.new_status;
break;
//qDebug() << TIMEMS << "状态改变: " << event->u.media_state_changed.new_state;
case libvlc_MediaPlayerOpening:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerOpening";
break;
case libvlc_MediaPlayerPlaying:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerPlaying";
break;
case libvlc_MediaPlayerPaused:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerPaused";
break;
case libvlc_MediaPlayerStopped:
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerStopped";
break;
case libvlc_MediaPlayerEndReached: {
thread->doEvent(0, QVariantList());
qDebug() << TIMEMS << "状态改变: " << "libvlc_MediaPlayerEndReached";
}
break;
default:
break;
}
}
//订阅事件
static void libvlc_event_new(libvlc_event_manager_t *vlcEvent, VlcThread *thread)
{
//逐个订阅自己感兴趣的需要的事件
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerLengthChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerTimeChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPositionChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaParsedChanged, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerOpening, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPlaying, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerPaused, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerStopped, handleEvents, thread);
libvlc_event_attach(vlcEvent, libvlc_MediaPlayerEndReached, handleEvents, thread);
}
//反订阅事件
static void libvlc_event_release(libvlc_event_manager_t *vlcEvent, VlcThread *thread)
{
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerLengthChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerTimeChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPositionChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaParsedChanged, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerOpening, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPlaying, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerPaused, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerStopped, handleEvents, thread);
libvlc_event_detach(vlcEvent, libvlc_MediaPlayerEndReached, handleEvents, thread);
}
- 小白博客 Xiaobai___详细教你如何在Linux环境下安装mysql数据库
- 3856: Monster
- BZOJ4753: [Jsoi2016]最佳团体
- 3101: N皇后
- 算法模板——线性欧拉函数
- jdbc基础 (一) MySQL的简单使用
- 小白博客 爆破内网mysql数据库root密码脚本代码
- 2818: Gcd
- 1688: [Usaco2005 Open]Disease Manangement 疾病管理
- 通过MySQL自动同步刷新Redis
- 13.MySQL(一) 数据库简介mysql安装数据库操作Mysql数据类型存储引擎
- 3314: [Usaco2013 Nov]Crowded Cows
- BZOJ4766: 文艺计算姬
- 14.MySQL(二) 数据之表操作表内容操作Mysql 连接事务外键
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- linux如何利用crontab添加定时任务详解
- windows安装openssh并通过生成SSH密钥登录Linux服务器
- SSH设置别名访问远程服务器详细介绍
- Linux检查Swap交换空间的五个命令小结
- seaborn数据总体分布的可视化策略
- 配置 Apache 服务器禁止所有非法域名 访问自己的服务器
- Ubuntu16.04源码安装Mininet
- Kotlin基础学习之Deprecated与Suppress注解使用
- Centos 7下利用crontab定时执行任务详解
- 树莓派无线上网时无屏幕下发现树莓派IP的方法
- Ubuntu18.04安装opencv 3.2.0的解决方法
- Android MVP BaseFragment 通用式封装的实现
- 腾讯云服务器Centos挂载数据盘的方法
- CentOS 8.0.1905 安装 ZABBIX4.4版本 (已验证)
- seaborn分类变量的汇总展示