前言
一直聽聞QML無比強大好用,工作中需要扣一個同時播放視頻的Demo,所以就趁這個機會研究了一下。
效果圖和源碼
主要設計
主頁面QML
import QtQuick 2.12
import QtQuick.Window 2.12
Window {
visible: true
width: 640
height: 480
Counter{
id : counter
}
Player {
id:player1
visible: true
anchors.left:parent.left
anchors.top:parent.top
width: parent.width
height: parent.height
}
Player {
id:player2
visible: true
x:parent.x
y:parent.height-height
width: parent.width/3
height: parent.height/3
counter:counter
canchangez : true
}
Player {
id:player3
visible: true
x:player2.width
y:parent.height-height
width: parent.width/3
height: parent.height/3
counter:counter
canchangez : true
}
Player {
id:player4
visible: true
x:player2.width+player3.width
y:parent.height-height
width: parent.width/3
height: parent.height/3
counter:counter
canchangez : true
}
}
程序窗口共有4個播放器,最下層有1個,剩下3個作爲子控件放在其上方。
播放器QML
import QtQuick 2.12
import QtMultimedia 5.12
import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.2
//播放器
Rectangle {
color: "black"
property Counter counter
property bool canchangez : false
function setTop() {
z = counter.getNext()
//console.log("change z to ", z)
}
function setBot(){
//z = 0
}
//背景圖
Image{
id: bkimg
source: "qrc:/bk.png"
anchors.fill: parent
}
TextInput {
id: uri
width: parent.width - btn.width
height: 25
font.pixelSize: 15
topPadding: 5
//text: "file:../RandB/media/gx.wmv"
text: qsTr("rtsp://wowzaec2demo.streamlock.net/vod/mp4:BigBuckBunny_115k.mov")
color: "blue"
clip: true
//onEditingFinished: {
// mediaplayer.play()
//}
}
Button {
id: btn
width: 100
anchors.right: parent.right
height: uri.height
text: qsTr("file")
highlighted: true
onClicked: {
fileDialog.open()
}
}
FileDialog {
id: fileDialog
title: qsTr("Please choose a media file")
nameFilters: [ "Media Files (*.mp4 *.flv *.avi *.wmv *.mkv)", "*.*"]
onAccepted: {
uri.text = String(fileUrl)
}
}
//需要安裝LAVFilter
//低版本QT(5.12)也可能會出現debug版本運行出錯
MediaPlayer {
id: mediaplayer
loops: MediaPlayer.Infinite
}
VideoOutput {
id: videooutput
anchors.left: parent.left
anchors.bottom: parent.bottom
width: parent.width
height: parent.height - uri.height
source: mediaplayer
autoOrientation: true
}
MouseArea{
anchors.fill: videooutput
onClicked: {
bkimg.visible = false
mediaplayer.source = uri.text
mediaplayer.play()
}
onDoubleClicked: {
mediaplayer.stop()
bkimg.visible = true
}
property real lastX: 0
property real lastY: 0
onPressed: {
lastX = mouseX
lastY = mouseY
if(canchangez){
setTop()
}
}
onReleased: {
if(canchangez){
setBot()
}
}
onPositionChanged: {
if (pressed) {
parent.x += mouseX - lastX
parent.y += mouseY - lastY
}
}
}
}
使用QML提供的MediaPlayer和VideoOutput組合,播放視頻。MouseArea中添加onPressed、onReleased和onPositionChanged等事件處理器處理鼠標的操作進行播放、暫停和移動。
計數器QML
import QtQuick 2.0
//計數器
Item {
property int number : 0
function getNext(){
return ++number
}
}
主要用於處理播放器控件Z軸座標的累增(一句C艹代碼都不想寫,所以才這麼設計一個計數器控件)。
後記
Windows平臺下運行,需要安裝LAVFilter,不然會出現某些媒體格式不能播放。Android平臺能編譯apk,但是播放會報出很多openGL相關的錯誤,最終未能解決。之前還以爲真的能,一份代碼,windows和android都能完美運行。
Player控件可以進一步優化,在其他項目中使用。
QML真的挺好用的!