Qt+Quick實(shí)現(xiàn)播放音樂和視頻的開發(fā)
MediaPlayer 是 QML 提供的核心多媒體類,可以播放音頻、視頻。要使用 MediaPlayer,需要引入 QtMultimedia 模塊,在 QML 文檔的開始加入 “import QtMultimedia 5.0” 語(yǔ)句。QML 中的 MediaPlayer 是 Qt C++ 中的多媒體框架在 QML 環(huán)境中的代言人,假如以 Qt QuickApp 為模板創(chuàng)建項(xiàng)目,你還需要在 pro 文件中加入語(yǔ)句:QT += multimedia。
1、播放音樂
先看最簡(jiǎn)單的播放音樂的例子,simple_music.qml,就十來行代碼:
import QtQuick 2.2 import QtMultimedia 5.0 Rectangle { width: 200; height: 100; MediaPlayer { autoPlay: true; source: "wangjie_game_and_dream.mp3"; } }
關(guān)于 MediaPlayer 的,就 4 行代碼。在 QML 文檔同目錄下放置對(duì)應(yīng)的 MP3 文件,執(zhí)行 “qmlscenesimple_music.qml” 命令,音樂就會(huì)響起來。
在這個(gè)簡(jiǎn)單的示例中,source 屬性指定了要播放的文件,它的類型是 url,它能接受絕對(duì)路徑、相對(duì)路徑、有效的 http 鏈接。autoPlay 屬性設(shè)置為 true,指示 MediaPlayer 對(duì)象創(chuàng)建后立即開始播放。如果你覺得立馬開始播放不太好,也可以在你認(rèn)為合適的時(shí)候調(diào)用 MediaPlayer 的 play() 方法。
如果你想知道音樂的時(shí)長(zhǎng),訪問 duration 屬性,它是整型值,單位是毫秒,實(shí)現(xiàn) onDurationChanged 信號(hào)處理器,可以取到時(shí)長(zhǎng)。
如果你還想知道播放進(jìn)度,可以訪問 position 屬性,它是整型值,單位是毫秒,實(shí)現(xiàn)一 個(gè) onPositionChanged 信號(hào)處理器,就可以實(shí)時(shí)顯示進(jìn)度。
調(diào)用 pause() 方法暫停播放,調(diào)用 stop() 方法停止播放。而播放狀態(tài)變化時(shí),會(huì)發(fā)出 playbackStateChanged() 信號(hào),在 onPlaybackStateChanged 信號(hào)處理器內(nèi),可以讀取枚舉類型的 playbackState 屬性,它取 MediaPlayer.PlayingState、MediaPlayer.PausedState、MediaPlayer. StoppedState 三個(gè)值中的一個(gè)。
seekable 屬性指示媒體是否支持 seek,當(dāng)它為 true 時(shí),你就可以調(diào)用 seek (offset) 方法來定位播放了。參數(shù) offset 是相對(duì)于當(dāng)前位置的偏移量,單位是毫秒。注意,操作可能是異步的,當(dāng)方法返回時(shí) position 屬性不一定會(huì)立即變成新的。
靜音可以通過 imited 屬性讀取、設(shè)置,音量通過 volume 屬性讀取、設(shè)置。
好啦,常用操作就這么多,現(xiàn)在讓我們來打造一個(gè)功能更豐富的簡(jiǎn)易音樂播放器。(另外需要用到 FlatButton,其 qml 文件內(nèi)容,由于篇幅原因未貼出。)simple_music_player.qml 的內(nèi)容如下:
import QtQuick 2.2 import QtMultimedia 5.0 Rectangle { width: 320; height: 240; color: "black"; property var utilDate: new Date(); function msecs2String(msecs){ utilDate.setTime(msecs); return Qt.formatTime(utilDate, "mm:ss"); } MediaPlayer { id: player; source: "wangjie_game_and_dream.mp3"; onPositionChanged: { progress.text = msecs2String(position) + progress.sDuration; } onDurationChanged: { progress.sDuration = " / " + msecs2String(duration); } onPlaybackStateChanged: { switch(playbackState){ case MediaPlayer.PlayingState: state.text = "播放中"; break; case MediaPlayer.PausedState: state.text = "已暫停"; break; case MediaPlayer.StoppedState: state.text = "停止"; break; } } onStatusChanged: { switch(status){ case MediaPlayer.Loaded: console.log(metaData.albumArtist, metaData.albumTitle, metaData.author, metaData.channelCount); break; } } } Row { id: controller; anchors.top: parent.verticalCenter; anchors.horizontalCenter: parent.horizontalCenter; anchors.topMargin: 4; spacing: 4; FlatButton { width: 50; height: 50; iconSource: "ic_rew.png"; onClicked: if(player.seekable)player.seek(player.position - 5000); } FlatButton { width: 50; height: 50; iconSource: "ic_pause.png"; onClicked: player.pause(); } FlatButton { width: 50; height: 50; iconSource: "ic_play.png"; onClicked: player.play(); } FlatButton { width: 50; height: 50; iconSource: "ic_stop.png"; onClicked: player.stop(); } FlatButton { width: 50; height: 50; iconSource: "ic_ff.png"; onClicked: if(player.seekable)player.seek(player.position + 5000); } } Text { id: progress; anchors.left: controller.left; anchors.bottom: controller.top; anchors.bottomMargin: 4; color: "white"; font.pointSize: 12; property string sDuration; } Text { id: state; anchors.left: progress.left; anchors.bottom: progress.top; anchors.bottomMargin: 4; color: "white"; font.pointSize: 12; } Text { id: metaInfo; anchors.left: state.left; anchors.bottom: state.top; anchors.bottomMargin: 4; color: "blue"; font.pointSize: 14; } }
使用 qmlscene 加載 simple_music_player.qml,效果如下圖所示。
這個(gè)版本的播放器依舊很簡(jiǎn)單,只能播放一個(gè)內(nèi)置的文件,也沒有可拖動(dòng)的進(jìn)度條,不過 MediaPlayer 的常用接口都用到了。界面上的那些事兒,播放列表那些事兒,都可以在此基礎(chǔ)上加進(jìn)來,再找些漂亮的圖片,你就可以打造出一個(gè)酷炫的音樂播放器了。
2、播放視頻
播放視頻比音樂稍稍復(fù)雜一些,需要使用 VideoOutput 元素與 MediaPlayer 配合。 VideoOutput 用來渲染視頻,也可以作為相機(jī)的取景器(預(yù)覽窗口),最簡(jiǎn)單的用法是,你只需要將其 source 屬性指向一個(gè) MediaPlayer 對(duì)象即可。 simple_video.qml 演示如何播放一個(gè)本地視頻:
import QtQuick 2.2 import QtMultimedia 5.0 Rectangle { width: 720; height: 480; MediaPlayer { id: player; source: "D:/game/helloMv/3D1.mp4"; onError: { console.log(errorString); } } VideoOutput { anchors.fill: parent; source: player; } MouseArea { anchors.fill: parent; onClicked: { console.log("call play"); player.play(); } } }
如你所見,視頻的示例相比音頻,僅僅多了一個(gè) VideoOutput 對(duì)象,其 source 屬性為 player。當(dāng)用鼠標(biāo)左鍵單擊時(shí),調(diào)用 play() 播放視頻。
如果你在 Windows 平臺(tái)上使用 qmlscene 加載 simple_video.qml,不一定能夠播放,要確保你的系統(tǒng)安裝了必需的 DirectShow Filter 才行。如果不能播放,可以嘗試安裝 LAV Filters(請(qǐng)找度娘要下載地址,親測(cè)安裝即可,無序配置)。LAV Filters 是一組基于 ffmpeg 的 DirectShow 分離器和音視頻解碼器,支持絕大多數(shù)常見的音視頻格式。
下圖是播放效果圖:
視頻播放的控制,如暫停、停止、定位等,與音樂一樣,不多說了。接下來我們看看如何獲取多媒體的元信息。
3、多媒體元信息
何謂多媒體元信息?就是媒體以外、用來描述媒體的那些信息,比如一首歌,專輯、發(fā)行時(shí)間、藝術(shù)家、采樣率等,就是元信息;又如一個(gè)視頻,分辨率、編碼格式、幀率等,就是元信息。
MediaPlayer 對(duì)象有個(gè)分組屬性 metaData,它包含了方方面面的元信息,通過訪問它,你就可以知道多媒體的描述信息。不過呢,這些看上去很美的元信息,不一定可用哦,要看 MediaPlayer 使用的底層的播放服務(wù)是否能夠提供這些。如果你需要這些信息,可以這么獲取: 在 onStatusChanged 信號(hào)處理器中,讀取 status 屬性,當(dāng)它的值為 MediaPlayer.Loaded 時(shí), 訪問你想要的信息。就像下面這樣:
MediaPlayer { id: player; source: "wangjie_game_and_dream.mp3"; onStatusChanged: { switch(status){ case MediaPlayer.Loaded: console.log(metaData.albumArtist, metaData.albumTitle, metaData.author, metaData.channelCount); break; } } }
我用的 MP3 文件,只能取到 channelCount 這個(gè)信息,輸出結(jié)果為 2,說明是雙聲道。 如果你想了解多媒體元信息的更多細(xì)節(jié),請(qǐng)?jiān)?Qt 幫助中查看 MediaPlayer 的文檔。
以上就是Qt+Quick實(shí)現(xiàn)播放音樂和視頻的開發(fā)的詳細(xì)內(nèi)容,更多關(guān)于Qt Quick播放音樂視頻的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
java string對(duì)象上的操作,常見的用法你知道嗎
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí),文章圍繞著Java String類用法展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-08-08C語(yǔ)言實(shí)現(xiàn)繪制LoveBeat愛心曲線的示例代碼
這篇文章主要為大家詳細(xì)介紹了如何溧陽(yáng)C語(yǔ)言實(shí)現(xiàn)繪制LoveBeat愛心曲線,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03c++動(dòng)態(tài)庫(kù)調(diào)用的實(shí)現(xiàn)
本文主要介紹了c++動(dòng)態(tài)庫(kù)調(diào)用的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-07-07詳解C語(yǔ)言中條件判斷語(yǔ)句if和switch的用法
這篇文章主要介紹了詳解C語(yǔ)言中條件判斷語(yǔ)句if和switch的用法,是C語(yǔ)言入門學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下2016-04-04C++實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)簡(jiǎn)單計(jì)算器功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-05-05C++實(shí)現(xiàn)圖書信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C++實(shí)現(xiàn)圖書信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03