[QML开发笔记]-QML+FFmpge制作视频播放器

本文记录使用QML和FFmpeg在QT5.13环境下开发视频播放器的过程,包括所需环境、展示效果及关键代码组件如VideoFFmpeg、VideoThread等。
摘要由CSDN通过智能技术生成
[QML开发笔记]-QML+FFmpge制作视频播放器

QML结合FFmpge制作视频播放器

环境:QT5.13 ffmpeg-4.2.2-win64

效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
代码:

main.qml

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12
import QtQuick.Dialogs 1.2
import KDMQuick 1.0
/**
* @FileName      main.qml
* @brief         File Description
* @author        Kongdemin
* @date          2020-05-20
*/
Window {
   
    id: window
    visible: true
    width: 1280
    height: 720
    maximumHeight: 720
    minimumHeight: 720
    maximumWidth: 1280
    minimumWidth: 1280
    flags: Qt.Dialog
    title: qsTr("QML+FFmpeg视频播放器")

    property string filePath: ''
    property string fileName: ''

    Connections{
   
        target: toolBtn
        onValueChanged: {
   
            if(toolBtn.sliderPressed){
   
                videoItem.setSeek(toolBtn.value)
            }
        }
    }

    FileDialog {
   
        id: fileDialog
        visible: false
        title: "Please choose a file"
        modality: Qt.ApplicationModal
        folder: shortcuts.movies
        nameFilters: ["Video files(*.mp4 *.avi)", "All files (*)"]
        selectedNameFilter: "All files (*)"
        onAccepted: {
   
            console.log("You chose: " + fileDialog.fileUrl)
            filePath = fileDialog.fileUrl
            window.fileName = fileDialog.fileUrl
            videoItem.filePath = filePath
            fileName.opacity = 1
            toolBtn.totalTime = videoItem.totalTime()
            toolBtn.opacity = 1
            videoItem.play()
            timer.start()
            fileNameTimer.start()
        }
        onRejected: {
   
            console.log("Canceled")
        }
    }

    MouseArea {
   
        anchors.fill: parent
        hoverEnabled: true
        onEntered: {
   
            toolBtn.opacity = 0
        }
    }

    VideoItem{
   
        id: videoItem
        x: 0
        y: 0
        width: 1280
        height: 720
    }
    Timer {
   
        id: timer
        interval: 40; running: false; repeat: true
        onTriggered: {
   
            if(!toolBtn.sliderPressed){
   
                videoItem.updatePaint()
                toolBtn.currentTime = videoItem.currentTime()
                toolBtn.seek = videoItem.seek()
            }
        }
    }

    Timer {
   
        id: fileNameTimer
        interval: 2000; running: false; repeat: false
        onTriggered: {
   
            fileName.opacity = 0
            toolBtn.opacity = 0
        }
    }
    Text {
   
        id: fileName
        x: 15
        y: 550
        font.family: "Helvetica"
        font.pointSize: 20
        text: window.fileName
    }

    ToolButton {
   
        id: toolBtn
        x: 0
        y: window.height - toolBtn.height
        width: parent.width
        height: 100
        opacity: 0
        onPlayClicked: {
   
            videoItem.play()
            timer.start()
        }
        onPauseClicked: {
   
            timer.stop()
            videoItem.pause()
        }
        onStopClicked: {
   
            timer.stop()
            videoItem.pause()
            videoItem.stop()
            videoItem.updatePaint()
            toolBtn.currentTime = '00:00'
            toolBtn.totalTime = '00:00'
            toolBtn.seek = 0
        }
    }

    MenuButton {
   
        id: menuBtn
        x: 10; y: 10
        opacity: 0.1
        onClicked: {
   
            drawer.open()
        }
    }

    Drawer {
   
        id: drawer
        width: 150
        height: parent.height
        dragMargin: 10
        
        Column{
   
            spacing: 5
            padding: 0

            Image {
   
                id: logo
                width: parent.width
                anchors.horizontalCenter: parent.horizontalCenter
                fillMode: Image.PreserveAspectFit
                source: "./qt-logo.png"
            }

            FlatButton {
   
                id: open
                text: "打开"
                font.pixelSize: 23
                font.family: "Helvetica"
                width: drawer.width
                height: 50
                backgroundDefaultColor: '#5A6268'
                onClicked: {
   
                    fileDialog.open()
                    drawer.close()
                }
            }

            FlatButton {
   
                id: close
                text: "关闭"
                font.pixelSize: 23
                width: drawer.width
                height: 50
                backgroundDefaultColor: '#5A6268'
                onClicked: {
   
                    timer.stop()
                    videoItem.pause()
                    videoItem.stop()
                    Qt.quit()
                }
            }

            FlatButton {
   
                id: about
                text: "关于"
                font.pixelSize: 23
                width: drawer.width
                height: 50
                backgroundDefaultColor: '#5A6268'
                onClicked: {
   
                    messageDialog.open()
                    drawer.close()
                }
            }
        }
        background: Rectangle {
   
             Rectangle {
   
                 x: parent.width - 1
                 width: 1
                 height: parent.height
             }
         }
    }

    MessageDialog {
   
        id: messageDialog
        title: "About"
        text: "QML+FFmpet视频播放器"
        onAccepted: {
   
            console.log("And of course you could only agree.")
        }
        Component.onCompleted: visible = false
    }

    onClosing: {
   
        timer.stop()
        videoItem.pause()
        videoItem.stop()
    }
    Component.onCompleted: {
   }
}

ToolButton.qml

import QtQuick 2.0
import QtQuick.Controls 2.12
/**
* @FileName      ToolButton.qml
* @brief         File Description
* @author        Kongdemin
* @date          2020-05-20
*/
Rectangle {
   
    id: root
    property bool containMouseing: false
    property bool play: false
    property string playImage: "/play.png"
    property string pauseImage: "/pause.png"
    property string currentTime: '00:00'
    property string totalTime: '00:00'
    property bool sliderPressed: false
    property int seek: 0
    property real value: 0
    signal playClicked()
    signal pauseClicked()
    signal stopClicked()
    width: 50
    height: 50
    color: 'gray'

    MouseArea{
   
        anchors.fill: parent
        hoverEnabled: true
        onContainsMouseChanged: {
   
            root.containMouseing = containsMouse
            if (root.containMouseing){
   
                root.opacity = 1
            }
            else
                root.opacity = 0
        }
    }

    Slider {
   
        id: slider
        x: 0
        y: 15
        height:
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值