Qt音视频开发4-vlc读取和控制
时间:2022-07-22
本文章向大家介绍Qt音视频开发4-vlc读取和控制,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一、前言
vlc本身是个全功能的很牛逼的播放器,你能够想到的播放的功能他都有,比如获取视频文件的长度、唱片的封面、当前播放进度、设置播放进度、声音控制、静音控制等,这些vlc都给你封装好了,你直接调用对应的api函数即可。
看vlc的官方对vlc的更新频率也是蛮高的,所以在各种新的视频标准和格式出来以后,他也是在不断的更新完善,比如H265,8K视频等,都能正常的播放,查阅vlc的动态库目录可以看见,vlc的部分解码用的就是ffmpeg,所以知道了为啥他这么强大了吧,原来是依赖ffmpeg这个超级牛逼的全功能解码库呢。
用vlc做控制这块有两种处理方式,一种是在线程中来定时读取,比如读取播放进度、当前各种状态、当前音量、静音等,还有一种方式是采用事件回调的形式,默认建议事件回调的机制,能够拿到很多事件消息,效率也更高。你只需要在打开视频以前调用libvlc_event_attach订阅自己感兴趣的事件,在不需要的时候比如关闭的时候调用libvlc_event_detach注销订阅的事件即可。
二、功能特点
- 多线程实时播放视频流和本地视频。
- 支持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
五、核心代码
void VlcThread::setSize(int width, int height)
{
if (vlcPlayer != NULL) {
QString option = QString("%1:%2").arg(width).arg(height);
QByteArray data = option.toUtf8();
const char *arg = data.constData();
//一旦打开视频以后要动态更改宽高比,值只能是vlc认识的比如 16:9 1:1 之类的
//const char *arg = "4:3";
libvlc_video_set_aspect_ratio(vlcPlayer, arg);
}
}
bool VlcThread::getIsPlaying()
{
bool isPlaying = false;
if (vlcPlayer != NULL) {
int result = libvlc_media_player_is_playing(vlcPlayer);
isPlaying = (result != 0);
}
return isPlaying;
}
VlcThread::VlcState VlcThread::getState()
{
VlcState state = VlcThread::VlcState_NothingSpecial;
if (vlcPlayer != NULL) {
state = (VlcState)libvlc_media_player_get_state(vlcPlayer);
}
return state;
}
uint VlcThread::getLength()
{
uint length = 0;
if (vlcPlayer != NULL) {
length = libvlc_media_player_get_length(vlcPlayer);
}
return length;
}
uint VlcThread::getPosition()
{
uint positon = 0;
if (vlcPlayer != NULL) {
positon = libvlc_media_player_get_time(vlcPlayer);
}
return positon;
}
void VlcThread::setPosition(int position)
{
if (vlcPlayer != NULL && !isRtsp) {
libvlc_media_player_set_time(vlcPlayer, position);
}
}
bool VlcThread::getMute()
{
bool ok = false;
if (vlcPlayer != NULL) {
int result = libvlc_audio_get_mute(vlcPlayer);
ok = (result == 0);
}
return ok;
}
void VlcThread::setMute(bool mute)
{
if (vlcPlayer != NULL) {
libvlc_audio_set_mute(vlcPlayer, mute ? 1 : 0);
}
}
int VlcThread::getVolume()
{
int volume = 0;
if (vlcPlayer != NULL) {
volume = libvlc_audio_get_volume(vlcPlayer);
}
return volume;
}
void VlcThread::setVolume(int volume)
{
if (vlcPlayer != NULL) {
libvlc_audio_set_volume(vlcPlayer, volume);
}
}
int VlcThread::getTrack()
{
int track = 0;
if (vlcPlayer != NULL) {
track = libvlc_audio_get_track(vlcPlayer);
}
return track;
}
int VlcThread::getTrackCount()
{
int trackCount = 0;
if (vlcPlayer != NULL) {
trackCount = libvlc_audio_get_track_count(vlcPlayer);
}
return trackCount;
}
void VlcThread::setTrack(int track)
{
if (vlcPlayer != NULL) {
track = libvlc_audio_set_track(vlcPlayer, track);
}
}
- 几个比较有意思的JS脚本
- Java多线程高并发学习笔记——阻塞队列
- 使用javascript+xml实现分页
- 使用OAuth打造webapi认证服务供自己的客户端使用
- 洛谷P3381 【模板】最小费用最大流(dijstra费用流)
- 使用OAuth打造webapi认证服务供自己的客户端使用(二)
- JavaScript基础1
- JavaScript实例-----反选
- 1303: [CQOI2009]中位数图
- 1050: [HAOI2006]旅行comf
- 某厂2016实习招聘安全技术试题答案及解析
- 3732: Network
- 洛谷P3388 【模板】割点(割顶)(tarjan求割点)
- 每天学一点Docker(3)(制作你的第一个容器)
- 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 数组属性和方法
- 打卡群2刷题总结1004——无重复字符的最长子串
- 如何恢复故障KVM虚拟机qcow2磁盘镜像文件LVM分区中的数据
- 8000字 | 32 张图 | 一文搞懂事务+隔离级别+阻塞+死锁
- 闪回flashback
- 海贼王 One Piece,一起康康Vue版本号中的彩蛋
- MySQL 三万字精华总结 + 面试100 问,吊打面试官绰绰有余(收藏系列)
- Oracle数据结构
- 打卡群2刷题总结1003——搜索旋转排序数组
- Rman备份恢复和管理
- 重做日志和日志挖掘
- 『技术随手学』解决windows与ubuntu平台 CondaHTTPError: HTTP 000 CONNECTION FAILED 问题
- DevOps编程操练:用Jenkins流水线建立代码质量预警机制
- 『技术随手学』pip conda 替换清华源 Windows与Ubuntu通用
- 回滚段undo
- 『AI实践学』测试深度学习框架GPU版本是否正确安装方法:TensorFlow,PyTorch,MXNet,PaddlePaddle