完全依赖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真的挺好用的!

posted @ 2020-03-03 15:57  gongluck  阅读(2705)  评论(0编辑  收藏  举报