【Qt 学习之路】Qt+VLC播放多个视频的Demo

24 篇文章 1 订阅
11 篇文章 0 订阅

目录

1、先看示例

2、源代码

3、如何使用


1、先看示例

这个Demo做的是同时播放9个相同的视频:

详细代码可以参考我写的这篇:Qt+VLC简单的使用显示视频Demo

2、源代码

目前做的这个小Demo代码微微做了一点小优化,单独封装的类:

#ifndef SVLCCONTROL_H
#define SVLCCONTROL_H

#include <QWidget>
#include <QLabel>
struct libvlc_media_track_info_t;
struct libvlc_media_t;
struct libvlc_instance_t;
struct libvlc_media_player_t;
struct libvlc_event_t;

class SVLCControl : public QWidget
{
    Q_OBJECT
public:
    explicit SVLCControl(QLabel* lab, QWidget *parent = 0);

    bool load(const QString &filepath);
    void play();
    void pause();
    void stop();
    bool loadVlc(const QString &filepath);
    void freeVlc();
protected:
    static void vlcEvents(const libvlc_event_t *ev, void *param);

private:
    QLabel* m_lab = Q_NULLPTR;
    libvlc_instance_t *m_vlcInstance = Q_NULLPTR;
    libvlc_media_t *m_media = Q_NULLPTR;
    libvlc_media_player_t *m_mediaPlayer = Q_NULLPTR;

    QMutex m_mutex;
    qint64 m_duration = 0;
    bool m_bPlaying = false;
};

#endif // SVLCCONTROL_H

#include "svlccontrol.h"
#include <QDir>
#include <QFile>
#include <QGraphicsScene>
#include <QGraphicsProxyWidget>
#include <QGraphicsView>
#include "vlc/vlc.h"
#include <QDebug>

SVLCControl::SVLCControl(QLabel *lab, QWidget *parent) : QWidget(parent)
{
    m_lab = lab;
}

bool SVLCControl::load(const QString &filepath)
{
    if(filepath.isEmpty()){
        qDebug() << "filepath isEmpty";
        return false;
    }
    if(!QFile::exists(filepath)){
        qDebug() << "QFile no exists";
        return false;
    }
    bool bload = loadVlc(QDir::toNativeSeparators(filepath).toUtf8().constData());
    if(!bload){
        qDebug() << "bload no isEmpty";
        return false;
    }
    return true;
}

void SVLCControl::play()
{
    if(libvlc_Ended == libvlc_media_get_state(m_media)){
        stop();//vlc这个设定太奇怪了,当自然播放结束,重新播放还得主动调用一次stop();
    }
    libvlc_media_player_play(m_mediaPlayer);
}

void SVLCControl::pause()
{
    if((bool)libvlc_media_player_is_playing(m_mediaPlayer)){
        m_bPlaying = false;
        libvlc_media_player_set_pause(m_mediaPlayer, 1);//暂停
    }
}

void SVLCControl::stop()
{
    m_bPlaying = false;
    libvlc_media_player_stop(m_mediaPlayer);
}

bool SVLCControl::loadVlc(const QString &filepath)
{
    m_vlcInstance = libvlc_new(0, NULL);
    m_media = libvlc_media_new_path(m_vlcInstance, filepath.toUtf8().data());
    if(!m_media){
        freeVlc();
        return m_media;
    }
    qDebug() << "SVLCControl:loadVlc:" << qPrintable(filepath);
    m_mediaPlayer = libvlc_media_player_new_from_media(m_media);
    if(!m_mediaPlayer){
        freeVlc();
        return false;
    }
    libvlc_media_parse(m_media);
    libvlc_event_manager_t *em = libvlc_media_player_event_manager(m_mediaPlayer);
    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_media_player_set_hwnd(m_mediaPlayer, (void *)m_lab->winId());
    return true;
}

void SVLCControl::freeVlc()
{
    if(m_media){
        libvlc_media_release(m_media);
        m_media = Q_NULLPTR;
    }
    if(m_mediaPlayer){
        libvlc_media_player_stop(m_mediaPlayer);
        libvlc_media_player_release(m_mediaPlayer);
        m_mediaPlayer = Q_NULLPTR;
    }
    if(m_vlcInstance){
        libvlc_release(m_vlcInstance);
        m_vlcInstance = Q_NULLPTR;
    }
}

void SVLCControl::vlcEvents(const libvlc_event_t *ev, void *param)
{
    Q_UNUSED(param);
    switch (ev->type) {
    case libvlc_MediaPlayerTimeChanged:
        break;
    case libvlc_MediaPlayerEndReached://不能在回调里调用stop();否则会卡死
        break;
    case libvlc_MediaPlayerStopped:
        qDebug() << "libvlc_MediaPlayerStopped";
        break;
    case libvlc_MediaPlayerPlaying:
        qDebug() << "libvlc_MediaPlayerPlay";
        break;
    case libvlc_MediaPlayerPaused:
        qDebug() << "libvlc_MediaPlayerPaused";
        break;
    }
}

3、如何使用

调用方法:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QFileDialog>
#include <QLabel>
#include "svlccontrol.h"

namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
 private slots:
    void on_pushButton_clicked();
    void on_pB_Stop_clicked();
    void on_pB_Open_clicked();

private:
    Ui::MainWindow *ui;
    QFileDialog *m_fileDialog = Q_NULLPTR;
    QList <QLabel*> m_allBgs;
    QList <SVLCControl*> m_allVideos;
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QFile>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    m_fileDialog = new QFileDialog(this);
    m_fileDialog->setWindowTitle(tr("Open Video"));
    m_fileDialog->setDirectory(".");
    m_fileDialog->setNameFilter(tr("Video Files(*.mp4 *.mp3 *flv *3gp *rmvb)"));
    m_fileDialog->hide();
    qDebug() << "is:" << ui->widget->size();
    int tmpW = ui->widget->width()/3;
    int tmpH = ui->widget->height()/3;
    for(int i = 0; i < 9; i++) {
        QLabel* lab = new QLabel(ui->widget);
        lab->setFrameShape(QLabel::Shape::Box);
        lab->resize(tmpW - 1, tmpH - 1);
        lab->move(i%3*tmpW, i/3*tmpH);
        SVLCControl* vlcC = new SVLCControl(lab, this);
        m_allBgs << lab;
        m_allVideos << vlcC;
    }
}

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

void MainWindow::on_pushButton_clicked()
{
    if(ui->pushButton->text() == "播放") {
        foreach (SVLCControl* vlcT, m_allVideos) {
            vlcT->play();
        }
        ui->pushButton->setText("暂停");
    } else if(ui->pushButton->text() == "暂停") {
        foreach (SVLCControl* vlcT, m_allVideos) {
            vlcT->pause();
        }
        ui->pushButton->setText("播放");
    }
}

void MainWindow::on_pB_Stop_clicked()
{
    foreach (SVLCControl* vlcT, m_allVideos) {
        vlcT->stop();
    }
    ui->pushButton->setText("播放");
}

void MainWindow::on_pB_Open_clicked()
{
    foreach (SVLCControl* vlcT, m_allVideos) {
        vlcT->freeVlc();
    }
    m_fileDialog->show();
    if(m_fileDialog->exec() == QDialog::Accepted) {
        QString path = m_fileDialog->selectedFiles()[0];
        ui->lB_Path->setText(path);
        foreach (SVLCControl* vlcT, m_allVideos) {
            vlcT->load(path);
        }
    }
}



 

  • 5
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
实现 QTVLC 视频播放器的上一曲下一曲功能,可以按照以下步骤进行: 1. 在 QT 中创建一个新的项目,选择 Qt Widgets Application。 2. 在项目中添加 VLC 的头文件和库文件路径。在 .pro 文件中添加以下代码: ``` INCLUDEPATH += /path/to/vlc/include LIBS += -L/path/to/vlc/lib -lvlc ``` 3. 在 Qt Designer 中创建一个主窗口,添加一个 QMediaPlayer 控件和两个 QPushButton 控件。一个用于上一曲,一个用于下一曲。 4. 在主窗口的构造函数中创建一个 QMediaPlayer 对象,并且将其设置到 QVideoWidget 控件中: ``` QMediaPlayer *player = new QMediaPlayer(this); QVideoWidget *videoWidget = new QVideoWidget(this); player->setVideoOutput(videoWidget); ``` 5. 在 QPushButton 的 clicked 信号中,调用 QMediaPlayer 的相应接口进行上一曲和下一曲操作: ``` connect(prevButton, &QPushButton::clicked, [=]() { playlist->previous(); }); connect(nextButton, &QPushButton::clicked, [=]() { playlist->next(); }); ``` 6. 创建一个 QMediaPlaylist 对象,用于管理视频文件列表,并将列表设置到 QMediaPlayer 中: ``` QMediaPlaylist *playlist = new QMediaPlaylist(this); playlist->addMedia(QUrl::fromLocalFile("/path/to/video1.mp4")); playlist->addMedia(QUrl::fromLocalFile("/path/to/video2.mp4")); playlist->addMedia(QUrl::fromLocalFile("/path/to/video3.mp4")); player->setPlaylist(playlist); ``` 7. 最后,播放视频: ``` player->play(); ``` 这样,一个基于 QtVLC视频播放器就完成了,并且可以实现上一曲和下一曲功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沙振宇

你的鼓励将是我创作的最大动力~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值