完全依赖QML实现播放器

2022-10-09,,

前言

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

《完全依赖QML实现播放器.doc》

下载本文的Word格式文档,以方便收藏与打印。