• Linux 下使用libvlc 播放视频 C++


    libvlc 在Linux下播放视频的时候和Windows大部分api类似, 可以说api基本一致, 主要是在设置播放容器时有一些区别:

    Windows下使用的是libvlc_media_player_set_hwnd绑定一个窗口句柄;

    Linux下使用libvlc_media_player_set_xwindow绑定一个窗口Id.(也可以理解成Windows中的句柄,不同的是Windows句柄除可以表示窗口外,还可能是一个文件等等,而Linux下的window id是X11中的,只能表示和窗口相关的控件);

    首先需要安装libvlc-dev和libvlccore-dev(也可以编译安装最新的vlc,编译后也可以得到libvlc.solibvlccore.so),主要使用vlc(libvlc.so)和vlccore(libvlccore.so)库和一些vlc头文件:

    apt-get install libvlc-dev
    apt-get install libvlccore-dev

    一个简单的vlc实例

    创建demo.cpp:

    1. 引入头文件

    #include <vlc/vlc.h>
    #include <unistd.h>

    2. 声明播放过程中要用到的结构体

    //VLC 播放器实例(可以理解成VLC引擎)
    libvlc_instance_t * inst;
    //VLC 媒体播放器(播放视频时控制, 播放、暂停、停止、音量...)
    libvlc_media_player_t * vlc_player = NULL;
    //播放视频来源,和视频文件的信息(本地视频文件,网络视频文件,RTSP...) libvlc_media_t * vlc_media = NULL;

    3.播放部分,参考VLC实例

    //初始化VLC引擎
    inst = libvlc_new (0, NULL);
    //指定本地根目录下/test.mov为视频来源
    vlc_media = libvlc_media_new_path(inst, "/test.mov"); //创建VLC视频播放器,根据vlc_media vlc_player = libvlc_media_player_new_from_media(vlc_media); //以下代码暂时不使用vlc_media指针了,所以提前释放了 libvlc_media_release (vlc_media); //设置播放容器,0x4800006并不是死值,这是X11的窗口ID,下边简单说一下获取窗口ID方法
    //也可以不调用此方法,或者窗口ID参数处也可以随意填写一个int值, VLC已做判断,没有找不到指定窗口ID时或没设置窗口ID时都会创建一个窗口播放视频
    //首次调用建议先不要调用此api libvlc_media_player_set_xwindow(vlc_player,
    0x4800006); //播放视频,返回0 表示已开始播放,非0表示播放失败 int result = libvlc_media_player_play(vlc_player);
    //睡1秒,如果不睡,在后续调用libvlc_media_player_is_playing时会返回0(0:当前未播放, 1:正在播放)!!!,应该是播放视频也需要一些时间,1秒足够
    //不一定必须睡一秒,对libvlc api还不是特别的解,如果您对libvlc非常了解,不要参考此处...
    sleep(1); //设置音量,可以发现在控制视频时都需要用到vlc_player指针 libvlc_audio_set_volume(vlc_player,
    50); //循环判断当前视频是否是播放状态 while(libvlc_media_player_is_playing(vlc_player)){ sleep(1); } //播放完毕,释放播放器 libvlc_media_player_release (vlc_player); //释放引擎 libvlc_release (inst);

    完整demo.cpp:

    #include <vlc/vlc.h>
    #include <unistd.h>
    
    int main(void){
        //VLC 播放器实例(可以理解成VLC引擎)
        libvlc_instance_t * inst;
        //VLC 媒体播放器(播放视频时控制, 播放、暂停、停止、音量...)
        libvlc_media_player_t * vlc_player = NULL;
        //播放视频来源,和视频文件的信息(本地视频文件,网络视频文件,RTSP...)
        libvlc_media_t * vlc_media = NULL;
        //初始化VLC引擎
        inst = libvlc_new (0, NULL);
        //指定本地根目录下/test.mp4为视频来源,请按实际路径指定,可以去https://www.haolizi.net/example/view_20786.html下载各种格式测试视频
        vlc_media = libvlc_media_new_path(inst, "/test.mov");
        //创建VLC视频播放器,根据vlc_media
        vlc_player = libvlc_media_player_new_from_media(vlc_media);
        //以下代码暂时不使用vlc_media指针了,所以提前释放了
        libvlc_media_release (vlc_media);
        //设置播放容器,0x4800006并不是死值,这是X11的窗口ID,下边简单说一下获取窗口ID方法
        //也可以不调用此方法,或者窗口ID参数处也可以随意填写一个int值, VLC已做判断,没有找不到指定窗口ID时或没设置窗口ID时都会创建一个窗口播放视频
        //首次调用建议先不要调用此api
        libvlc_media_player_set_xwindow(vlc_player, 0x4800006);
        //播放视频,返回0 表示已开始播放,非0表示播放失败
        int result = libvlc_media_player_play(vlc_player);
        //睡1秒,如果不睡,在后续调用libvlc_media_player_is_playing时会返回0(0:当前未播放, 1:正在播放)!!!,应该是播放视频也需要一些时间,1秒足够
        //不一定必须睡一秒,对libvlc api还不是特别的解,如果您对libvlc非常了解,不要参考此处...
        sleep(1);
        //设置音量,可以发现在控制视频时都需要用到vlc_player指针
        libvlc_audio_set_volume(vlc_player, 50);
        //循环判断当前视频是否是播放状态
        while(libvlc_media_player_is_playing(vlc_player)){
            sleep(1);
        }
        //播放完毕,释放播放器
        libvlc_media_player_release (vlc_player);
        //释放引擎
        libvlc_release (inst);
        return 0;
    }

    编译

    g++ demo.cpp -lvlc -lvlccore
    //一切顺利,会有a.out
    ./a.out
    -lvlc: libvlc.so
    -lvlccore: libvlccore.so
    安装libvlc-dev和libvlccore-dev后,可以全局搜一下libvlc.so和libvlccore.so,我是debian,我安装后在: /usr/lib/x86_64-linux-gnu/下
    注意:如果是通过下载源码编译得到的libvlc.so和libvlccore.so,需要配置ld默认搜索库路径,把libvlc.so和libvlccore.so库所在路径添加到ld搜索路径中,这样才可以编译成功.
    例如debian:
      ld默认配置文件路径为:/etc/ld.so.conf
      最后在/etc/ld.so.conf.d/x86_64-linux-gnu.conf文件中添加vlc库所在路径
      使用ldconfig刷新
      重新尝试
    g++ demo.cpp -lvlc -lvlccore编译

    获取X11的window id

    主要使用xprop和xwininfo命令,如果您有更好的获取window id的方法,那跳过此处:

    xprop和xwininfo命令网络上使用教程太少了,xprop获取的窗口信息很详细,但是没有目标窗口ID- _-,xwininfo虽然获取到的窗口信息很少,但可以获取到目标窗口ID。

    xprop获取当前窗口ID,当前仅发现只能获取当前窗口id

    xprop -root | grep "_NET_ACTIVE_WINDOW(WINDOW)"
    _NET_ACTIVE_WINDOW(WINDOW): window id # 0x6600006
    0x6600006就是当前窗口id,可以把这个获取到的窗口id写到libvlc_media_player_set_xwindow参数中

    也可以直接调用xprop来获取指定窗口信息,但是不能获取指定窗口ID:

    xprop

    执行后鼠标会变成一个十字光标,这时候需要选择一个窗体,来查看这个窗体的一些详细信息

    xwininfo获取指定窗口ID

    xwininfo

    光标也会变成十字,选择窗口后输出:

    xwininfo: Please select the window about which you
              would like information by clicking the
              mouse in that window.
    
    xwininfo: Window id: 0x6600006 "root@ming:~"
    
      Absolute upper-left X:  8
      Absolute upper-left Y:  89
      Relative upper-left X:  23
      Relative upper-left Y:  49
      Width: 733
      Height: 601
      Depth: 24
      Visual: 0x11d
      Visual Class: TrueColor
      Border  0
      Class: InputOutput
      Colormap: 0x6600005 (not installed)
      Bit Gravity State: NorthWestGravity
      Window Gravity State: NorthWestGravity
      Backing Store State: NotUseful
      Save Under State: no
      Map State: IsViewable
      Override Redirect State: no
      Corners:  +8+89  -625+89  -625-78  +8-78
      -geometry 103x36+-15+40

    Window id: 0x6600006 的 0x6600006就是指定窗口ID

     如果启动遇见问题,可以在初始化VLC实例时传入参数,打开日志,libvlc_new改成这样:

    const char * vlc_args[] =
    {
        "-I",
        "dummy",
        "--extraintf=logger",
        "--verbose=2"
    };
    inst = libvlc_new (sizeof(vlc_args)/sizeof(vlc_args[0]), vlc_args);
    vlc_media
  • 相关阅读:
    openfire学习4------->android客户端聊天开发之聊天功能开发
    MTD中的nand驱动初步分析---面向u-boot
    在线代码编缉器
    三个角度解构云计算,商业驱动or技术驱动?
    分布式存储的三个基本问题
    云计算核心技术
    云计算历史
    《信息产业指南》云计算解读
    2017云计算市场需要密切关注的10个趋势
    2017云计算机会
  • 原文地址:https://www.cnblogs.com/GengMingYan/p/14878804.html
Copyright © 2020-2023  润新知