summaryrefslogtreecommitdiffstats
path: root/examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml
diff options
context:
space:
mode:
Diffstat (limited to 'examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml')
-rw-r--r--examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml318
1 files changed, 318 insertions, 0 deletions
diff --git a/examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml b/examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml
new file mode 100644
index 000000000..056cf50d0
--- /dev/null
+++ b/examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml
@@ -0,0 +1,318 @@
+// 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
+ || !playbackController.mediaPlayer.playing
+
+ 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.currentFile
+ 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
+ }
+ }
+ }
+}