基于vlc-qt的视频播放器(支持添加视频列表单曲循环等)(代码片段)

b11252 b11252     2023-03-31     296

关键词:

        基于libvlc和Qt实现了一个视频播放器,可实现列表循环播放,单曲播放等,效果好于Qt自带的视频播放库。网上已有诸多基于vlc库的视频播放器,但设计列表播放的资源较少,基于vlc实现列表播放主要利用了libvlc_media_list_player_t和libvlc_media_list_t两个类。

也可查看本人github项目,附链接:

github主页:https://github.com/qin11152

环境准备及接口实现

        首先需要下载vlc相关库文件,可以在http://download.videolan.org/pub/videolan/vlc/下载对应的版本,安装后可在安装目录下找到对应的vlc库文件。在项目的包含目录中包含头文件,并链接libvlc和libvlccore两个动态库。之后便可进行相应开发。

相关编码实现

libvlc_instance_t* m_ptrVlcInstance = libvlc_new(0, NULL);

    使用vlc库首先需要new一个libvlc的实例,类型为libvlc_instance_t,后续相关操作均基于此对象。

播放器实例

libvlc_media_player_t* m_ptrMediaPlayer= libvlc_media_player_new(m_ptrVlcInstance);    //1媒体播放器
libvlc_media_player_set_hwnd(m_ptrMediaPlayer, (void *)ui.playWidget->winId());    //2设置播放窗口
libvlc_media_player_play():    //3播放
libvlc_media_player_pause():    //4暂停
libvlc_media_player_stop();    //5停止

        libvlc_media_player_t代表一个vlc的媒体播放器,可用于播放视频,但其功能不仅用于播放视频。上述代码中的2则是指定了媒体播放的界面,通过传递句柄可以指定媒体在具体的某一个widget上进行播放。后续的几个接口可以进行播放,暂停和结束,但因本项目为列表播放,所以不使用上述控制接口,若进行单视频播放可使用上述接口。

媒体列表及媒体列表播放器

libvlc_media_list_t* m_ptrMediaList=libvlc_media_list_new(m_ptrVlcInstance);    //1媒体列表
libvlc_media_list_player_t* m_ptrListMediaPlayer = libvlc_media_list_player_new(m_ptrVlcInstance);    //2媒体列表播放器
libvlc_media_list_player_set_media_list(m_ptrListMediaPlayer, m_ptrMediaList);    //3为列表播放器设置媒体列表
libvlc_media_list_player_set_media_player(m_ptrListMediaPlayer, m_ptrMediaPlayer);    //4为列表播放器设置播放器实例
libvlc_media_list_player_set_playback_mode(m_ptrListMediaPlayer, libvlc_playback_mode_repeat);    //5循环模式

    libvlc_media_list_t(媒体列表)和libvlc_media_list_player_t(媒体列表播放器)两个对象是实现列表播放的重点。实例化两个对象后首先需要将媒体列表设定到媒体列表播放器中,如上述代码3所示。之后需要为媒体列表播放器设定播放器实体,如上述代码4所示,此播放器实体就是前面实例化的libvlc_media_player_t。可通过代码5设定列表播放器的循环方式(列表循环,单曲循环)。

libvlc_media_t* m_ptrMedia =libvlc_media_new_path(m_ptrVlcInstance,item.toUtf8().data());    //1实例化一个媒体对象
libvlc_media_list_add_media(m_ptrMediaList, m_ptrMedia);    //2添加媒体对象到媒体列表
libvlc_media_parse(m_ptrMedia);    //3释放资源 

    像媒体列表中传入媒体对象时,首先需要实例化一个媒体对象,实例化时需指定媒体所在的路径,然后调用上述代码中第2行接口将媒体对象塞到已有的媒体列表中即可。执行完后需要释放媒体对象。存在多个媒体时只需要循环的添加即可。媒体列表和媒体列表播放器也提供了诸多借口来进行控制,如下面代码所示,具体功能可参考注释。

libvlc_media_list_count( libvlc_media_list_t *p_ml );    //返回媒体列表中数量
libvlc_media_list_remove_index( libvlc_media_list_t *p_ml, int i_pos );    //根据index移除媒体列表中某一项
libvlc_media_list_insert_media( libvlc_media_list_t *p_ml, libvlc_media_t *p_md, int i_pos );    //像媒体列表中指定位置插入播放对象
libvlc_media_list_player_play(libvlc_media_list_player_t * p_mlp);    //列表播放开始
libvlc_media_list_player_pause(libvlc_media_list_player_t * p_mlp);    //列表播放暂停
libvlc_media_list_player_play_item_at_index(libvlc_media_list_player_t * p_mlp,int i_index);    //播放指定位置视频
libvlc_media_list_player_previous(libvlc_media_list_player_t * p_mlp);    //播放前一个视频
libvlc_media_list_player_next(libvlc_media_list_player_t * p_mlp);    //播放下一个视频

回调事件管理

libvlc_event_manager_t* em = libvlc_media_player_event_manager(m_ptrMediaPlayer);    //回到事件管理器
libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, vlcEvents, this);    //注册关注的回调事件


void vlcEvents(const libvlc_event_t *ev, void *param)


 Q_UNUSED(param);
    switch (ev->type) 
    
    case libvlc_MediaPlayerTimeChanged:
    
        //从回调事件中得到播放时间
        auto tmpTime= ev->u.media_player_time_changed.new_time;
        QString time = "";
        m_ptrThis->transferTime(time, tmpTime);
        m_ptrThis->ui.horizontalSlider->setValue(tmpTime);
        m_ptrThis->ui.curTimeLabel->setText(time);
    
        break;
default:
        break;
    

    在使用vlc库的过程中,可以通过注册相关回调。使用方法如上述代码前半部分所示,修改libvlc_event_attach中第二个参数值即可得到不同事件的回调。对于回调事件的处理则需要重写vlcEvents函数实现,如上述代码中后半部分所示,对于播放时间、播放进度、播放视频切换至下一个等事件均需这样获取,然后才可以进行下一步处理。

其它接口

libvlc_media_get_duration( libvlc_media_t *p_md );    //获取视频时长
libvlc_media_player_set_time( libvlc_media_player_t *p_mi, libvlc_time_t i_time );    //设置视频播放至某一位置
libvlc_audio_get_volume( libvlc_media_player_t *p_mi );    //获取音量
libvlc_audio_set_volume( libvlc_media_player_t *p_mi, int i_volume );    //设置音量

    上述代码中列出了一些常用的接口,其作用如注释所示,如需要更详细介绍或其它接口,可查看文档或库文件。

实际工程

 代码如下,也可在本人github中查看下载具体工程。github地址:https://github.com/qin11152 

#include "MyMediaplayer.h"
#include <algorithm>

int MyMediaplayer::curTime =  0 ;
MyMediaplayer* MyMediaplayer::m_ptrThis =  nullptr ;
MyMediaplayer::MyMediaplayer(QWidget *parent)
    : QWidget(parent)

    ui.setupUi(this);
    initData();
    initConnect();
    m_ptrThis = this;


void MyMediaplayer::onPlayCurrentVedio()

    if (m_ptrMediaPlayer == nullptr)
    
        return;
    
    if (bool(libvlc_media_list_player_is_playing(m_ptrListMediaPlayer)))
    
        return;
    
    libvlc_media_list_player_play(m_ptrListMediaPlayer);
    int volumes = libvlc_audio_get_volume(m_ptrMediaPlayer);
    ui.VolumeSlider->setValue(volumes);


void MyMediaplayer::onPauseCurrentVideo()

    if (m_ptrListMediaPlayer == nullptr)
    
        return;
    
    if (bool(libvlc_media_list_player_is_playing(m_ptrListMediaPlayer)))
    
        m_bIsPlay = false;
        libvlc_media_list_player_pause(m_ptrListMediaPlayer);
    


void MyMediaplayer::onStopCurrentVideo()

    if (m_ptrListMediaPlayer == nullptr)
    
        return;
    
    m_bIsPlay = false;
    libvlc_media_list_player_stop(m_ptrListMediaPlayer);
    freeVlc();


void MyMediaplayer::onOpenPushButtonClicked()

    m_vecPlayList.clear();
    if (m_ptrVlcInstance)
    
        freeVlc();
    
    QStringList tmp = QFileDialog::getOpenFileNames(this, u8"打开视频", ".", u8"视频文件(*.mp4 *.mp3 *.flv *.3gp *.rmvb)");
    if (tmp.empty())
    
        return;
    
    for (auto& item : tmp)
    
        if (std::find(m_vecPlayList.begin(), m_vecPlayList.end(), item) == m_vecPlayList.end())
        
            m_vecPlayList.push_back(QDir::toNativeSeparators(item));
        
    
    m_strCurPath = QDir::toNativeSeparators(tmp[0]);
    setplayList();


void MyMediaplayer::onPausePushButtonClicked()

    onPauseCurrentVideo();


void MyMediaplayer::onPlayPushButtonClicked()

    onPlayCurrentVedio();


void MyMediaplayer::onStopPushButtonClicked()

    onStopCurrentVideo();


void MyMediaplayer::onSliderRelease(int val)

    int time = ui.horizontalSlider->value();
    libvlc_media_player_set_time(m_ptrMediaPlayer, val);


void MyMediaplayer::onSingleButtonClicked()

    if (m_bIsSingleCycle)
    
        ui.pushButton->setText(u8"列表循环");
        m_bIsSingleCycle = false;
        if (nullptr != m_ptrListMediaPlayer)
        
            libvlc_media_list_player_set_playback_mode(m_ptrListMediaPlayer, libvlc_playback_mode_loop);
        
    
    else
    
        ui.pushButton->setText(u8"单曲循环");
        m_bIsSingleCycle = true;
        if (nullptr != m_ptrListMediaPlayer)
        
            libvlc_media_list_player_set_playback_mode(m_ptrListMediaPlayer, libvlc_playback_mode_repeat);
        
    


void MyMediaplayer::onSignalFreshButtonClicked()

    /*if (!m_ptrVlcInstance)
    
        return;
    
    QString item = u8"D:/技改技措业务_产品技术.mp4";
    item = QDir::toNativeSeparators(item);
    m_ptrMedia = libvlc_media_new_path(m_ptrVlcInstance, item.toUtf8().data());
    if (!m_ptrMedia)
    
        return;
    
    libvlc_media_list_add_media(m_ptrMediaList, m_ptrMedia);
    libvlc_media_parse(m_ptrMedia);
    libvlc_media_release(m_ptrMedia);*/
    return;


void MyMediaplayer::initData()

    ui.VolumeSlider->setMinimum(0);
    ui.VolumeSlider->setMaximum(100);
    m_ptrFileDialog = new QFileDialog(this);
    m_ptrFileDialog->hide();


bool MyMediaplayer::initVlcData()

    m_ptrVlcInstance = libvlc_new(0, NULL);
    if (!m_ptrVlcInstance)
    
        qDebug() << "qqqq create vlc failed";
        qDebug() << libvlc_errmsg;
        freeVlc();
        return false;
    
    m_ptrListMediaPlayer = libvlc_media_list_player_new(m_ptrVlcInstance);
    if (!m_ptrListMediaPlayer)
    
        qDebug() << "qqqq create m_ptrListMediaPlayer failed";
        freeVlc();
        return false;
    
    m_ptrMediaList = libvlc_media_list_new(m_ptrVlcInstance);
    if (!m_ptrMediaList)
    
        qDebug() << "qqqq create m_ptrMediaList failed";
        freeVlc();
        return false;
    
    m_ptrMediaPlayer = libvlc_media_player_new(m_ptrVlcInstance);
    libvlc_video_set_mouse_input(m_ptrMediaPlayer, false);
    libvlc_video_set_key_input(m_ptrMediaPlayer, false);
    if (!m_ptrMediaPlayer)
    
        freeVlc();
        qDebug() << "qqqq my media player failed";
        return false;
    
    libvlc_event_manager_t* em = libvlc_media_player_event_manager(m_ptrMediaPlayer);
    libvlc_event_attach(em, libvlc_MediaPlayerTimeChanged, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerEndReached, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerStopped, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPlaying, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPaused, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerPositionChanged, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerLengthChanged, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerTitleChanged, vlcEvents, this);
    libvlc_event_attach(em, libvlc_MediaPlayerVout, vlcEvents, this);
    //libvlc_media_player_set_hwnd(m_ptrMediaPlayer, (void *)ui.playWidget->winId());
    return true;


void MyMediaplayer::initConnect()

    connect(ui.openPushButton, &QPushButton::clicked, this, &MyMediaplayer::onOpenPushButtonClicked);
    connect(ui.playPushButton, &QPushButton::clicked, this, &MyMediaplayer::onPlayPushButtonClicked);
    connect(ui.pausePushButton, &QPushButton::clicked, this, &MyMediaplayer::onPausePushButtonClicked);
    connect(ui.stopPushButton, &QPushButton::clicked, this, &MyMediaplayer::onStopPushButtonClicked);
    connect(ui.horizontalSlider, &QSlider::sliderMoved, this, &MyMediaplayer::onSliderRelease);
    connect(ui.pushButton, &QPushButton::clicked, this, &MyMediaplayer::onSingleButtonClicked);
    connect(ui.VolumeSlider, &QSlider::valueChanged, this, [&](int val)
        
            if (nullptr != m_ptrMediaPlayer)
            
                qDebug() << "qqqq val:" << val;
                libvlc_audio_set_volume(m_ptrMediaPlayer, val);
            
        );


void MyMediaplayer::freeVlc()

    if (m_ptrMedia)
    
        libvlc_media_release(m_ptrMedia);
        m_ptrMedia = nullptr;
    
    if (m_ptrMediaPlayer)
    
        libvlc_media_player_stop(m_ptrMediaPlayer);
        libvlc_media_player_release(m_ptrMediaPlayer);
        m_ptrMediaPlayer = nullptr;
    
    if (m_ptrVlcInstance)
    
        libvlc_release(m_ptrVlcInstance);
        m_ptrVlcInstance = nullptr;
    
    if (m_ptrListMediaPlayer)
    
        libvlc_media_list_player_stop(m_ptrListMediaPlayer);
        libvlc_media_list_player_release(m_ptrListMediaPlayer);
        m_ptrListMediaPlayer = nullptr;
    
    if (m_ptrMediaList)
    
        libvlc_media_list_release(m_ptrMediaList);
        m_ptrMediaList = nullptr;
    


void MyMediaplayer::transferTime(QString& time, int msTime)

    msTime = msTime / 1000;
    int hour = msTime / 3600;
    msTime = msTime % 3600;
    int minute = msTime / 60;
    msTime = msTime % 60;
    if (hour > 0)
    
        time += QString::number(hour);
        time += ":";
    
    if (minute < 10)
    
        time += "0";
        time += QString::number(minute);
        time += ":";
    
    else
    
        time += QString::number(minute);
        time += ":";
    
    if (msTime < 10)
    
        time += "0";
        time += QString::number(msTime);
    
    else
    
        time += QString::number(msTime);
    


void MyMediaplayer::setplayList()

    if (m_ptrVlcInstance)
    
        freeVlc();
    
    if (!initVlcData())
    
        return;
    
    bool first = true;
    for (auto& item : m_vecPlayList)
    
        qDebug() << "qqqq path is" << item.toUtf8().data();
        m_ptrMedia = libvlc_media_new_path(m_ptrVlcInstance, item.toUtf8().data());
        if (m_ptrMedia)
        
            qDebug() << "qqqq create media succ";
        
        else
        
            qDebug() << "qqqq create media failed";
        
        libvlc_media_list_add_media(m_ptrMediaList, m_ptrMedia);
        libvlc_media_parse(m_ptrMedia);
        if (first)
        
            first = false;
            int time = libvlc_media_get_duration(m_ptrMedia);
            QString strTime = "";
            ui.horizontalSlider->setMaximum(time);
            ui.horizontalSlider->setMinimum(0);
            transferTime(strTime, time);
            ui.totalTimelabel->setText(strTime);
        
        libvlc_media_release(m_ptrMedia);
    
    m_ptrMedia = nullptr;
    libvlc_media_list_player_set_media_list(m_ptrListMediaPlayer, m_ptrMediaList);
    libvlc_media_list_player_set_media_player(m_ptrListMediaPlayer, m_ptrMediaPlayer);
    if (m_bIsSingleCycle)
    
        libvlc_media_list_player_set_playback_mode(m_ptrListMediaPlayer, libvlc_playback_mode_repeat);
    
    else
    
        libvlc_media_list_player_set_playback_mode(m_ptrListMediaPlayer, libvlc_playback_mode_loop);
    
    libvlc_media_player_set_hwnd(m_ptrMediaPlayer, (void*)ui.playWidget->winId());


void MyMediaplayer::vlcEvents(const libvlc_event_t* ev, void* param)

    Q_UNUSED(param);
    switch (ev->type)
    
    case libvlc_MediaPlayerTimeChanged:
    
        //curTime = ev->u.media_player_time_changed.new_time;
        auto tmpTime = ev->u.media_player_time_changed.new_time;
        QString time = "";
        m_ptrThis->transferTime(time, tmpTime);
        m_ptrThis->ui.horizontalSlider->setValue(tmpTime);
        m_ptrThis->ui.curTimeLabel->setText(time);
    
    break;
    case libvlc_MediaPlayerEndReached:
        break;
    case libvlc_MediaPlayerStopped:
        //m_ptrThis->onPlayFinish();
        break;
    case libvlc_MediaPlayerPlaying:
        break;
    case libvlc_MediaPlayerPaused:
        break;
    case libvlc_MediaPlayerPositionChanged:
    
    
    break;
    case libvlc_MediaPlayerVout:
    
        qDebug() << ev->u.media_player_vout.new_count;
    
    break;
    case libvlc_MediaPlayerLengthChanged:
    
        int time = (ev->u.media_player_length_changed.new_length);
        qDebug() << "qqqq" << time;
        QString strtime = "";
        m_ptrThis->transferTime(strtime, time);
        m_ptrThis->ui.horizontalSlider->setMaximum(time);
        m_ptrThis->ui.totalTimelabel->setText(strtime);
    
    break;
    default:
        break;
    


MyMediaplayer::~MyMediaplayer()

    freeVlc();
    delete m_ptrFileDialog;
    m_ptrFileDialog = nullptr;

hls视频播放-基于chplayer(代码片段)

...载hls的m3u8格式文件,不能用在chrome,ie等浏览器上。 基于ChPlayer视频播放经过查询资料发现ChPlayer,使用ChPlayer进行视频的播放,支持点播和直播,支持m3u8格式。调用示例:<scr 查看详情

javascripthtml5视频播放器

需要一个jsh5的在线视频播放器给我文件不要给个链接或者swf的(但最好要能放h264的)也凑合了款很棒的HTML5视频播放器作为下一代的网页语言,HTML5拥有很多让人期待已久的新特性,其中之一就是video标签,让开发者可以在网页中... 查看详情

javascripthtml5视频播放器

款很棒的HTML5视频播放器作为下一代的网页语言,HTML5拥有很多让人期待已久的新特性,其中之一就是video标签,让开发者可以在网页中和添加图片一样简单的方式添加视频。1、VideoJSVideoJS是最流行的HTML5视频播放器,免费、开源... 查看详情

Open Graph 基于 iframe 的视频嵌入支持?

...述】:我希望能够为Facebook新闻源和时间线提供iframe视频播放器。我知道可以为不同的视频格式指定多个og:video:type属性以显示在新闻源/时间线中。例如一个实现,例如ShareHTML5playeronFacebookwa 查看详情

将视频添加到 YouTube 上用户的“稍后观看”播放列表

】将视频添加到YouTube上用户的“稍后观看”播放列表【英文标题】:Addvideotouser\'s"WatchLater"playlistonYouTube【发布时间】:2017-07-1916:40:37【问题描述】:目的是使用YouTubeAPI创建一个稍后观看按钮。当用户单击按钮时,视频... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持流媒体地址播放

QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(一)https://xiaolong.blog.csdn.net/article/details/126832537QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(二)https://xiaolong.blog.csdn.net/article/details/126833434QT软件开发-基于FFMPEG设... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解-完整例子

QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(一)https://xiaolong.blog.csdn.net/article/details/126832537QT软件开发-基于FFMPEG设计视频播放器-支持软解与硬解(二)https://xiaolong.blog.csdn.net/article/details/126833434QT软件开发-基于FFMPEG设... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解(代码片段)

...本概念,完成了ffmpeg对视频软件解码并渲染,实现了基本播放器功能设计。这篇文章介绍ffmpeg硬件加速解码视频的流程,完成基本播放器设计。我这里开发视频播放器用到的环境介绍:ffmpeg版本:4.2.2Qt版本:5.12.6编译器类型:MinGW32b... 查看详情

将视频添加到 YouTube 上用户的收藏夹/点赞播放列表

】将视频添加到YouTube上用户的收藏夹/点赞播放列表【英文标题】:Addvideotouser\'sFavorite/LikeplaylistonYouTube【发布时间】:2017-08-3023:00:16【问题描述】:目的是使用YouTubeAPI创建一个收藏/点赞按钮。当用户点击该按钮时,视频被保存... 查看详情

基于react的audio组件(代码片段)

样式请自己定义哦~需要其他功能请自行添加!//组件调用<Audiosrc=src地址id=srcID/>audio属性src歌曲的路径preload是否在页面加载后立即加载(设置autoplay后无效)controls显示audio自带的播放控件loop音频循环autoplay音频加载后自动播... 查看详情

基于react的audio组件(代码片段)

样式请自己定义哦~需要其他功能请自行添加!//组件调用<Audiosrc=src地址id=srcID/>audio属性src歌曲的路径preload是否在页面加载后立即加载(设置autoplay后无效)controls显示audio自带的播放控件loop音频循环autoplay音频加载后自动播... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解(代码片段)

...频解码,完成视频帧渲染,音频解码播放。之前做的视频播放器里,虽然也使用了硬件加速解码,解码确实快,但是渲染都采用QWidget方式渲染绘制,占用CPU较高,并且采用QWidget方式渲染,需要将硬解码之后的数据转为RGB24,然... 查看详情

安卓liveplayer是干嘛的

安卓LivePlayer是一款安卓平台上的视频播放器,支持播放本地视频、网络视频、直播视频等,支持多种视频格式,支持视频播放、暂停、快进、快退等操作,支持视频播放时调节音量、亮度等,支持视频播放时设置播放模式,支... 查看详情

基于libmpv内核设计开发的视频播放器-高级版(代码片段)

...已经对libmpv做了详细的介绍,第二篇文章里完成了完整的播放器开发,设计了UI,实现了播放器的基本功能。这一篇里对libmpv完成功能扩展,增加进度条预览图的支持(鼠标放在进度条上弹出预览窗口),支持视频章节解析渲染... 查看详情

基于libmpv内核设计开发的视频播放器-高级版(代码片段)

...已经对libmpv做了详细的介绍,第二篇文章里完成了完整的播放器开发,设计了UI,实现了播放器的基本功能。这一篇里对libmpv完成功能扩展,增加进度条预览图的支持(鼠标放在进度条上弹出预览窗口),支持视频章节解析渲染... 查看详情

armavi视频播放基于2440freambuffer绘制

AVI文件格式图解 整理:AVI是一种容器,里面放什么格式的数据都可以视频编码:格式可以是H264,MPEG-4,MJPEG,因为MJPEG比较简单,所以仅支持MJPEG的avi视频。音频编码:PCM16,mp3因为PCM编码,文件实在过大,所以仅支持mp3编码。难... 查看详情

qt软件开发-基于ffmpeg设计视频播放器-支持软解与硬解(代码片段)

...peg基本概念,完成了ffmpeg对视频解码并渲染,实现了基本播放器功能设计。只是之前都只是解码了图像,忽略了音频数据,这篇文章介绍ffmpeg如何解码音频,制作一个音乐播放器,为后续的完整播放器做铺垫。ffmpeg版本:4.2.2Qt版... 查看详情

安卓基于jcvideoplayer播放视频(本地网络),基于java计数器实现视频轮播(代码片段)

JCVideoPlayer是一款开源的播放器 如果通过控件播放网络视频和本地视频?代码很简单:JCVideoPlayer.toFullscreenActivity(this,"http://vfx.mtime.cn/Video/2019/03/09/mp4/190309153658147087.mp4","http://p.qpic.cn/videoyun/0/2449_43b6f696980311e59ed467f2... 查看详情