欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

完全依赖QML实现播放器

程序员文章站 2022-03-25 17:36:39
前言 一直听闻QML无比强大好用,工作中需要扣一个同时播放视频的Demo,所以就趁这个机会研究了一下。 效果图和源码 "源码仓库" 主要设计 主页面QML 程序窗口共有4个播放器,最下层有1个,剩下3个作为子控件放在其上方。 播放器QML 使用QML提供的MediaPlayer和VideoOutpu ......

前言

一直听闻qml无比强大好用,工作中需要扣一个同时播放视频的demo,所以就趁这个机会研究了一下。

效果图和源码

完全依赖QML实现播放器
完全依赖QML实现播放器
源码仓库

主要设计

主页面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真的挺好用的!