QT应用编程:基于VLC开发音视频播放器(句柄方式)
xsobi 2024-12-25 16:15 2 浏览
一、环境介绍
操作系统: win10 64位
QT版本: QT5.12.6
编译器: MinGW 32
VLC版本: 3.0.12
功能说明: 下面的播放器例子支持基本播放器的功能。
1. 支持鼠标点击进度条跳转到指定帧
2. 支持音量设置、静音设置
3. 支持加载视频、暂停、停止、重播
4. 播放速率设置
5. 播放总时间与当前时间显示
完整项目代码下载地址:https://download.csdn.net/download/xiaolong1126626497/16579867
二、下载VLC的SDK文件
VLC官网地址: www.videolan.org/
所有的VLC版本下载地址: http://ftp.heanet.ie/pub/videolan/vlc
3.0.12的SDK下载地址: http://ftp.heanet.ie/pub/videolan/vlc/last/win32/
三、创建QT工程,编写简单的播放器
3.1 拷贝SDK文件到工程目录下
将下载目录下的sdk文件夹拷贝到QT的工程目录下,方便引用库和头文件。
3.2 pro工程文件里加路径
3.3 ui文件
【领QT开发教程学习资料,点击下方链接莬费领取↓↓,先码住不迷路~】
3.4 widget.cpp代码
#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里运行测试。
【领QT开发教程学习资料,点击下方链接莬费领取↓↓,先码住不迷路~】
点击这里:「链接」
作者:DS小龙哥
链接:https://juejin.cn/post/6985337286313377805
相关推荐
- 斗鱼针针成旻云个人资料 针针年龄身高演艺经历介绍
-
[闽南网]针针成旻云曾是七煌旗下签约艺人,经常在斗鱼进行直播身高超过170cm的她更因为有一双大长腿而被称为“斗鱼第一美腿”、“电竞第一腿”。本文这就来对针针的个人资料进行详细介绍,想知道她的年龄身高...
- 轻量级RTSP服务模块和RTSP推流模块适用场景区别
-
好多开发者一直搞不清轻量级RTSP服务SDK和RTSP推流SDK的区别,以下是相关区别:1.轻量级RTSP服务模块:轻量级RTSP服务解决的核心痛点是避免用户或者开发者单独部署RTSP或者RTMP服...
- 《新·奥特曼》11月18日国内视频平台上线
-
《新·奥特曼》海报。新京报讯11月14日,由上海新创华文化发展有限公司授权引进电影《新·奥特曼》宣布正式定档11月18日(周五)00:00上线视频平台,上线版本为日语配音中文字幕版。影片由庵野秀明(...
- 剑指Apple Watch!Android Wear也将支持视频功能
-
想必智能手表发展到现在,大家最期待的还是视频功能,近日AndroidWear就实现了这一功能,以后就能在手表上看视频了,想想就挺激动的,快来看看吧!其实早在WWDC大会上,老对手AppleWatc...
- QT应用编程:基于VLC开发音视频播放器(句柄方式)
-
一、环境介绍操作系统:win1064位QT版本:QT5.12.6编译器:MinGW32VLC版本:...
- OBS 源码分析 obs开发
-
本文将按照数据源的获取、渲染、推送的直播流程来让大家深入了解一下。1、直播源数据获取obs在启动时会优先加载libobs核心库,这个库初始化obs很多内容,包括crash模块、com、性能监...
- Android和iOS端Moments更新:支持视频分享功能
-
Moments是社交网络巨头Facebook推出的一款私人照片分享应用,今天公司宣布对Android端和iOS端应用同时升级,新增对视频分享功能的支持。事实上早在数周之前,Facebook就曾表示Mo...
- 您很快就可以在Android Galaxy设备之间传输视频通话
-
在阅读此文之前,辛苦点击右上角的“关注”,既方便您进行讨论与分享,又能给您带来不一样的参与感,感谢您的支持!导语:在科技领域,每时每刻都有新的发展,令人兴奋的创新不断涌现。早在八月份,Android系...
- 一篇文章带你FFmpeg到流媒体服务器开发
-
安装ffmpeg:下载FFmpeg和libx264的包ffmpeg-2.4.1.tar.bz2last_x264.tar.bz2libx264需要yasm,所以先安装yasmapt-getinst...
- YouTube 为 Android 平台提供 1440P 视频
-
安锋网8月10日消息,Android从起初的480P的屏幕分辨率发展到2014年的1440P花了将近六年的时间,一般认为1080P的屏幕分辨率已经是人眼可以识别的极限,但是...
- FFmpeg 调用 Android MediaCodec 进行硬解码(附源码)
-
FFmpeg在3.1版本之后支持调用平台硬件进行解码,也就是说可以通过FFmpeg的C代码去调用Android上的MediaCodec了。在官网上有对应说明,地址如下:trac....
- Android FFmpeg + OpenGL ES YUV Player
-
1、FFmpeg解出YUV帧数据1.1方法介绍打开封装格式上下文...
- 基于WebRTC的Android移动端无线视频传输
-
摘要:视频传输技术在现代社会广泛应用,人们对其的要求也越来越高,其发展的趋势是方便、快捷、随时随地。传统的视频传输过于依赖线路,线路的走向限制了传输的很多可能,所以无线传输才是发展的方向。本文提出...
- 使用python爬取抖音app视频 python爬取抖音视频数据
-
记录一下如何用python爬取app数据,本文以爬取抖音视频app为例。编程工具:pycharm...
- Android IOS WebRTC 音视频开发总结(七七)-- WebRTC的架构和协议栈
-
本文主要介绍WebRTC的架构和协议栈(我们翻译和整理的,译者:litie),最早发表在【编风网】为了便于理解,我们来看一个最基本的三角形WebRTC架构(见下图)。在这个架构中,移动电话用“浏览器M...
- 一周热门
- 最近发表
- 标签列表
-
- grid 设置 (58)
- 移位运算 (48)
- not specified (45)
- patch补丁 (31)
- strcat (25)
- 导航栏 (58)
- context xml (46)
- scroll (43)
- element style (30)
- dedecms模版 (53)
- vs打不开 (29)
- nmap (30)
- c 视频教程下载 (33)
- paddleocr (28)
- listview排序 (33)
- firebug 使用 (31)
- transactionmanager (30)
- characterencodingfilter (33)
- getmonth (34)
- commandtimeout (30)
- hibernate教程 (31)
- label换行 (33)
- curlpost (31)
- android studio 3 0 (34)
- android开发视频 (30)