diff options
Diffstat (limited to 'examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml')
-rw-r--r-- | examples/multimedia/video/mediaplayer/controls/PlaybackControl.qml | 318 |
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 + } + } + } +} |