前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >采用libvlc做一个视频播放器(续)-注册事件回调

采用libvlc做一个视频播放器(续)-注册事件回调

作者头像
DS小龙哥
发布2024-05-24 08:33:58
1700
发布2024-05-24 08:33:58
举报
文章被收录于专栏:嵌入式项目开发

一、功能介绍

在前面文章里已经介绍过,如何调用libvlc提供的API快速开发一款简单的视频播放器(https://juejin.cn/post/7023552394798006279) 这篇文章继续完善视频播放器的基本功能。 增加播放进度条、播放时间进度显示、实时获取播放过程中的状态等等。

libvlc提供了事件回调,注册相应的事件之后,在回调里可以得到各种事件,比如: 开始播放状态、停止播放、暂停播放、播放进度等等。

事件注册示例代码:

代码语言:javascript
复制
//创建事件管理器
libvlc_event_manager_t * eventManager = libvlc_media_player_event_manager(vlc_mediaPlayer);

//订阅事件
attachEvents(eventManager);

//订阅事件
void Widget::attachEvents(libvlc_event_manager_t *eventManager)
{
    // 事件列表
    QList<libvlc_event_e> events = {
        libvlc_MediaPlayerPositionChanged,
        libvlc_MediaPlayerTimeChanged,
        libvlc_MediaPlayerLengthChanged,
        libvlc_MediaPlayerPaused,
        libvlc_MediaPlayerPlaying,
        libvlc_MediaPlayerStopped,
        libvlc_MediaPlayerEndReached,
        libvlc_MediaParsedChanged
    };

    // 订阅事件
    for (const libvlc_event_e &e : events)
    {
        libvlc_event_attach(eventManager, e, vlcEvents, nullptr);
    }
}


void Widget::vlcEvents(const libvlc_event_t *event, void *param)
{
    qint64 pos=0;
    switch (event->type){
    case libvlc_MediaPlayerTimeChanged:
         //获取当前媒体播放的位置
         pos=event->u.media_player_time_changed.new_time;
         pThis->ui->label_t1->setText(QTime(0, 0, 0,0).addMSecs(int(pos)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
         pThis->ui->horizontalSlider_pos->setValue(pos);
         break;
    case libvlc_MediaPlayerPositionChanged:
         //qDebug() << "Position: " << event->u.media_player_position_changed.new_position << endl;
         break;
    case libvlc_MediaPlayerLengthChanged:
         qDebug() << "Length:"<< event->u.media_player_length_changed.new_length;
         break;
    case libvlc_MediaPlayerEndReached:
         qDebug() << "VLC播放完毕.";
         break;
    case libvlc_MediaPlayerStopped:
         qDebug() << "VLC停止播放";
         break;
    case libvlc_MediaPlayerPlaying:
         qDebug() << "VLC开始播放";
         break;
    case libvlc_MediaPlayerPaused:
         qDebug() << "VLC暂停播放";
         break;
    case libvlc_MediaParsedChanged: //获取媒体信息
          qDebug() << "获取媒体信息";
         break;
    }
}

最终运行效果:

二、完整实现代码

2.1 widget.cpp
代码语言:javascript
复制
#include "widget.h"
#include "ui_widget.h"

Widget* Widget::pThis = nullptr;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    pThis=this;

    ui->setupUi(this);

    //创建并初始化libvlc实例
    vlc_base=libvlc_new(0,nullptr);

    this->setWindowTitle("libvlc设计的视频播放器");
}


Widget::~Widget()
{
    delete ui;
}

//选择视频
void Widget::on_pushButton_open_clicked()
{
    /*选择文件*/
    QString filename=QFileDialog::getOpenFileName(this,"选择打开的文件","D:/",tr("*.*"));

    std::replace(filename.begin(), filename.end(), QChar('/'), QChar('\\'));
    qDebug()<<"播放的媒体:"<<filename;

    /*为特定文件路径创建媒体*/
    if(vlc_media)libvlc_media_release(vlc_media);
    vlc_media=libvlc_media_new_path(vlc_base,filename.toUtf8().data());
    if(vlc_media==nullptr)
    {
        qDebug()<<"libvlc_media_new_path 执行错误.";
        return;
    }

    /*根据给定的媒体对象创建一个播放器对象*/
    if(vlc_mediaPlayer)libvlc_media_player_release(vlc_mediaPlayer);
    vlc_mediaPlayer=libvlc_media_player_new_from_media(vlc_media);

    //创建事件管理器
    eventManager = libvlc_media_player_event_manager(vlc_mediaPlayer);

    //订阅事件
    attachEvents(eventManager);

    /*设置给予媒体播放器媒体输出的win32/win64窗口句柄*/
    libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui->widget->winId());

    /*播放媒体文件*/
    if(vlc_mediaPlayer)libvlc_media_player_play(vlc_mediaPlayer);

    //等待VLC解析文件.否则下面的时间获取不成功
    QThread::msleep(500);

    //获取媒体文件总长度 ms
    libvlc_time_t length = libvlc_media_player_get_length(vlc_mediaPlayer);
    qDebug()<<"媒体文件总长度:"<<length;
    ui->label_t2->setText(QTime(0, 0, 0,0).addMSecs(int(length)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
    ui->horizontalSlider_pos->setMaximum(length);
    ui->horizontalSlider_pos->setMinimum(0);
}


//暂停与继续
void Widget::on_pushButton_pause_clicked()
{
    if(vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}

//停止
void Widget::on_pushButton_stop_clicked()
{
    if(vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
}


//订阅事件
void Widget::attachEvents(libvlc_event_manager_t *eventManager)
{
    // 事件列表
    QList<libvlc_event_e> events = {
        libvlc_MediaPlayerPositionChanged,
        libvlc_MediaPlayerTimeChanged,
        libvlc_MediaPlayerLengthChanged,
        libvlc_MediaPlayerPaused,
        libvlc_MediaPlayerPlaying,
        libvlc_MediaPlayerStopped,
        libvlc_MediaPlayerEndReached,
        libvlc_MediaParsedChanged
    };

    // 订阅事件
    for (const libvlc_event_e &e : events)
    {
        libvlc_event_attach(eventManager, e, vlcEvents, nullptr);
    }
}


void Widget::vlcEvents(const libvlc_event_t *event, void *param)
{
    qint64 pos=0;
    switch (event->type){
    case libvlc_MediaPlayerTimeChanged:
         //获取当前媒体播放的位置
         pos=event->u.media_player_time_changed.new_time;
         pThis->ui->label_t1->setText(QTime(0, 0, 0,0).addMSecs(int(pos)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
         pThis->ui->horizontalSlider_pos->setValue(pos);
         break;
    case libvlc_MediaPlayerPositionChanged:
         //qDebug() << "Position: " << event->u.media_player_position_changed.new_position << endl;
         break;
    case libvlc_MediaPlayerLengthChanged:
         qDebug() << "Length:"<< event->u.media_player_length_changed.new_length;
         break;
    case libvlc_MediaPlayerEndReached:
         qDebug() << "VLC播放完毕.";
         break;
    case libvlc_MediaPlayerStopped:
         qDebug() << "VLC停止播放";
         break;
    case libvlc_MediaPlayerPlaying:
         qDebug() << "VLC开始播放";
         break;
    case libvlc_MediaPlayerPaused:
         qDebug() << "VLC暂停播放";
         break;
    case libvlc_MediaParsedChanged: //获取媒体信息
          qDebug() << "获取媒体信息";
         break;
    }
}
2.2 widget.h
代码语言:javascript
复制
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <vlc/vlc.h>
#include <QDebug>
#include <QFileDialog>
#include <QMoveEvent>
#include <QTime>
#include <QThread>

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
    void attachEvents(libvlc_event_manager_t *eventManager);
private slots:
    void on_pushButton_open_clicked();

    void on_pushButton_pause_clicked();

    void on_pushButton_stop_clicked();
protected:
    static void vlcEvents(const libvlc_event_t *ev, void *param);
private:
    Ui::Widget *ui;
    static Widget *pThis;
    libvlc_instance_t *vlc_base=nullptr;
    libvlc_media_t *vlc_media=nullptr;
    libvlc_media_player_t *vlc_mediaPlayer=nullptr;
    libvlc_event_manager_t *eventManager;
};
#endif // WIDGET_H
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-05-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、功能介绍
  • 二、完整实现代码
    • 2.1 widget.cpp
      • 2.2 widget.h
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档