Qt音视频开发4-vlc读取和控制

2020-08-06 14:41:25 浏览数 (1)

一、前言

vlc本身是个全功能的很牛逼的播放器,你能够想到的播放的功能他都有,比如获取视频文件的长度、唱片的封面、当前播放进度、设置播放进度、声音控制、静音控制等,这些vlc都给你封装好了,你直接调用对应的api函数即可。

看vlc的官方对vlc的更新频率也是蛮高的,所以在各种新的视频标准和格式出来以后,他也是在不断的更新完善,比如H265,8K视频等,都能正常的播放,查阅vlc的动态库目录可以看见,vlc的部分解码用的就是ffmpeg,所以知道了为啥他这么强大了吧,原来是依赖ffmpeg这个超级牛逼的全功能解码库呢。

用vlc做控制这块有两种处理方式,一种是在线程中来定时读取,比如读取播放进度、当前各种状态、当前音量、静音等,还有一种方式是采用事件回调的形式,默认建议事件回调的机制,能够拿到很多事件消息,效率也更高。你只需要在打开视频以前调用libvlc_event_attach订阅自己感兴趣的事件,在不需要的时候比如关闭的时候调用libvlc_event_detach注销订阅的事件即可。

二、功能特点

  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. 自定义顶部悬浮条,发送单击信号通知,可设置是否启用。

三、效果图

QQ截图20200802133636.jpgQQ截图20200802133636.jpg

四、相关站点

  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

五、核心代码

代码语言:txt复制
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);
    }
}

0 人点赞