完全依赖QML实现播放器

前言

一直听闻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真的挺好用的!