第四章.视频播放软件
视频播放软件
视频播放解决方案
QVideoWidget播放视频
编译添加Qt modules
按钮点击代码
void MainWidget::on_btnOpen_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, u8"请选择视频文件",
"D:/testvideo",
u8"视频文件(*.mp4 *.flv);;所有文件(*.*);;");
//getopenfilename是一个静态成员函数
if (fileName.isEmpty())
return;
QMediaPlayer* pPlayer = new QMediaPlayer(this);
pPlayer->setMedia(QUrl::fromLocalFile(fileName));
pPlayer->setVideoOutput((QVideoWidget*)(ui.video_widget));
pPlayer->play();
}
libvlc使用介绍
vs studio引入外部库
Visual Studio引入外部库 ---- 弄懂静态库lib和动态库dll
vlc sdk
下载vlc,主要用到是vlc3.8
版本中的sdk
添加头文件目录:这一步是为了告诉编译器在哪里可以找到外部库的头文件。当你在代码中包含这些头文件时,编译器会去这些指定的目录查找。
添加lib静态库:这一步是为了告诉链接器在哪里可以找到外部库的lib文件。链接器会使用这些lib文件来链接你的程序,从而使得程序能够使用库中的函数或变量。
添加工程引用的lib文件名:这一步是告诉链接器具体需要链接哪些lib文件。通常,我们只需要指定lib文件的名称,链接器会自动找到并链接它。
- 首先先将vlc解压的文件夹放在和项目所在的文件内,添加头文件目录:右键工程根目录→ 属性 → C/C++ → 常规 → 附加包含目录,添加include目录。
- 添加lib静态库:右键工程根目录 → 属性 → 链接器 → 常规 → 附加库目录,添加lib目录。
- 添加工程引用的lib文件名:工程 → 属性 → 链接器 → 输入 → 附加依赖项:输入lib文件名
实操
// vlc初始化
m_pInstance = libvlc_new(0, nullptr);//创建vlc实例
if (m_pInstance)
{
m_pMediaPlayer = libvlc_media_player_new(m_pInstance);//创建媒体播放器
if (!m_pMediaPlayer)
{
libvlc_release(m_pInstance);
QMessageBox::information(this, u8"提示", u8"libvlc_media_player_new failed");
exit(EXIT_FAILURE);
}
}
else
{
QMessageBox::information(this, u8"提示", u8"libvlc_new failed");
exit(EXIT_FAILURE);
}
如果怕没有释放,可以在主窗口中加个保底
MainWidget::~MainWidget()
{
if (m_pInstance)
{
libvlc_release(m_pInstance);
m_pInstance = nullptr;
}
}
编译出错(1)
编译出错(2)
运行出错
同时还要把libvlc.dll和libvlccore.lib一起放到解决方案的Debug里面
打开按钮代码详解
void MainWidget::on_btnOpen_clicked()
{
QString fileName = QFileDialog::getOpenFileName(this, u8"请选择视频文件",
"D:/testvideo",
u8"视频文件(*.mp4 *.flv);;所有文件(*.*);;");
if (fileName.isEmpty())
return;
fileName = QDir::toNativeSeparators(fileName); // 这一句很重要,决定m_pMedia是否创建成功.这行代码将文件路径转换为本地格式,这对于确保路径格式正确和LibVLC库能够正确处理很重要。如果这一步没有正确执行,可能会导致m_pMedia无法成功创建。
//设置路径
m_pMedia = libvlc_media_new_path(m_pInstance, fileName.toStdString().c_str());//使用LibVLC库创建一个新的媒体对象,该对象表示选择的视频文件。这个对象是播放视频所必需的。
if (m_pMedia)
{
//解析media
libvlc_media_parse(m_pMedia);//解析媒体对象,准备播放。这是播放视频之前的一个必要步骤。
//设置media
libvlc_media_player_set_media(m_pMediaPlayer, m_pMedia);//将之前创建的媒体对象设置到媒体播放器中,这样播放器就知道要播放哪个视频了。
//设置播放的窗口句柄
libvlc_media_player_set_hwnd(m_pMediaPlayer, (void*)(ui.video_widget->winId()));//告诉LibVLC在哪里显示视频。这里,视频将被显示在ui.video_widget这个Qt窗口部件上。
//释放media
libvlc_media_release(m_pMedia);
m_pMedia = nullptr;
//播放视频
libvlc_media_player_play(m_pMediaPlayer);
}
else
{
QMessageBox::information(this, u8"提示", u8"libvlc_media_new_path failed");
exit(EXIT_FAILURE);
}
}
窗口句柄和窗口id
获取视频总时长
获取视频声音
视频参数管理
封装vlc播放功能
vlc封装
#pragma once
#ifdef _WIN32
#include <basetsd.h>
typedef SSIZE_T ssize_t;
#endif
#include "vlc/vlc.h"
#include <QObject>
class CVlcKits:public QObject
{
Q_OBJECT
public:
CVlcKits();
~CVlcKits();
int initVLC();//vlc初始化
libvlc_media_player_t* media_player();//???
void setTimeSliderPos(int value);//这三个与下面三个信号相对应
void setVolumeSliderPos(int value);
void setTimeText(const QString& str);
libvlc_time_t getDurations();//???
int play(QString fileName, void* hwnd);//四个按钮接口
void play();
void pause();
void stop();
signals:
void sig_TimeSliderPos(const int& value);
void sig_VolumeSliderPos(const int& value);
void sig_UpdateTimeText(const QString& str);
private:
libvlc_instance_t* m_pInstance = nullptr;//vlc实例
libvlc_media_player_t* m_pMediaPlayer = nullptr;
libvlc_media_t* m_pMedia = nullptr;
libvlc_event_manager_t* m_pEvent_manager = nullptr;//媒体改动的时间类型,主要用于回调函数
libvlc_time_t m_totalSecs = -1;
};
回调函数
//这两句是在媒体播放器初始化以后链接上的
libvlc_event_attach(m_pEvent_manager, libvlc_MediaPlayerPositionChanged, vlc_callback, this);
libvlc_event_attach(m_pEvent_manager, libvlc_MediaPlayerAudioVolume, vlc_callback, this);
void vlc_callback(const struct libvlc_event_t* p_event, void* p_data)
{
CVlcKits* pThis = static_cast<CVlcKits*>(p_data);
if (pThis)
{
switch (p_event->type)
{
case libvlc_MediaPlayerPositionChanged:
{
float pos = libvlc_media_player_get_position(pThis->media_player());
pThis->setTimeSliderPos(pos * 100);
qint64 curSecs = libvlc_media_player_get_time(pThis->media_player()) / 1000;
#ifdef _DEBUG
cout << "curSecs" << curSecs << endl;
#endif
int curH = curSecs / 3600;
int curMinute = (curSecs - curH * 3600) / 60;
int curSec = curSecs - curH * 3600 - curMinute * 60;
char buf1[256] = { 0 };
sprintf(buf1, "%02d:%02d:%02d", curH, curMinute, curSec);
QString str1(buf1);
qint64 totalSecs = pThis->getDurations();
int _hour = totalSecs / 3600;
int _minute = (totalSecs - _hour * 3600) / 60;
int _sec = totalSecs - _hour * 3600 - _minute * 60;
char buf2[256] = { 0 };
sprintf(buf2, "%02d:%02d:%02d", _hour, _minute, _sec);
QString str2(buf2);
QString text = str1 + "/" + str2;
pThis->setTimeText(text);
}
break;
case libvlc_MediaPlayerAudioVolume:
{
int volume = libvlc_audio_get_volume(pThis->media_player());
pThis->setVolumeSliderPos(volume);
}
break;
}
}
}