一、環境介紹
作業系統: win10 64位
QT版本: QT5.12.6
編譯器: MinGW 32
VLC版本: 3.0.12
功能說明: 下面的播放器例子支援基本播放器的功能。
1. 支援滑鼠點選進度條跳轉到指定幀
2. 支援音量設定、靜音設定
3. 支援加載視訊、暫停、停止、重播
4. 播放速率設定
5. 播放總時間與目前時間顯示
完整項目代碼下載下傳位址:
https://download.csdn.net/download/xiaolong1126626497/16579867![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SY4EjY3IWYjJmZhFjY3MTOhNWM0cDM2ImNhVTN1kDMi9CX5d2bs92Yl1iclB3bsVmdlR2LcNWaw9CXt92Yu4GZjlGbh5yYjV3Lc9CX6MHc0RHaiojIsJye.png)
二、下載下傳VLC的SDK檔案
VLC官網位址:
https://www.videolan.org/ 所有的VLC版本下載下傳位址: http://ftp.heanet.ie/pub/videolan/vlc 3.0.12的SDK下載下傳位址: http://ftp.heanet.ie/pub/videolan/vlc/last/win32/3.1 拷貝SDK檔案到工程目錄下
将下載下傳目錄下的sdk檔案夾拷貝到QT的工程目錄下,友善引用庫和頭檔案。
#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);
this->setWindowTitle("視訊播放器");
//VLC相關的初始化
vlc_base=libvlc_new(0, nullptr); //建立并初始化libvlc執行個體
if(!vlc_base)
{
qDebug()<<"libvlc_new 執行錯誤.";
}
//播放速度設定
ui->MediaSpeedBtn->setCheckable(true);
m_TimeSpeedGrp = new QActionGroup(this);
QStringList strSpeedItems;
strSpeedItems << tr("0.03X") << tr("0.06X") << tr("0.1X") << tr("0.15X") << tr("0.2X") << tr("0.3X") << tr("0.4X") << tr("0.5X") << tr("0.6X") << tr("0.8X") << tr("1.0X") << tr("1.25X") << tr("1.5X") << tr("2.0X") << tr("4.0X") << tr("8.0X");
float speeds[] = { 0.03, 0.06, 0.1, 0.15, 0.2, 0.3, 0.4, 0.5,0.6,0.8,1.0,1.25,1.5,2.0,4.0,8.0};
for (int i = 0; i < strSpeedItems.size(); i++)
{
QAction *pSpeedItem = m_SpeedMenu.addAction(strSpeedItems.at(i));
pSpeedItem->setData(QVariant::fromValue(speeds[i]));
pSpeedItem->setCheckable(true);
m_TimeSpeedGrp->addAction(pSpeedItem);
if (i == 10)
{
pSpeedItem->setChecked(true);
}
}
connect(m_TimeSpeedGrp, SIGNAL(triggered(QAction *)), this, SLOT(slot_onSetTimeSpeed(QAction *)));
//事件監聽
ui->horizontalSlider_pos->installEventFilter(this);
ui->horizontalSlider_volume->installEventFilter(this);
}
Widget::~Widget()
{
delete ui;
libvlc_release(vlc_base); //減少libvlc執行個體的引用計數,并銷毀它
}
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
if(obj==ui->horizontalSlider_pos)
{
if (event->type()==QEvent::MouseButtonPress) //判斷類型
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) //判斷左鍵
{
int value = QStyle::sliderValueFromPosition(ui->horizontalSlider_pos->minimum(), ui->horizontalSlider_pos->maximum(), mouseEvent->pos().x(), ui->horizontalSlider_pos->width());
ui->horizontalSlider_pos->setValue(value);
//跳轉播放器
float f_value=(float)value/(float)ui->horizontalSlider_pos->maximum();
libvlc_media_player_set_position(vlc_mediaPlayer,f_value);
}
}
}
if(obj==ui->horizontalSlider_volume)
{
if (event->type()==QEvent::MouseButtonPress) //判斷類型
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) //判斷左鍵
{
int value = QStyle::sliderValueFromPosition(ui->horizontalSlider_volume->minimum(), ui->horizontalSlider_volume->maximum(), mouseEvent->pos().x(), ui->horizontalSlider_volume->width());
ui->horizontalSlider_volume->setValue(value);
//設定音量
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,value);
}
}
}
return QWidget::eventFilter(obj, event);
}
/*
工程: QtVLC_Player
日期: 2021-03-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 打開本地檔案
*/
void Widget::on_pushButton_open_clicked()
{
/*選擇檔案*/
QString filename=QFileDialog::getOpenFileName(this,"選擇打開的檔案","D:/",tr("*.*"));
/* 将 / 轉為windows下的右斜杆 */
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);
/*解析媒體執行個體*/
// libvlc_media_parse(vlc_media);
/*擷取媒體播放器事件管理器*/
libvlc_event_manager_t *em = libvlc_media_player_event_manager(vlc_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);
/*設定給予媒體播放器媒體輸出的win32/win64視窗句柄*/
libvlc_media_player_set_hwnd(vlc_mediaPlayer, (void *)ui->widget_VideoPlay->winId());
//如果不使用句柄方式,VLC也支援回調方式處理圖像,這種方式可以自己提取圖像資料,自己渲染顯示處理. libvlc_video_set_callbacks
/*播放媒體檔案*/
if(vlc_mediaPlayer)libvlc_media_player_play(vlc_mediaPlayer);
//等待VLC解析檔案.否則下面的時間擷取不成功
QThread::msleep(100);
//擷取媒體檔案總長度 ms
libvlc_time_t length = libvlc_media_player_get_length(vlc_mediaPlayer);
qDebug()<<"媒體檔案總長度:"<<length;
ui->label_t2->setText(QString("%1").arg(length));
ui->horizontalSlider_pos->setMaximum(length);
ui->horizontalSlider_pos->setMinimum(0);
//擷取目前媒體播放的位置
libvlc_time_t current_movie_time=libvlc_media_player_get_time(vlc_mediaPlayer);
qDebug()<<"擷取目前媒體播放的位置:"<<current_movie_time;
unsigned int width=0,height=0;
libvlc_video_get_size(vlc_mediaPlayer,0,&width,&height);
qDebug()<<"視訊尺寸:"<<"width:"<<width<<"height:"<<height;
/*擷取媒體播放器使用的媒體。*/
ui->label_video_name->setText(QString("%1:%2x%3").arg(filename).arg(width).arg(height));
//暫停: 停留在第一幀畫面
if(vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}
/*
工程: QtVLC_Player
日期: 2021-03-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: VLC的事件回調
*/
void Widget::vlcEvents(const libvlc_event_t *ev, void *param)
{
qint64 pos;
switch (ev->type){
case libvlc_MediaPlayerTimeChanged:
qDebug() << "VLC媒體播放器時間已更改";
//擷取目前媒體播放的位置
pos=libvlc_media_player_get_time(pThis->vlc_mediaPlayer);
pThis->ui->label_t1->setText(QString("%1").arg(pos));
pThis->ui->horizontalSlider_pos->setValue(pos);
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;
}
}
/*
工程: QtVLC_Player
日期: 2021-03-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 暫停
*/
void Widget::on_pushButton_pause_clicked()
{
if(vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}
/*
工程: QtVLC_Player
日期: 2021-03-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 停止
*/
void Widget::on_pushButton_stop_clicked()
{
if(vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
}
/*
工程: QtVLC_Player
日期: 2021-03-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 速率
*/
void Widget::slot_onSetTimeSpeed(QAction *action)
{
action->setChecked(true);
ui->MediaSpeedBtn->setToolTip(action->text());
ui->MediaSpeedBtn->setText(action->text());
/*設定播放速率*/
if(vlc_mediaPlayer)libvlc_media_player_set_rate(vlc_mediaPlayer,float(action->data().toFloat()));
}
void Widget::on_MediaSpeedBtn_clicked()
{
QPoint ptWgt = ui->MediaSpeedBtn->mapToGlobal(QPoint(0, 0));
ptWgt -= QPoint(10, 180);
QAction *pSelect = m_SpeedMenu.exec(ptWgt);
if (pSelect == nullptr)
return;
}
void Widget::on_pushButton_get_state_clicked()
{
if(vlc_mediaPlayer)
{
//4表示暫停 3表示繼續 5表示停止
qDebug()<<"播放狀态:"<<libvlc_media_player_get_state(vlc_mediaPlayer);
}
}
void Widget::on_pushButton_reset_clicked()
{
/*需要先停止才可以繼續重頭播放*/
if(vlc_mediaPlayer)libvlc_media_player_stop(vlc_mediaPlayer);
/*播放媒體檔案*/
if(vlc_mediaPlayer)libvlc_media_player_play(vlc_mediaPlayer);
}
//靜音切換
void Widget::on_pushButton_volume_clicked()
{
static bool state=false;
state=!state;
if(state)
{
//靜音
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,0);
}
else
{
int val=ui->horizontalSlider_volume->value();
qDebug()<<"設定音量:"<<val;
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,val);
}
}
//音量滑塊
void Widget::on_horizontalSlider_volume_valueChanged(int value)
{
//設定音量
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,value);
}
3.5 widget.h代碼
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <vlc/vlc.h>
#include <QFileDialog>
#include <QDebug>
#include <QThread>
#include <QActionGroup>
#include <QMenu>
#include <QMouseEvent>
#include <QStyle>
#include <QTimer>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_open_clicked();
void on_pushButton_pause_clicked();
void on_pushButton_stop_clicked();
void slot_onSetTimeSpeed(QAction *action);
void on_MediaSpeedBtn_clicked();
void on_pushButton_get_state_clicked();
void on_pushButton_reset_clicked();
void on_pushButton_volume_clicked();
void on_horizontalSlider_volume_valueChanged(int value);
protected:
bool eventFilter(QObject *obj, QEvent *event);
static void vlcEvents(const libvlc_event_t *ev, void *param);
private:
Ui::Widget *ui;
libvlc_instance_t *vlc_base=nullptr;
libvlc_media_t *vlc_media=nullptr;
libvlc_media_player_t *vlc_mediaPlayer=nullptr;
QActionGroup *m_TimeSpeedGrp;
QMenu m_SpeedMenu;
static Widget *pThis;
};
#endif // WIDGET_H
3.6 編譯之後, 拷貝運作需要的檔案
編譯完成之後,将plugins目錄、libvlc.dll、libvlccore.dll檔案拷貝到exe同級目錄下,再去QtCreate裡運作測試。