日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

获取本地 qt_用QT实现视频/音乐播放组件

發(fā)布時(shí)間:2023/12/10 c/c++ 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 获取本地 qt_用QT实现视频/音乐播放组件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

我已經(jīng)有四五天沒有發(fā)布文章了,趁著這個(gè)周末有空,就又開始構(gòu)思我們自己的QT組件庫中的新組件,思考還有哪些有用、有趣、值得研究學(xué)習(xí)并構(gòu)建實(shí)現(xiàn)的組件,于是又有了兩個(gè)新的目標(biāo),即多媒體播放組件和地圖組件。之所以準(zhǔn)備實(shí)現(xiàn)這兩個(gè)小組件,是因?yàn)楝F(xiàn)在流行的很多軟件應(yīng)用中幾乎都能用得到音頻視頻播放和地圖導(dǎo)航或定位功能。所以我們在自己的軟件開發(fā)中如果也遇到類似的需求,能有一個(gè)使用方便、快捷靈活的多媒體或地圖組件,肯定能夠節(jié)省我們很多的工作量和精力,QT雖然有相關(guān)的類但是沒有相關(guān)的組件,如是我就開始了自己的實(shí)現(xiàn)。

功能展示

今天先跟大家分享一下我自己實(shí)現(xiàn)的多媒體播放組件,使用該組件可以很方便的用來播放音樂和視頻。而且所有功能完全是基于QT自帶的QMediaPlayer類和QVideoWidget類進(jìn)行實(shí)現(xiàn),沒有使用任何第三方庫,所以上手也比較容易。目前已實(shí)現(xiàn)的基本功能有:

  • 音樂/視頻播放、暫停功能
  • 時(shí)長和進(jìn)度顯示
  • 音量調(diào)節(jié)和靜音功能
  • 播放進(jìn)度調(diào)整,支持時(shí)間軸點(diǎn)選、拖拉和鍵盤控制
  • 全屏

因?yàn)殇浿频膅if沒有聲音,所以我只展示視頻播放功能,具體實(shí)現(xiàn)效果如下方動圖所示:

播放、暫停功能,點(diǎn)擊按鈕或視頻窗口都能實(shí)現(xiàn)該功能:

進(jìn)度調(diào)節(jié)和音量調(diào)節(jié):

靜音:

全屏:

實(shí)現(xiàn)方法

1、怎么使用QMediaPlayer類播放音樂和視頻?

播放音樂只需要設(shè)置好源即可,源既可以是本地路徑也可以是網(wǎng)址,如果播放使用本地文件的話,需要使用

QUrl::fromLocalFile函數(shù),方法如下:

m_pPlayer = new QMediaPlayer;m_pPlayer->setMedia(QMediaContent(QUrl::fromLocalFile(strPath)));m_pPlayer->play();

播放視頻的話還需要設(shè)置視頻輸出位置,所以QMediaPlayer通常需要連接一個(gè)QVideoWidget來進(jìn)行視頻的播放,方法如下:

m_pPlayer = new QMediaPlayer;m_pVideoWidget = new QVideoWidget;m_pPlayer->setMedia(QMediaContent(QUrl::fromLocalFile(strPath)));m_pPlayer->setVideoOutput(m_pVideoWidget);m_pVideoWidget->show();

2、怎么顯示視頻總時(shí)長和當(dāng)前播放進(jìn)度?

總時(shí)長可以通過m_pPlayer->duration()獲取,當(dāng)前播放進(jìn)度可以通過m_pPlayer->position()獲取,這兩個(gè)函數(shù)返回的都是毫秒數(shù),我們只需要將該毫秒數(shù)轉(zhuǎn)換為時(shí)間并顯示到標(biāo)簽上即可,我為了這兩個(gè)值能夠與時(shí)間軸對應(yīng)起來,所以我都是先轉(zhuǎn)換成秒,然后再對秒進(jìn)行處理:

//將秒數(shù)轉(zhuǎn)換為HH:mm::ss格式QString MediaPlayer::changeSecondsToStr(int nMesc){ m_nHour = nSeconds / 3600; nSeconds %= 3600; m_nMinute = nSeconds / 60; nSeconds %= 60; m_nSecond = nSeconds; return QString("%1:%2:%3").arg(m_nHour, 2, 10, QLatin1Char('0')).arg(m_nMinute, 2, 10, QLatin1Char('0')).arg(m_nSecond, 2, 10, QLatin1Char('0'));}

為了能夠?qū)崟r(shí)更新當(dāng)前的播放進(jìn)度,我設(shè)置了一個(gè)定時(shí)器,每50ms檢查一次當(dāng)前秒數(shù)是否變化并對界面進(jìn)行刷新:

//定時(shí)器超時(shí)處理void MediaPlayer::onTimerOut(){ if (m_pSlider->sliderPosition() != m_nLastPosition) { //之所以會出現(xiàn)這種情況,是因?yàn)橛|發(fā)了鍵盤事件,比如用戶按下了方向鍵、PgUp、PgDn、Home、End m_nLastPosition = m_pSlider->sliderPosition(); m_pSlider->setValue(m_nLastPosition); m_pPlayer->setPosition(m_nLastPosition * 1000); setPlayTime(m_nLastPosition); return; } int nCurPosition = m_pPlayer->position() / 1000; if (m_nLastPosition != nCurPosition) { m_nLastPosition = nCurPosition; //檢查是否播放完畢 if (nCurPosition >= m_pPlayer->duration() / 1000) play(); m_pSlider->setValue(nCurPosition); setPlayTime(nCurPosition); }}

3、如何使用QSlider對視頻進(jìn)行進(jìn)行展示和控制?

展示功能是很好實(shí)現(xiàn)的,只需要設(shè)置好QSlider的范圍并在定時(shí)器中setValue即可,QSlider本身也支持拖動控制,但是當(dāng)我自定義了QSlider上滑塊的樣式后,發(fā)現(xiàn)拖動滑塊不是很靈敏且經(jīng)常無法選中滑塊,且QSlider本身并不支持點(diǎn)擊改變當(dāng)前值,因此我對QSlider添加了事件過濾器,并自己處理了它的鼠標(biāo)點(diǎn)擊事件和鼠標(biāo)移動事件。

m_pSlider = new QSlider(Qt::Horizontal, this); m_pSlider->setObjectName("m_pSlider"); m_pSlider->setCursor(Qt::PointingHandCursor); m_pSlider->setSingleStep(1); m_pSlider->setPageStep(10); m_pSlider->installEventFilter(this); m_pSlider->setEnabled(false);bool MediaPlayer::eventFilter(QObject *watched, QEvent *event){ //進(jìn)度滑動條 if(watched == m_pSlider) { if (event->type() == QEvent::MouseButtonPress) { QMouseEvent *mouseEvent = static_cast(event); if (mouseEvent->button() == Qt::LeftButton)//判斷左鍵 { QSlider* pSlider = (QSlider*)watched; int dur = pSlider->maximum() - pSlider->minimum(); int pos = pSlider->minimum() + dur * ((double)mouseEvent->x() / pSlider->width()); if (pos != pSlider->sliderPosition()) { //if (pSlider == m_pSlider) { if (m_pSlider->isEnabled()) { m_pSlider->setValue(pos); onSliderPressed(); onSliderMoved(pos); onSliderReleased(); return true; } } } } } else if (event->type() == QEvent::MouseMove) { QMouseEvent *mouseEvent = static_cast(event); //if (mouseEvent->button() == Qt::LeftButton)//判斷左鍵 { QSlider* pSlider = (QSlider*)watched; int dur = pSlider->maximum() - pSlider->minimum(); int pos = pSlider->minimum() + dur * ((double)mouseEvent->x() / pSlider->width()); //防止超出范圍 if (pos > pSlider->maximum()) pos = pSlider->maximum(); if (pos < pSlider->minimum()) pos = pSlider->minimum(); if (pos != pSlider->sliderPosition()) { //if (pSlider == m_pSlider) { if (m_pSlider->isEnabled()) { m_pSlider->setValue(pos); onSliderPressed(); onSliderMoved(pos); onSliderReleased(); return true; } } } } } } return QObject::eventFilter(watched, event);}

如果在視頻播放過程中改變進(jìn)度的話,定時(shí)器還在運(yùn)行,可能也會同時(shí)修改視頻的進(jìn)度,所以在用m_pSlider改變播放進(jìn)度時(shí),需要先停止視頻播放和定時(shí)器,這個(gè)操作我們通過管理QSlider的鼠標(biāo)按下響應(yīng)、鼠標(biāo)移動響應(yīng)和鼠標(biāo)釋放響應(yīng)進(jìn)行處理。當(dāng)鼠標(biāo)按下時(shí)停止視頻播放和定時(shí)器,鼠標(biāo)移動時(shí)修改視頻進(jìn)度,鼠標(biāo)釋放時(shí)恢復(fù)視頻播放和重啟定時(shí)器。

connect(m_pSlider, SIGNAL(sliderPressed()), this, SLOT(onSliderPressed()));connect(m_pSlider, SIGNAL(sliderMoved(int)), this, SLOT(onSliderMoved(int)));connect(m_pSlider, SIGNAL(sliderReleased()), this, SLOT(onSliderReleased()));//滑動條鼠標(biāo)點(diǎn)擊響應(yīng)void MediaPlayer::onSliderPressed(){ m_bIsLastPlay = m_bIsPlay;}//滑動條滑動響應(yīng)void MediaPlayer::onSliderMoved(int nPosition){ Q_UNUSED(nPosition); //在拖動過程中暫停播放 if (m_bIsPlay) play(); if (m_nLastPosition != nPosition) { m_nLastPosition = nPosition; m_pSlider->setValue(m_nLastPosition); m_pPlayer->setPosition(m_nLastPosition * 1000); setPlayTime(m_nLastPosition); }}//滑動條鼠標(biāo)釋放響應(yīng)void MediaPlayer::onSliderReleased(){ if (m_bIsLastPlay) play();}

4、如何實(shí)現(xiàn)音量控制和音量控制窗口的自動顯示和隱藏?

音量修改也是使用滑動條進(jìn)行控制,實(shí)現(xiàn)方法和改變播放進(jìn)度類似,就不再細(xì)說。這里只說一下怎么控制音量窗口的自動出現(xiàn)和隱藏。當(dāng)鼠標(biāo)移動到音量按鈕上方時(shí),音量窗口自動顯示,當(dāng)鼠標(biāo)移動到音量窗口上方時(shí),音量窗口一直保持顯示狀態(tài),當(dāng)鼠標(biāo)從音量窗口移出1s以后,音量窗口自動隱藏。了解這個(gè)過程以后,其實(shí)不難發(fā)現(xiàn),還是需要對鼠標(biāo)事件進(jìn)行過濾和自定義處理。至于怎么使窗口延遲1s后隱藏,使用QTimer::singleShot進(jìn)行單次觸發(fā)最為方便合適。

bool MediaPlayer::eventFilter(QObject *watched, QEvent *event){ if (watched == m_pVolumeButton) //音量鍵 { if (event->type() == QEvent::Enter) { changeVolume(m_pPlayer->volume()); m_pVolumeSlider->setValue(m_pPlayer->volume()); //計(jì)算位置,使其位于音量控制按鈕的上方 m_pVolumeWidget->setGeometry(QRect(m_pVolumeButton->pos().rx()+0.5*m_pVolumeButton->width()-m_pVolumeWidget->width()/2, m_pControlWidget->y()-110 , m_pVolumeWidget->width(), 100)); m_pVolumeWidget->show(); m_bVolume = true; } if (event->type() == QEvent::Leave) { m_bVolume = false; QTimer::singleShot(1000, this, SLOT(hideSlider())); } } else if (watched == m_pVolumeWidget) //音量窗口 { if (event->type() == QEvent::Enter) m_bVolume = true; else if(event->type() == QEvent::Leave) { m_bVolume = false; QTimer::singleShot(1000, this, SLOT(hideSlider())); } } return QObject::eventFilter(watched, event);}

5、如何實(shí)現(xiàn)實(shí)現(xiàn)靜音和全屏顯示?

當(dāng)我們點(diǎn)擊音量按鈕的時(shí)候進(jìn)行打開靜音或關(guān)閉靜音操作,當(dāng)然靜音時(shí)手動的設(shè)置音量為0也無可厚非,但是QMediaPlayer中也提高了相關(guān)接口,使用方法如下:

//打開或關(guān)閉靜音void MediaPlayer::openOrCloseMute(){ if (m_pPlayer->isMuted()) m_pVolumeButton->setIcon(QIcon(":/Images/MediaPlayer_Icon/sound.png")); else m_pVolumeButton->setIcon(QIcon(":/Images/MediaPlayer_Icon/mute.png")); m_pPlayer->setMuted(!m_pPlayer->isMuted());

全屏方法也是調(diào)用接口,直接上代碼:

//打開或關(guān)閉全屏顯示void MediaPlayer::openOrCloseFullScreen(){ if (this->isFullScreen()) { m_pFullScreenButton->setIcon(QIcon(":/Images/MediaPlayer_Icon/showMax.png")); m_pFullScreenButton->setToolTip("進(jìn)入全屏"); this->showNormal(); } else { m_pFullScreenButton->setIcon(QIcon(":/Images/MediaPlayer_Icon/showNormal.png")); m_pFullScreenButton->setToolTip("退出全屏"); this->showFullScreen(); }}

總結(jié)

其實(shí)整個(gè)實(shí)現(xiàn)過程也很簡單,主要是QSlider的使用和對鼠標(biāo)移動事件的處理,該組件的下方控制窗口也可以實(shí)現(xiàn)自動隱藏,實(shí)現(xiàn)方法和音量窗口類似。還可以集成之前我們自己做的彈幕組件,從而支持發(fā)送彈幕功能,由于時(shí)間關(guān)系,我就沒有實(shí)現(xiàn)。該組件的使用方法也非常方便:

MediaPlayer *pMediaPlayer = new MediaPlayer;pMediaPlayer->show();//pMediaPlayer->playMusic("D:/CloudMusic/1.mp3"); //播放音樂pMediaPlayer->playVideo("C:/Users/金/Desktop/2.mp4"); //播放視頻

源碼大概有500行左右,這里就不再貼出來了,否則篇幅太長,主要功能實(shí)現(xiàn),上面也都放了源碼,如果有需要也可以評論留言,后期也會統(tǒng)一上傳github。

總結(jié)

以上是生活随笔為你收集整理的获取本地 qt_用QT实现视频/音乐播放组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。