qt6-bb10/qtmultimedia/examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml

318 lines
9.0 KiB
QML

// Copyright (C) 2024 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtMultimedia
import QtQuick.Dialogs
//! [0]
Item {
id: playbackController
required property MediaPlayer mediaPlayer
required property MetadataInfo metadataInfo
required property TracksInfo audioTracksInfo
required property TracksInfo videoTracksInfo
required property TracksInfo subtitleTracksInfo
//! [0]
property alias muted: audioControl.muted
property alias volume: audioControl.volume
property bool landscapePlaybackControls: root.width >= 668
property bool busy: fileDialog.visible
|| urlPopup.visible
|| settingsPopup.visible
|| audioControl.busy
|| playbackSeekControl.busy
implicitHeight: landscapePlaybackControls ? 168 : 208
Behavior on opacity { NumberAnimation { duration: 300 } }
FileDialog {
id: fileDialog
title: "Please choose a file"
onAccepted: {
playbackController.mediaPlayer.stop()
playbackController.mediaPlayer.source = fileDialog.selectedFile
playbackController.mediaPlayer.play()
}
}
UrlPopup {
id: urlPopup
anchors.centerIn: Overlay.overlay
mediaPlayer: playbackController.mediaPlayer
}
SettingsPopup {
id: settingsPopup
anchors.centerIn: Overlay.overlay
metadataInfo: playbackController.metadataInfo
mediaPlayer: playbackController.mediaPlayer
audioTracksInfo: playbackController.audioTracksInfo
videoTracksInfo: playbackController.videoTracksInfo
subtitleTracksInfo: playbackController.subtitleTracksInfo
}
component CustomButton: RoundButton {
implicitWidth: 40
implicitHeight: 40
radius: 4
icon.width: 24
icon.height: 24
flat: true
}
component CustomRoundButton: RoundButton {
property int diameter: 40
Layout.preferredWidth: diameter
Layout.preferredHeight: diameter
radius: diameter / 2
icon.width: 24
icon.height: 24
}
//! [1]
CustomButton {
id: fileDialogButton
icon.source: "../images/open_new.svg"
flat: false
onClicked: fileDialog.open()
}
CustomButton {
id: openUrlButton
icon.source: "../images/link.svg"
flat: false
onClicked: urlPopup.open()
}
//! [1]
CustomButton {
id: loopButton
icon.source: "../images/loop.svg"
icon.color: playbackController.mediaPlayer.loops === MediaPlayer.Once ? palette.buttonText : palette.accent
onClicked: playbackController.mediaPlayer.loops = playbackController.mediaPlayer.loops === MediaPlayer.Once
? MediaPlayer.Infinite
: MediaPlayer.Once
}
CustomButton {
id: settingsButton
icon.source: "../images/more.svg"
onClicked: settingsPopup.open()
}
CustomButton {
id: fullScreenButton
icon.source: root.fullScreen ? "../images/zoom_minimize.svg"
: "../images/zoom_maximize.svg"
onClicked: {
root.fullScreen ? root.showNormal() : root.showFullScreen()
root.fullScreen = !root.fullScreen
}
}
RowLayout {
id: controlButtons
spacing: 16
CustomRoundButton {
id: backward10Button
icon.source: "../images/backward10.svg"
onClicked: {
const pos = Math.max(0, playbackController.mediaPlayer.position - 10000)
playbackController.mediaPlayer.setPosition(pos)
}
}
//! [2]
CustomRoundButton {
id: playButton
visible: playbackController.mediaPlayer.playbackState !== MediaPlayer.PlayingState
icon.source: "../images/play_symbol.svg"
onClicked: playbackController.mediaPlayer.play()
}
CustomRoundButton {
id: pauseButton
visible: playbackController.mediaPlayer.playbackState === MediaPlayer.PlayingState
icon.source: "../images/pause_symbol.svg"
onClicked: playbackController.mediaPlayer.pause()
}
//! [2]
//! [3]
CustomRoundButton {
id: forward10Button
icon.source: "../images/forward10.svg"
onClicked: {
const pos = Math.min(playbackController.mediaPlayer.duration,
playbackController.mediaPlayer.position + 10000)
playbackController.mediaPlayer.setPosition(pos)
}
}
//! [3]
} // RowLayout controlButtons
AudioControl {
id: audioControl
showSlider: root.width >= 960
}
PlaybackSeekControl {
id: playbackSeekControl
Layout.fillWidth: true
mediaPlayer: playbackController.mediaPlayer
}
Frame {
id: landscapeLayout
anchors.fill: parent
padding: 32
topPadding: 28
visible: landscapePlaybackControls
background: Rectangle {
color: "#F6F6F6"
}
ColumnLayout {
anchors.fill: parent
spacing: 16
Item {
Layout.fillWidth: true
implicitHeight: 40
LayoutItemProxy {
id: fdbProxy
target: fileDialogButton
anchors.left: parent.left
}
LayoutItemProxy {
target: openUrlButton
anchors.left: fdbProxy.right
anchors.leftMargin: 12
}
LayoutItemProxy {
target: controlButtons
anchors.horizontalCenter: parent.horizontalCenter
}
LayoutItemProxy {
target: loopButton
anchors.right: acProxy.left
anchors.rightMargin: 12
}
LayoutItemProxy {
id: acProxy
target: audioControl
anchors.right: sbProxy.left
anchors.rightMargin: 30
anchors.verticalCenter: parent.verticalCenter
}
LayoutItemProxy {
id: sbProxy
target: settingsButton
anchors.right: fbProxy.left
anchors.rightMargin: 12
}
LayoutItemProxy {
id: fbProxy
target: fullScreenButton
anchors.right: parent.right
}
} // Item
LayoutItemProxy {
target: playbackSeekControl
Layout.topMargin: 16
Layout.bottomMargin: 16
}
}
} // Frame frame
Frame {
id: portraitLayout
anchors.fill: parent
padding: 32
topPadding: 28
visible: !landscapePlaybackControls
background: Rectangle {
color: "#F6F6F6"
}
ColumnLayout {
anchors.fill: parent
spacing: 16
Item {
Layout.fillWidth: true
implicitHeight: 40
LayoutItemProxy {
target: loopButton
anchors.right: cbProxy.left
anchors.rightMargin: 16
}
LayoutItemProxy {
id: cbProxy
target: controlButtons
anchors.horizontalCenter: parent.horizontalCenter
}
LayoutItemProxy {
target: audioControl
anchors.left: cbProxy.right
anchors.leftMargin: 16
}
}
Item {
Layout.fillWidth: true
implicitHeight: 40
LayoutItemProxy {
id: fdbProxy_
target: fileDialogButton
anchors.left: parent.left
}
LayoutItemProxy {
target: openUrlButton
anchors.left: fdbProxy_.right
anchors.leftMargin: 12
}
LayoutItemProxy {
target: settingsButton
anchors.right: fbProxy_.left
anchors.rightMargin: 12
}
LayoutItemProxy {
id: fbProxy_
target: fullScreenButton
anchors.right: parent.right
}
}
LayoutItemProxy {
target: playbackSeekControl
Layout.topMargin: 8
Layout.bottomMargin: 8
}
}
}
}