完全依赖QML实现播放器
- 2020 年 3 月 5 日
- 筆記
前言
一直听闻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真的挺好用的!