一、環境介紹
作業系統: win10 64位
QT版本: QT5.12.6
編譯器: MinGW 32
libvlc版本: 3.0.12
完整工程下載地址(下載即可編譯運行): https://download.csdn.net/download/xiaolong1126626497/20479530
二、播放器運行效果與功能介紹





播放器的功能介紹:
1. 影像旋轉播放(90°、0°、180°、360°)
2. 視頻畫面截圖保存到本地
3. 倍速切換、速度切換不會改變聲音音色
4. 音量調整,靜音切換
5. 快進、快退支持
6. 點擊按鈕加載檔案、滑鼠拖拽檔案進行播放
7. 重播按鈕支持
8. 暫停與繼續切換
9. 單幀切換、前一幀、后一幀
10. 流媒體播放,輸入流媒體鏈接
11. 進度條顯示,支持滑鼠點擊任意跳轉到點擊位置
12. 播放時間實時更新顯示
其他功能可自己增加.....
三、libVLC介紹
3.1 下載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.2 libvlc介紹

來至官網的介紹:
libVLC是核心引擎,也是VLC 媒體播放器所基于的多媒體框架的介面,
libVLC被模塊化為數百個插件,可以在運行時加載,這種架構為開發人員(VLC 開發人員和使用該庫的開發人員)提供了極大的靈活性,它允許開發人員使用VLC功能創建范圍廣泛的多媒體應用程式,
- 播放每種媒體檔案格式、每種編解碼器和每種流媒體協議,
- 在各種平臺上運行,從桌面(Windows、Linux、Mac)到移動設備(Android、iOS)和電視,
- 每個平臺上的硬體和高效解碼,高達 8K,
- 遠程檔案系統(SMB、FTP、SFTP、NFS...)和服務器(UPnP、DLNA)的網路瀏覽,
- 使用選單導航播放音頻 CD、DVD 和藍光,
- 支持 HDR,包括 SDR 流的色調映射,
- 具有 SPDIF 和 HDMI 的音頻直通,包括音頻高清編解碼器,如 DD+、TrueHD 或 DTS-HD,
- 支持視頻和音頻過濾器,
- 支持 360 度視頻和 3D 音頻播放,包括 Ambisonics,
- 能夠投射和流式傳輸到遠程渲染器,如 Chromecast 和 UPnP 渲染器,
libVLC是一個 C 庫,可以嵌入到您自己的應用程式中,它適用于大多數流行的作業系統平臺,包括移動設備和桌面設備,它在LGPL2.1 許可下,
libVLC版本控制本質上與 VLC 應用程式版本控制相關聯,libVLC 當前穩定的主要版本是 version 3,預覽/開發版本是 version 4,
libVLC 的各種編程語言系結可用于在您選擇的生態系統中無縫使用該庫,
VideoLAN 系結
- 用于 C++ 的libvlcpp
- 用于 Apple 平臺的VLCKit,使用 Objective-C/Swift,
- 用于 Android 平臺的libvlcjni,使用 Java/Kotlin,
- LibVLCSharp適用于大多數作業系統平臺,使用 .NET/Mono,
社區系結
- vlcj用于使用 Java 的桌面平臺,
- python-vlc用于使用 Python 的桌面平臺,
- vlc-rs使用 Rust 編程語言,
- libvlc-go使用 Go 編程語言,

四、播放器程式設計
#include "widget.h"
#include "ui_widget.h"
Widget* Widget::pThis = nullptr;
Widget::Widget(QString filename,QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
pThis=this;
//設定視窗的標題名稱
this->setWindowTitle("VLC內核視頻播放器");
//獲取VLC版本號
qDebug()<<"VLC內核版本:"<<libvlc_get_version();
qDebug()<<"編譯LIBVLC的編譯器版本:"<<libvlc_get_compiler();
//加載樣式表
SetStyle(":/resource/VideoPlayer.qss");
//讀取組態檔
ReadConfig();
//播放器初始化
VLC_InitConfig();
//UI界面相關初始化
UI_InitConfig();
//如果建構式傳入的視頻檔案就直接加載
if(!filename.isEmpty())
{
load_video_file(0,filename);
}
//拖放檔案需要使用
setAcceptDrops(true);
}
Widget::~Widget()
{
delete ui;
libvlc_release(vlc_base); //減少libvlc實體的參考計數,并銷毀它
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 加載樣式表
*/
void Widget::SetStyle(const QString &qssFile)
{
QFile file(qssFile);
if (file.open(QFile::ReadOnly))
{
QByteArray qss=file.readAll();
qApp->setStyleSheet(qss);
file.close();
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: UI界面初始化
*/
void Widget::UI_InitConfig()
{
//音量滑塊范圍設定
ui->horizontalSlider_AudioValue->setMaximum(100);
ui->horizontalSlider_AudioValue->setMinimum(0);
//安裝事件過濾器
ui->horizontalSlider_AudioValue->installEventFilter(this);
//播放速度設定
ui->MediaSpeedBtn->setCheckable(true);
m_TimeSpeedGrp = new QActionGroup(this);
QStringList strSpeedItems;
strSpeedItems << tr("0.5X") << tr("1.0X") << tr("1.5X") << tr("2.0X") << tr("4.0X");
float speeds[] = {0.5,1.0,1.5,2.0,4.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 == 1)
{
pSpeedItem->setChecked(true);
}
}
connect(m_TimeSpeedGrp, SIGNAL(triggered(QAction *)), this, SLOT(slot_onSetTimeSpeed(QAction *)));
//影像的旋轉方向
m_RotateGrp = new QActionGroup(this);
QStringList strDegrees;
strDegrees << tr("0~") << tr("90~") << tr("180~") << tr("270~");
int Degrees[] = {0, 90, 180, 270 };
for (int i = 0; i < strDegrees.size(); i++)
{
QAction *pItem = m_RotateMenu.addAction(strDegrees.at(i));
pItem->setData(QVariant::fromValue(Degrees[i]));
pItem->setCheckable(true);
m_RotateGrp->addAction(pItem);
if (i == 0)
{
pItem->setChecked(true);
}
}
connect(m_RotateGrp, SIGNAL(triggered(QAction *)), this, SLOT(slot_onMediaRotate(QAction *)));
//功能設定
// ui->toolButton_set->setCheckable(true);
m_ConfigurationFunctionGrp = new QActionGroup(this);
QAction *pToKeyFrame = m_ConfigurationFunctionMenu.addAction(tr("保留1"));
QAction *pAppInfo = m_ConfigurationFunctionMenu.addAction(tr("保留2"));
pToKeyFrame->setData(MENU_TO_KeyFrame); //保存到剪切板
pAppInfo->setData(MENU_APP_INFO); //保存到檔案
m_ConfigurationFunctionGrp->addAction(pToKeyFrame); //添加到分組
m_ConfigurationFunctionGrp->addAction(pAppInfo); //添加到分組
connect(m_ConfigurationFunctionGrp, SIGNAL(triggered(QAction *)), this, SLOT(slot_onConfigurationFunction(QAction *)));
//截圖保存
// ui->MediaSnapshotBtn->setCheckable(true);
m_SnapshotGrp = new QActionGroup(this);
QAction *pClipboard = m_SnapshotMenu.addAction(tr("截圖保存到剪切板"));
QAction *pFileDirectory = m_SnapshotMenu.addAction(tr("截圖保存到檔案"));
pClipboard->setData(MENU_COPY_CLIPBOARD); //保存到剪切板
pFileDirectory->setData(MENU_SAVE_FILE_SYSTEM); //保存到檔案
m_SnapshotGrp->addAction(pClipboard); //添加到分組
m_SnapshotGrp->addAction(pFileDirectory); //添加到分組
connect(m_SnapshotGrp, SIGNAL(triggered(QAction *)), this, SLOT(slot_onMediaSnapshot(QAction *)));
//安裝事件監聽器 事件篩選器是接收發送到此物件的所有事件的物件
ui->horizontalSlider_PlayPosition->installEventFilter(this);
ui->widget_videoDisplay->installEventFilter(this);
//狀態資訊初始化
MediaInfo.state=MEDIA_NOLOAD;
//工具提示資訊
ui->toolButton_load->setToolTip(tr("加載視頻,也可以直接將視頻檔案拖拽到視窗"));
ui->MediaPrevBtn->setToolTip(tr("快退5秒"));
ui->MediaPlayBtn->setToolTip(tr("快進5秒"));
ui->MediaPauseBtn->setToolTip(tr("暫停/繼續"));
ui->MediaSpeedBtn->setToolTip(tr("倍速選擇"));
ui->MediaResetBtn->setToolTip(tr("從頭播放"));
ui->MediaSnapshotBtn->setToolTip(tr("截圖"));
ui->MediaRotateBtn->setToolTip(tr("畫面旋轉"));
ui->ReverseFrameBtn->setToolTip(tr("上一幀"));
ui->ForwardFrameBtn->setToolTip(tr("下一幀"));
ui->VolumeBtn->setToolTip(tr("靜音切換"));
ui->toolButton_link->setToolTip(tr("流媒體鏈接"));
//播放進度潭訓塊初始化
connect(ui->horizontalSlider_PlayPosition, SIGNAL(sliderMoved(int)), SLOT(seek(int)));
connect(ui->horizontalSlider_PlayPosition, SIGNAL(sliderPressed()), SLOT(seek()));
this->setMouseTracking(true);
}
/*
工程: ECRS_VideoPlayer
日期: 2021-03-15
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: MediaPlayer初始化
*/
void Widget::VLC_InitConfig(void)
{
const char *tempArg = "";
// tempArg = "--demux=h264";
const char *vlc_args[9] = {"-I", "dummy", "--no-osd", "--no-stats", "--ignore-config", "--no-video-on-top", "--no-video-title-show", "--no-snapshot-preview", tempArg};
//VLC相關的初始化
//vlc_base=libvlc_new(0, nullptr); //創建并初始化libvlc實體
vlc_base=libvlc_new(sizeof(vlc_args) / sizeof(vlc_args[0]), vlc_args);
if(!vlc_base)
{
qDebug()<<"libvlc_new 執行錯誤.";
}
//影像緩沖區申請空間
ctx.pixels = new uchar[MAX_WIDTH * MAX_HEIGHT * 4];
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 更新播放進度
*/
void Widget::updateSliderPosition(qint64 value)
{
//設定進度條的時間
ui->horizontalSlider_PlayPosition->setValue(int(value));
//設定右上角的時間
ui->label_current_Time->setText(QTime(0, 0, 0,0).addMSecs(int(value)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
}
/*
工程: ECRS_VideoPlayer
日期: 2021-03-15
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 媒體總時間
*/
void Widget::media_durationChanged(qint64 value)
{
//最大值最小值
ui->horizontalSlider_PlayPosition->setMinimum(int(0));
ui->horizontalSlider_PlayPosition->setMaximum(int(value));
ui->label_Total_Time->setText(QTime(0, 0, 0,0).addMSecs(int(value)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
}
/*
工程: QtVLC_Player
日期: 2021-03-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: VLC的事件回呼
*/
void Widget::vlcEvents(const libvlc_event_t *ev, void *param)
{
libvlc_time_t play_ms_pos=0;
switch (ev->type){
case libvlc_MediaPlayerTimeChanged:
//獲取當前視頻的播放位置
play_ms_pos=libvlc_media_player_get_time(pThis->vlc_mediaPlayer);
//設定右上角的時間
pThis->ui->label_current_Time->setText(QTime(0, 0, 0,0).addMSecs(int(play_ms_pos)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
//設定進度條
pThis->ui->horizontalSlider_PlayPosition->setValue(int(play_ms_pos));
break;
case libvlc_MediaPlayerEndReached:
qDebug() << "VLC播放完畢.";
break;
case libvlc_MediaPlayerStopped:
qDebug() << "VLC停止播放";
//獲取當前視頻的播放位置
play_ms_pos=libvlc_media_player_get_time(pThis->vlc_mediaPlayer);
//設定右上角的時間
pThis->ui->label_current_Time->setText(QTime(0, 0, 0,0).addMSecs(int(play_ms_pos)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
//設定進度條
pThis->ui->horizontalSlider_PlayPosition->setValue(int( pThis->ui->horizontalSlider_PlayPosition->maximum()));
break;
case libvlc_MediaPlayerPlaying:
qDebug() << "VLC開始播放";
break;
case libvlc_MediaPlayerPaused:
qDebug() << "VLC暫停播放";
break;
case libvlc_MediaParsedChanged:
qDebug() << "獲取到元資料";
int state=ev->u.media_parsed_changed.new_status;
if(libvlc_media_parsed_status_done==state)
{
qDebug()<<"媒體元資料:"<<libvlc_media_get_meta(pThis->vlc_media,libvlc_meta_Date);
}
break;
}
}
void Widget::display(void *opaque, void *picture)
{
(void)opaque;
}
void *Widget::vlc_lock(void *opaque, void **planes)
{
struct Context *ctx = (struct Context *)opaque;
ctx->mutex.lock();
// 告訴 VLC 將解碼的資料放到緩沖區中
*planes = ctx->pixels;
return nullptr;
}
//獲取 argb 幀
void Widget::vlc_unlock(void *opaque, void *picture, void *const *planes)
{
struct Context *ctx = (struct Context *)opaque;
unsigned char *data = static_cast<unsigned char *>(*planes);
quint32 w=pThis->video_width;
quint32 h=pThis->video_height;
if(w>0 && h>0 && data!=nullptr)
{
QImage image(data, int(w),int(h), QImage::Format_RGB32);
if(!image.isNull())
{
pThis->ui->widget_videoDisplay->slotGetOneFrame(image.copy());
}
}
ctx->mutex.unlock();
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 加載視頻檔案 flag=0 重新加載檔案 flag=1 重新開始播放
QString file_path 這引數可以傳入檔案名稱,因為視窗支持拖放檔案進來
回傳值: true 成功 false 失敗
*/
bool Widget::load_video_file(bool flag,QString file_path)
{
if(flag==false)
{
QString filename=file_path;
if(filename.isEmpty())
{
//獲取路徑,如果沒有默認路徑,就使用當前C盤根目錄
if(open_dir_path.isEmpty())
{
open_dir_path="C:/";
}
filename=QFileDialog::getOpenFileName(this,"選擇播放的視頻",open_dir_path,tr("*.mkv *.flv *.mp4 *.wmv *.*"));
if(filename.isEmpty())return false;
open_dir_path=QFileInfo(filename).path();
qDebug()<<"路徑:"<<open_dir_path;
}
media_filename=filename;
}
//判斷檔案是否存在
if(QFileInfo::exists(media_filename)==false)
{
if(media_filename.contains("rtsp:", Qt::CaseInsensitive)==false&&
media_filename.contains("rtmp:", Qt::CaseInsensitive)==false)
{
return false;
}
else
{
qDebug()<<"播放的流媒體:"<<media_filename;
}
}
else
{
/* 將 / 轉為windows下的右斜桿 */
std::replace(media_filename.begin(), media_filename.end(), QChar('/'), QChar('\\'));
qDebug()<<"播放的本地媒體:"<<media_filename;
}
MediaInfo.state=MEDIA_LOAD;
MediaInfo.mediaName=media_filename;
//設定當前播放的視頻名稱
QFileInfo info(media_filename);
ui->label_FileName->setText(QString("%1").arg(info.fileName()));
//寬高清0
video_width=0;
video_height=0;
/*為特定檔案路徑創建媒體*/
if(vlc_media)libvlc_media_release(vlc_media);
vlc_media=libvlc_media_new_path(vlc_base,media_filename.toUtf8());
if(vlc_media==nullptr)
{
qDebug()<<"libvlc_media_new_path 執行錯誤.";
return false;
}
/*根據給定的媒體物件創建一個播放器物件*/
if(vlc_mediaPlayer)libvlc_media_player_release(vlc_mediaPlayer);
vlc_mediaPlayer=libvlc_media_player_new_from_media(vlc_media);
//設定回呼,用于提取幀或者在界面上顯示,
libvlc_video_set_callbacks(vlc_mediaPlayer, vlc_lock, vlc_unlock, display, &ctx);
/*獲取媒體播放器事件管理器*/
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); //暫停
libvlc_event_attach(em, libvlc_MediaParsedChanged, vlcEvents, this); //獲取到元資料
/*播放媒體檔案*/
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_Total_Time->setText(QTime(0, 0, 0,0).addMSecs(int(length)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
//每次加載新檔案設定播放進度條為0
ui->horizontalSlider_PlayPosition->setValue(0);
//設定進度條的范圍
ui->horizontalSlider_PlayPosition->setMaximum(int(length));
ui->horizontalSlider_PlayPosition->setMinimum(0);
//獲取當前媒體播放的位置
libvlc_time_t current_movie_time=libvlc_media_player_get_time(vlc_mediaPlayer);
qDebug()<<"獲取當前媒體播放的位置:"<<current_movie_time;
libvlc_video_get_size(vlc_mediaPlayer,0,&video_width,&video_height);
qDebug()<<"視頻尺寸:"<<"width:"<<video_width<<"height:"<<video_height;
memset(ctx.pixels, 0, MAX_WIDTH * MAX_HEIGHT * 4);
//設定影像顏色格式
libvlc_video_set_format(vlc_mediaPlayer, "RV32", video_width, video_height, video_width * 4);
libvlc_media_add_option(vlc_media, ":rtsp=tcp"); //連接方式
libvlc_media_add_option(vlc_media, ":network-caching=200"); //快取
//設定按鈕狀態為播放狀態
ui->MediaPauseBtn->setChecked(false);
//隱藏標簽控制元件
ui->label->setVisible(false);
//獲取媒體的元資料資訊--異步方式
libvlc_media_parse_with_options(vlc_media,libvlc_media_parse_local,1000);
qDebug()<<"媒體元資料獲取---媒體標題:"<<libvlc_media_get_meta(vlc_media,libvlc_meta_Title);
//獲取媒體描述符的基本流描述
libvlc_media_track_t **tracks;
//正常的視頻獲取的流的數量是2. 一個視頻流 一個音頻流
if(libvlc_media_tracks_get(vlc_media,&tracks))
{
qDebug()<<"視頻寬:"<<tracks[0]->video->i_width;
qDebug()<<"視頻高:"<<tracks[0]->video->i_height;
//手機拍的視頻是翻轉(寬高反過來的),電腦上播放需要翻轉回去
qDebug()<<"旋轉度數:"<<tracks[0]->video->i_orientation;
//逆時針旋轉90°
if(tracks[0]->video->i_orientation==libvlc_video_orient_right_top)
{
// video_width=tracks[0]->video->i_height;
// video_height=tracks[0]->video->i_width;
//ui->widget_videoDisplay->Set_Rotate(90);
//libvlc_media_add_option(vlc_media, ":transform-type=90");
}
// libvlc_video_set_scale(vlc_mediaPlayer,1);
}
/*
libvlc_media_add_option(vlc_media, ":rtsp=tcp"); //連接方式
libvlc_media_add_option(vlc_media, ":codec=ffmpeg");
libvlc_media_add_option(vlc_media, ":avcodec-threads=1");
libvlc_media_add_option(vlc_media, ":avcodec-hw=any"); //硬體解碼
libvlc_media_add_option(vlc_media, ":network-caching=200"); //快取
libvlc_media_add_option(vlc_media, ":prefetch-buffer-size=1024"); //預裝取緩沖大小512K
libvlc_media_add_option(vlc_media, ":prefetch-read-size=65535"); //預裝取讀取大小64K
*/
return true;
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 加載視頻檔案
*/
void Widget::on_toolButton_load_clicked()
{
qDebug()<<"加載視頻檔案狀態:"<<load_video_file(0,"");
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 暫停播放
*/
void Widget::on_MediaPauseBtn_clicked()
{
//暫停與繼續
if(vlc_mediaPlayer)libvlc_media_player_pause(vlc_mediaPlayer);
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 重新開始播放
*/
void Widget::on_MediaResetBtn_clicked()
{
//加重新開始播放
load_video_file(true,"");
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 快退播放
*/
void Widget::on_MediaPrevBtn_clicked()
{
//得到播放進度的當前位置
int value=ui->horizontalSlider_PlayPosition->value();
seek(value-1000*5);
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 快進播放
*/
void Widget::on_MediaPlayBtn_clicked()
{
//得到播放進度的當前位置
int value=ui->horizontalSlider_PlayPosition->value();
seek(value+1000*5);
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 向左一幀
*/
void Widget::on_ReverseFrameBtn_clicked()
{
//得到播放進度的當前位置
int value=ui->horizontalSlider_PlayPosition->value();
value+=100;
if(value<=ui->horizontalSlider_PlayPosition->maximum())
{
ui->horizontalSlider_PlayPosition->setValue(value);
ui->label_current_Time->setText(QTime(0, 0, 0,0).addMSecs(int(value)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
//跳轉播放器
float f_value=(float)value/(float)ui->horizontalSlider_PlayPosition->maximum();
qDebug()<<"f_value:"<<f_value;
libvlc_media_player_set_position(vlc_mediaPlayer,f_value);
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 向右一幀
*/
void Widget::on_ForwardFrameBtn_clicked()
{
//得到播放進度的當前位置
int value=ui->horizontalSlider_PlayPosition->value();
value-=100;
if(value>=0)
{
ui->horizontalSlider_PlayPosition->setValue(value);
ui->label_current_Time->setText(QTime(0, 0, 0,0).addMSecs(int(value)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
//跳轉播放器
float f_value=(float)value/(float)ui->horizontalSlider_PlayPosition->maximum();
qDebug()<<"f_value:"<<f_value;
libvlc_media_player_set_position(vlc_mediaPlayer,f_value);
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 音量設定
*/
void Widget::on_VolumeBtn_clicked()
{
bool checked=ui->VolumeBtn->isChecked();
if(checked)
{
//靜音
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,0);
}
else
{
//設定正常音量
int volume_val=ui->horizontalSlider_AudioValue->value();
//音量設定
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,volume_val);
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 音量設定
*/
void Widget::on_horizontalSlider_AudioValue_valueChanged(int value)
{
//音量設定
if(vlc_mediaPlayer)libvlc_audio_set_volume(vlc_mediaPlayer,value);
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: 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()));
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了速度設定按鈕
*/
void Widget::on_MediaSpeedBtn_clicked()
{
QPoint ptWgt = ui->MediaSpeedBtn->mapToGlobal(QPoint(0, 0));
ptWgt -= QPoint(10, 94);
QAction *pSelect = m_SpeedMenu.exec(ptWgt);
if (pSelect == nullptr)
return;
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了旋轉選擇選單
*/
void Widget::slot_onMediaRotate(QAction *action)
{
action->setChecked(true);
ui->MediaRotateBtn->setToolTip(action->text());
ui->widget_videoDisplay->Set_Rotate(action->data().toInt());
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-23
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了畫面旋轉選單
*/
void Widget::on_MediaRotateBtn_clicked()
{
QPoint ptWgt = ui->MediaRotateBtn->mapToGlobal(QPoint(0, 0));
ptWgt -= QPoint(10, 94);
QAction *pSelect = m_RotateMenu.exec(ptWgt);
if (pSelect == nullptr)
return;
}
/*
工程: ECRS_VideoPlayer
日期: 2021-03-08
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了功能設定選單
*/
void Widget::slot_onConfigurationFunction(QAction *action)
{
if (action == nullptr)
return;
//得到按下的序號
MENU_ITEM item = MENU_ITEM(action->data().toInt());
//轉視頻為關鍵幀
if (item == MENU_TO_KeyFrame)
{
}
//APP功能介紹
else if(item==MENU_APP_INFO)
{
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了截圖選單
*/
void Widget::slot_onMediaSnapshot(QAction *action)
{
if (action == nullptr)
return;
//得到按下的序號
MENU_ITEM item = MENU_ITEM(action->data().toInt());
QImage Pic=ui->widget_videoDisplay->GetImage();
if (Pic.isNull() || Pic.height() <= 0)return;
//保存到剪切板
if (item == MENU_COPY_CLIPBOARD)
{
QApplication::clipboard()->setImage(Pic);
}
//保存到檔案
else if (item == MENU_SAVE_FILE_SYSTEM)
{
QString strFile = QDateTime::currentDateTime().toString("yyyyMMddHHmmss") + ".png";
QString strFileName = QFileDialog::getSaveFileName(nullptr, "保存圖片", strFile, "PNG(*.png);;BMP(*.bmp);;JPEG(*.jpg *.jpeg)");
if (!strFileName.isEmpty())
{
strFileName = QDir::toNativeSeparators(strFileName);
QFileInfo fInfo(strFileName);
Pic.save(strFileName, fInfo.completeSuffix().toStdString().c_str(), 80);
}
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了截圖按鈕
*/
void Widget::on_MediaSnapshotBtn_clicked()
{
QPoint ptWgt = ui->MediaSnapshotBtn->mapToGlobal(QPoint(0, 0));
ptWgt -= QPoint(10, 48);
QAction *pSelect = m_SnapshotMenu.exec(ptWgt);
if (pSelect == nullptr)
return;
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 攔截事件
*/
bool Widget::eventFilter(QObject *obj, QEvent *event)
{
//判斷是否在視頻視窗范圍內按下的滑鼠
if(obj==ui->widget_videoDisplay)
{
}
//點擊的是音量滑塊
else if(obj==ui->horizontalSlider_AudioValue)
{
if (event->type()==QEvent::MouseButtonPress) //判斷型別
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
if (mouseEvent->button() == Qt::LeftButton) //判斷左鍵
{
int value = QStyle::sliderValueFromPosition(ui->horizontalSlider_AudioValue->minimum(), ui->horizontalSlider_AudioValue->maximum(), mouseEvent->pos().x(), ui->horizontalSlider_AudioValue->width());
ui->horizontalSlider_AudioValue->setValue(value);
}
}
}
return QObject::eventFilter(obj,event);
}
/*
工程: ASS_SubtitleVideoPlayer
日期: 2021-06-15
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 按鍵事件
*/
void Widget::keyPressEvent(QKeyEvent *event)
{
switch(event->key())
{
case Qt::Key_Space:
//視頻加載成功才能進行下面的操作
if(MediaInfo.state==MEDIA_LOAD)
{
QKeyEvent *keyEvent = static_cast<QKeyEvent *>(event);
if (keyEvent->key() == Qt::Key_Space)
{
if(vlc_mediaPlayer)
{
//暫停與繼續切換
libvlc_media_player_pause(vlc_mediaPlayer);
//4表示暫停 3表示繼續 5表示停止
int state=libvlc_media_player_get_state(vlc_mediaPlayer);
if(state==4 || state==5)
{
//設定按鈕狀態
ui->MediaPauseBtn->setChecked(false);
}
else if(state==3)
{
//設定按鈕狀態
ui->MediaPauseBtn->setChecked(true);
}
}
}
}
break;
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-03-08
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 點擊了設定按鈕
*/
void Widget::on_toolButton_set_clicked()
{
// QPoint ptWgt = ui->toolButton_set->mapToGlobal(QPoint(0, 0));
// ptWgt -= QPoint(10, 48);
// QAction *pSelect = m_ConfigurationFunctionMenu.exec(ptWgt);
// if (pSelect == nullptr)
// return;
}
void Widget::seek(int value)
{
if(vlc_mediaPlayer)
{
float pos=value*1.0/ui->horizontalSlider_PlayPosition->maximum();
libvlc_media_player_set_position(vlc_mediaPlayer,pos);
qDebug()<<"跳轉的位置:"<<pos;
ui->horizontalSlider_PlayPosition->setValue(value);
ui->label_current_Time->setText(QTime(0, 0, 0,0).addMSecs(int(value)).toString(QString::fromLatin1("HH:mm:ss:zzz")));
//跳轉播放器
float f_value=(float)value/(float)ui->horizontalSlider_PlayPosition->maximum();
qDebug()<<"f_value:"<<f_value;
libvlc_media_player_set_position(vlc_mediaPlayer,f_value);
}
}
void Widget::seek()
{
seek(ui->horizontalSlider_PlayPosition->value());
}
void Widget::dragEnterEvent(QDragEnterEvent *e)
{
if (e->mimeData()->hasUrls())
{
e->acceptProposedAction();
}
}
void Widget::dropEvent(QDropEvent *e)
{
foreach (const QUrl &url, e->mimeData()->urls())
{
QString fileName = url.toLocalFile();
qDebug() << "拖入的檔案名稱:" << fileName;
//加載視頻檔案
load_video_file(false,fileName);
}
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 保存配置
*/
void Widget::SaveConfig()
{
//從UI界面獲取用戶的個性化配置引數
/*保存資料到檔案,方便下次加載*/
QString text;
text=QCoreApplication::applicationDirPath()+"/"+ConfigFile;
QFile filesrc(text);
filesrc.open(QIODevice::WriteOnly);
QDataStream out(&filesrc);
out << open_dir_path; //序列化
filesrc.flush();
filesrc.close();
}
/*
工程: ECRS_VideoPlayer
日期: 2021-02-24
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 讀取配置
*/
void Widget::ReadConfig()
{
//讀取組態檔
QString text;
text=QCoreApplication::applicationDirPath()+"/"+ConfigFile;
//判斷檔案是否存在
if(QFile::exists(text))
{
QFile filenew(text);
filenew.open(QIODevice::ReadOnly);
QDataStream in(&filenew); // 從檔案讀取序列化資料
in >>open_dir_path; //提取寫入的資料
filenew.close();
}
}
/*
工程: ASS_SubtitleVideoPlayer
日期: 2021-06-16
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 視窗關閉事件
*/
void Widget::closeEvent(QCloseEvent *event) //視窗關閉事件
{
int ret = QMessageBox::question(this, tr("重要提示"),
tr("是否退出播放器?"),
QMessageBox::Yes | QMessageBox::No);
if(ret==QMessageBox::Yes)
{
SaveConfig();
event->accept(); //接受事件
}
else
{
event->ignore(); //清除事件
}
}
/*
工程: VLC_Core_VideoPlayer
日期: 2021-07-26
作者: DS小龍哥
環境: win10 QT5.12.6 MinGW32
功能: 打開鏈接
*/
void Widget::on_toolButton_link_clicked()
{
bool ok;
QString text = QInputDialog::getText(this, tr("流媒體播放"),tr("請輸入流媒體地址:"), QLineEdit::Normal,
tr("rtmp://58.200.131.2:1935/livetv/cctv14"),&ok);
if (ok && !text.isEmpty())
{
load_video_file(0,text);
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/290469.html
標籤:其他
