[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: