千家信息网

Qt mpv事件订阅怎么实现

发表于:2025-01-24 作者:千家信息网编辑
千家信息网最后更新 2025年01月24日,这篇文章主要讲解了"Qt mpv事件订阅怎么实现",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Qt mpv事件订阅怎么实现"吧!一、前言在使用libm
千家信息网最后更新 2025年01月24日Qt mpv事件订阅怎么实现

这篇文章主要讲解了"Qt mpv事件订阅怎么实现",文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习"Qt mpv事件订阅怎么实现"吧!

一、前言

在使用libmpv的过程中,通过对mpv事件订阅,可以更准确和准时的得知一些事件,比如文件打开成功,播放状态的改变等,而不需要定时器去读取状态,尤其是打开成功这个事件,如果不采用事件订阅,有时候视频流会卡主一阵子,比如不存在的视频流或者网络不好的情况下,有两种办法可以规避这个情况,在vlc和ffmpeg解码中也是如此,一种方法是将这个打开直接放到线程中执行,本来解码处理就是一个完整的线程类,所以直接通过标志位的更改来在线程中执行初始化,毫无压力不卡主,还有一个办法就是采用事件回调,得到打开成功以后,再去执行其他的处理比如读取视频的宽度高度等信息,这些信息一般都是需要打开文件成功以后才能读取到的。

毫无疑问mpv也支持事件订阅,通过mpv_observe_property函数将需要订阅的属性事件更改加入事件订阅队列,这个函数有四个参数,第一个参数指mpv对象(通过mpv_create产生的),第二个参数指用户数据,如果不需要的话直接填0,一般都不需要,第三个参数指属性名称,至于属性名称是啥叫啥,可以官网查阅手册(http://mpv.io/manual/master/#properties),第四个参数指属性的格式类型。一般来说都会对这几个属性事件的更改订阅:duration(文件长度)、time-pos(当前播放进度)。事件订阅好以后执行mpv_set_wakeup_callback函数设置事件回调函数处理即可。

二、功能特点

  1. 多线程实时播放视频流+本地视频等。

  2. 支持windows+linux+mac。

  3. 多线程显示图像,不卡主界面。

  4. 自动重连网络摄像头。

  5. 可设置是否保存到文件以及文件名。

  6. 可直接拖曳文件到mpvwidget控件播放。

  7. 支持h365视频流+rtmp等常见视频流。

  8. 可暂停播放和继续播放。

  9. 支持存储单个视频文件和定时存储视频文件。

  10. 自定义顶部悬浮条,发送单击信号通知,可设置是否启用。

  11. 可设置画面拉伸填充或者等比例填充。

  12. 可对视频进行截图(原始图片)和截屏。

  13. 录像文件存储MP4文件。

  14. 支持qsv、dxva2、d3d11va等硬解码。

三、效果图

四、核心代码

//事件处理static void handleEvents(mpv_handle *mpvPlayer, mpv_event *event, MpvThread *thread){    switch (event->event_id) {        case MPV_EVENT_PROPERTY_CHANGE: {            mpv_event_property *property = (mpv_event_property *)event->data;            QString propertyName = property->name;            mpv_format propertyFormat = property->format;            if (propertyName == "duration") {                //文件总长度                if (propertyFormat == MPV_FORMAT_DOUBLE) {                    double time = *(double *)property->data;                    uint length = time * 1000;                    thread->doEvent(1, QVariantList() << length);                    qDebug() << TIMEMS << "文件总长: " << length;                }            } else if (propertyName == "time-pos") {                //当前播放进度                if (propertyFormat == MPV_FORMAT_DOUBLE) {                    double time = *(double *)property->data;                    uint position = time * 1000;                    thread->doEvent(2, QVariantList() << position);                    //qDebug() << TIMEMS << "当前时间: " << position;                }            } else {                qDebug() << TIMEMS << propertyName;                if (propertyFormat == MPV_FORMAT_NODE) {#if 0                    QVariant data = qtmpv::node_to_variant((mpv_node *)property->data);                    QJsonDocument json = QJsonDocument::fromVariant(data);                    qDebug() << TIMEMS << json.toJson().data();#endif                }            }            break;        }        //获取宽高        case MPV_EVENT_VIDEO_RECONFIG: {            //这里会执行两次,不知道为什么            int dwidth, dheight;            mpv_get_property(mpvPlayer, "dwidth", MPV_FORMAT_INT64, &dwidth);            mpv_get_property(mpvPlayer, "dheight", MPV_FORMAT_INT64, &dheight);            qDebug() << TIMEMS << "dwidth:" << dwidth << "dheight:" << dheight;            break;        }        //打印日志        case MPV_EVENT_LOG_MESSAGE: {            struct mpv_event_log_message *msg = (struct mpv_event_log_message *)event->data;            QString data = QString("[%1] %2: %3").arg(msg->prefix).arg(msg->level).arg(msg->text);            data.replace("\r", "");            data.replace("\n", "");            //qDebug() << TIMEMS << data;            break;        }        //文件播放结束        case MPV_EVENT_END_FILE: {            thread->doEvent(0, QVariantList());            break;        }        default:            break;    }}//订阅事件static void attachEvents(mpv_handle *mpvPlayer){    mpv_observe_property(mpvPlayer, 0, "duration", MPV_FORMAT_DOUBLE);    mpv_observe_property(mpvPlayer, 0, "time-pos", MPV_FORMAT_DOUBLE);    mpv_observe_property(mpvPlayer, 0, "track-list", MPV_FORMAT_NODE);    mpv_observe_property(mpvPlayer, 0, "chapter-list", MPV_FORMAT_NODE);}

感谢各位的阅读,以上就是"Qt mpv事件订阅怎么实现"的内容了,经过本文的学习后,相信大家对Qt mpv事件订阅怎么实现这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是,小编将为大家推送更多相关知识点的文章,欢迎关注!

事件 订阅 文件 视频 参数 属性 线程 视频流 支持 成功 函数 处理 就是 情况 可设 存储 学习 内容 办法 名称 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器未系安全带 中国网络安全产业统计 农科java软件开发 数据库表太多了我要怎么看 我的世界刀光剑影怎么进入服务器 语音聊天的网络技术是什么 对软件开发的认识作文 c 增删改查数据库方法 网络安全资产分配台帐 安卓youxi 软件开发 江西家用软件开发零售价格 秦皇岛市海港区网络安全进乡镇 数据库在电脑上怎么查 2019国家网络安全宣传片 河南明煌互联网科技有限公司 电脑对服务器的远程访问 软件开发行业薪酬待遇 加盟评论数据库 瑞幸 苹果手机服务器放在哪里 软件开发成本预算表怎么做 北京驰纵网络技术有限公司 现在学软件开发可以吗 mc侦探与杀手是哪个服务器 公安网络安全管理暂行办法 数据库运维笔试题 sql2008数据库邮件 奉贤区推广软件开发厂家口碑推荐 网络安全专业难度系数 外文数据库检索的方法有哪些 天地劫手游服务器获取失败
0