美文网首页QT GUI编程
Qt音视频开发5-vlc事件订阅

Qt音视频开发5-vlc事件订阅

作者: feiyangqingyun | 来源:发表于2020-08-07 11:32 被阅读0次

一、前言

事件订阅可以拿到文件长度、播放进度、播放状态改变等信息,vlc的事件订阅机制封装的比较友好,只需要先创建一个事件管理器,然后逐个订阅自己感兴趣的需要的事件,不感兴趣的可以不要订阅,只有订阅了的事件才能在事件回调中拿到,所以如果在事件回调中发现一些事件没有拿到,首先要检查下到底订阅了没有,所有事件的枚举在libvlc_events.h头文件中可以查阅到,都用的是通俗易懂的全英文单词描述,有过基本英语能力的开发人员都能看懂。

在调用libvlc_event_attach订阅事件的时候,第三个参数指定事件回调函数,第四个参数传入用户数据,一般是用来传入类的指针,这样在事件回调的时候,可以直接拿到并转换为类指针,然后使用类中的方法,在对Qt4-Qt5的兼容过程中发现,Qt5中的信号是public的,所以可以直接在回调函数中emit发送信号,而Qt4中的信号是protected的,没法直接emit,所以需要做一个通用的中转函数,用来重新分发信号,通过参数type来控制类型,QVariantList来传入参数集合。

二、功能特点

  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

五、核心代码

//事件回调
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);
}

相关文章

  • Qt音视频开发5-vlc事件订阅

    一、前言 事件订阅可以拿到文件长度、播放进度、播放状态改变等信息,vlc的事件订阅机制封装的比较友好,只需要先创建...

  • Qt音视频开发15-mpv事件订阅

    一、前言 在使用libmpv的过程中,通过对mpv事件订阅,可以更准确和准时的得知一些事件,比如文件打开成功,播放...

  • Qt音视频开发30-Onvif事件订阅

    一、前言 能够接收摄像机的报警事件,比如几乎所有的摄像机后面会增加报警输入输出接口,如果用户外接了报警输入,则当触...

  • Mac BigSur OS 下 Qt安装以及集成ffmpeg 笔

    前言 最近在学习音视频开发技术,开发环境为Qt搭配ffmpeg进行音视频开发学习。虽然网上QT环境搭建教程有许多,...

  • 简易播放器设计文档

    EntryTask: 使用FFMpeg编写一个简单音视频播放器 开发环境 开发语言:C++ IDE:QT Crea...

  • QML Book 第三章 开发工具

    3. Qt Creator 集成开发环境 Qt Creator 是 Qt 的默认集成开发环境。它是由 Qt 开发人...

  • 一个 Qt 事件对象的旅行

    Qt 的事件来自操作系统,Qt自己产生。当Qt应用程序运行时,qt有一个未处理的事件队列,每个事件处理周期内,将处...

  • 《Qt5开发及实例》

    《Qt5开发及实例》Qt是诺基亚公司的C++可视化开发平台,目前最新版本为Qt 5。《Qt5开发及实例》以Qt 5...

  • Qt中事件的理解(1)

    1、Qt中的事件 Qt中,事件作为一个对象,继承自QEvent类,常见的有键盘事件QKeyEvent、鼠标事件QM...

  • Qt及Qt Quick开发实战精解

    Qt及Qt Quick开发实战精解主要讲解了5个Qt综合应用程序的开发过程和Qt Quick的相关内容。《Qt及Q...

网友评论

    本文标题:Qt音视频开发5-vlc事件订阅

    本文链接:https://www.haomeiwen.com/subject/mykfdktx.html