目录
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);
}
}
}