summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKamil Hajdukiewicz <kaj@spyro-soft.com>2023-04-13 10:39:52 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2023-06-08 01:25:38 +0000
commit0abce5f4af3994853ff2d689cee3401457f0da01 (patch)
tree3c83735768ab7388cc2d84b15e7e20b03b5346a0
parente90ebab5c57eb68035013b101d8c56e13ce559ac (diff)
Refresh the 'Multimedia Player' example
Design of MultimediaPlayer example was refreshed. New icons, colors, application structure were provided. Some new functionalities were introduced to the sample: playlist, shuffle, loop, dark mode. Tested on Windows, Android Emulator, macOs, iOS emulator. Change-Id: I38a8e203021edc97b70a4ab8f0d8d83c6d5ae45b Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io> (cherry picked from commit d7554ab7004552f50ed72794c29976ed4ea2137a) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
-rw-r--r--examples/demos/CMakeLists.txt3
-rw-r--r--examples/demos/mediaplayer/CMakeLists.txt54
-rw-r--r--examples/demos/mediaplayer/Config/CMakeLists.txt13
-rw-r--r--examples/demos/mediaplayer/Config/Config.qml22
-rw-r--r--examples/demos/mediaplayer/Config/qmldir4
-rw-r--r--examples/demos/mediaplayer/ErrorPopup.qml41
-rw-r--r--examples/demos/mediaplayer/Main.qml382
-rw-r--r--examples/demos/mediaplayer/MediaControls/AudioControl.qml38
-rw-r--r--examples/demos/mediaplayer/MediaControls/CMakeLists.txt62
-rw-r--r--examples/demos/mediaplayer/MediaControls/CustomButton.qml26
-rw-r--r--examples/demos/mediaplayer/MediaControls/CustomRadioButton.qml40
-rw-r--r--examples/demos/mediaplayer/MediaControls/CustomSlider.qml44
-rw-r--r--examples/demos/mediaplayer/MediaControls/PlaybackControl.qml191
-rw-r--r--examples/demos/mediaplayer/MediaControls/PlaybackRateControl.qml40
-rw-r--r--examples/demos/mediaplayer/MediaControls/PlaybackSeekControl.qml106
-rw-r--r--examples/demos/mediaplayer/MediaControls/qmldir9
-rw-r--r--examples/demos/mediaplayer/MetadataInfo.qml76
-rw-r--r--examples/demos/mediaplayer/PlayerMenuBar.qml59
-rw-r--r--examples/demos/mediaplayer/PlaylistInfo.qml230
-rw-r--r--examples/demos/mediaplayer/SettingsInfo.qml84
-rw-r--r--examples/demos/mediaplayer/ThemeInfo.qml38
-rw-r--r--examples/demos/mediaplayer/TouchMenu.qml94
-rw-r--r--examples/demos/mediaplayer/TracksInfo.qml55
-rw-r--r--examples/demos/mediaplayer/TracksOptions.qml81
-rw-r--r--examples/demos/mediaplayer/UrlPopup.qml138
-rw-r--r--examples/demos/mediaplayer/doc/images/mediaplayer.pngbin0 -> 566168 bytes
-rw-r--r--examples/demos/mediaplayer/doc/src/mediaplayer.qdoc25
-rw-r--r--examples/demos/mediaplayer/icons/Add_file.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Add_file_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Cancel_Button.svg4
-rw-r--r--examples/demos/mediaplayer/icons/Default_CoverArt.svg29
-rw-r--r--examples/demos/mediaplayer/icons/Error.svg3
-rw-r--r--examples/demos/mediaplayer/icons/FullScreen_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/FullScreen_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Load_Button.svg18
-rw-r--r--examples/demos/mediaplayer/icons/Loop_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Loop_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Loop_Playlist.svg6
-rw-r--r--examples/demos/mediaplayer/icons/Menu_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Menu_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Movie_Active.svg4
-rw-r--r--examples/demos/mediaplayer/icons/Movie_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Movie_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Music_Active.svg4
-rw-r--r--examples/demos/mediaplayer/icons/Music_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Music_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Mute_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Mute_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Next_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Next_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Play_Icon.svg4
-rw-r--r--examples/demos/mediaplayer/icons/Playlist_Active.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Playlist_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Playlist_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Previous_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Previous_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Rate_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Rate_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Settings_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Settings_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Shadow.pngbin0 -> 103206 bytes
-rw-r--r--examples/demos/mediaplayer/icons/Shadow@2x.pngbin0 -> 377830 bytes
-rw-r--r--examples/demos/mediaplayer/icons/Shuffle_Active.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Shuffle_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Shuffle_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Single_Loop.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Stop_Icon.svg4
-rw-r--r--examples/demos/mediaplayer/icons/Trash_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Trash_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Volume_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Volume_Icon_Dark.svg3
-rw-r--r--examples/demos/mediaplayer/icons/Warning_Icon.svg3
-rw-r--r--examples/demos/mediaplayer/main.cpp37
73 files changed, 2170 insertions, 0 deletions
diff --git a/examples/demos/CMakeLists.txt b/examples/demos/CMakeLists.txt
index a76afc117..e9ce9e296 100644
--- a/examples/demos/CMakeLists.txt
+++ b/examples/demos/CMakeLists.txt
@@ -28,3 +28,6 @@ endif()
if(TARGET Qt::Quick AND TARGET Qt::QuickControls2 AND TARGET Qt::Quick3D)
qt_internal_add_example(robotarm)
endif()
+if(TARGET Qt::Quick AND TARGET Qt::QuickControls2 AND TARGET Qt::Multimedia)
+ qt_internal_add_example(mediaplayer)
+endif()
diff --git a/examples/demos/mediaplayer/CMakeLists.txt b/examples/demos/mediaplayer/CMakeLists.txt
new file mode 100644
index 000000000..834d11508
--- /dev/null
+++ b/examples/demos/mediaplayer/CMakeLists.txt
@@ -0,0 +1,54 @@
+cmake_minimum_required(VERSION 3.16)
+
+project(mediaplayer LANGUAGES CXX)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+if(NOT DEFINED INSTALL_EXAMPLESDIR)
+ set(INSTALL_EXAMPLESDIR "examples")
+endif()
+
+set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/demos/multimedia")
+
+find_package(Qt6 6.5 REQUIRED COMPONENTS Core Quick QuickControls2 Svg)
+
+qt_standard_project_setup(REQUIRES 6.5)
+
+qt_add_executable(${CMAKE_PROJECT_NAME}
+ main.cpp
+)
+
+set(qml_files
+ "Main.qml"
+ "MetadataInfo.qml"
+ "PlayerMenuBar.qml"
+ "TracksInfo.qml"
+ "TracksOptions.qml"
+ "PlaylistInfo.qml"
+ "UrlPopup.qml"
+ "SettingsInfo.qml"
+ "ThemeInfo.qml"
+ "ErrorPopup.qml"
+ "TouchMenu.qml"
+)
+
+qt_add_qml_module(${CMAKE_PROJECT_NAME}
+ URI MediaPlayerModule
+ QML_FILES ${qml_files})
+
+add_subdirectory(MediaControls)
+add_subdirectory(Config)
+
+target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE
+ Qt6::Core
+ Qt6::Svg
+ Qt6::Quick
+ MediaControlsplugin
+ Configplugin
+)
+
+install(TARGETS ${CMAKE_PROJECT_NAME}
+ RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
+ BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
+ LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
+)
diff --git a/examples/demos/mediaplayer/Config/CMakeLists.txt b/examples/demos/mediaplayer/Config/CMakeLists.txt
new file mode 100644
index 000000000..fe5abec22
--- /dev/null
+++ b/examples/demos/mediaplayer/Config/CMakeLists.txt
@@ -0,0 +1,13 @@
+qt_add_library(Config STATIC)
+
+set_source_files_properties(Config.qml
+ PROPERTIES
+ QT_QML_SINGLETON_TYPE true
+)
+
+qt_add_qml_module(Config
+ URI "Config"
+ OUTPUT_DIRECTORY Config
+ QML_FILES
+ "Config.qml"
+)
diff --git a/examples/demos/mediaplayer/Config/Config.qml b/examples/demos/mediaplayer/Config/Config.qml
new file mode 100644
index 000000000..9a73c182e
--- /dev/null
+++ b/examples/demos/mediaplayer/Config/Config.qml
@@ -0,0 +1,22 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma Singleton
+import QtQuick
+
+QtObject {
+ enum Theme {
+ Light,
+ Dark
+ }
+
+ property int activeTheme : Config.Theme.Dark
+
+ readonly property bool isMobileTarget : Qt.platform.os === "android" || Qt.platform.os === "ios"
+ readonly property color mainColor : activeTheme ? "#09102B" : "#FFFFFF"
+ readonly property color secondaryColor : activeTheme ? "#FFFFFF" : "#09102B"
+
+ function iconSource(fileName, addSuffix = true) {
+ return `qrc:/qt/qml/MediaControls/icons/${fileName}${activeTheme === Config.Theme.Dark && addSuffix ? "_Dark.svg" : ".svg"}`
+ }
+}
diff --git a/examples/demos/mediaplayer/Config/qmldir b/examples/demos/mediaplayer/Config/qmldir
new file mode 100644
index 000000000..042810d93
--- /dev/null
+++ b/examples/demos/mediaplayer/Config/qmldir
@@ -0,0 +1,4 @@
+module Config
+singleton Config 1.0 Config.qml
+
+
diff --git a/examples/demos/mediaplayer/ErrorPopup.qml b/examples/demos/mediaplayer/ErrorPopup.qml
new file mode 100644
index 000000000..f2ad6923b
--- /dev/null
+++ b/examples/demos/mediaplayer/ErrorPopup.qml
@@ -0,0 +1,41 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import Config
+
+Popup {
+ id: errorPopup
+ anchors.centerIn: Overlay.overlay
+ padding: 30
+
+ property alias errorMsg: label.text
+
+ onOpened: closeTimer.restart()
+
+ background: Rectangle {
+ color: "transparent"
+ }
+
+ Column {
+ spacing: 15
+
+ Image {
+ source: Config.iconSource("Error", false)
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ Label {
+ id: label
+ color: "#FFE353"
+ font.pixelSize: 24
+ }
+ }
+
+ Timer {
+ id: closeTimer
+ interval: 5000
+ onTriggered: errorPopup.close()
+ }
+}
diff --git a/examples/demos/mediaplayer/Main.qml b/examples/demos/mediaplayer/Main.qml
new file mode 100644
index 000000000..0d52b1edd
--- /dev/null
+++ b/examples/demos/mediaplayer/Main.qml
@@ -0,0 +1,382 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Window
+import QtQuick.Controls.Fusion
+import QtMultimedia
+import QtQuick.Effects
+import MediaControls
+import Config
+
+ApplicationWindow {
+ id: root
+ width: 1200
+ height: 780
+ minimumHeight: 460
+ minimumWidth: 640
+ visible: true
+ color: Config.mainColor
+ title: qsTr("Multimedia Player")
+
+ property alias currentFile: playlistInfo.currentIndex
+ property alias playlistLooped: playbackControl.isPlaylistLooped
+ property alias metadataInfo: settingsInfo.metadataInfo
+ property alias tracksInfo: settingsInfo.tracksInfo
+
+ function playMedia() {
+ mediaPlayer.source = playlistInfo.getSource()
+ mediaPlayer.play()
+ }
+
+ function closeOverlays() {
+ settingsInfo.visible = false
+ playlistInfo.visible = false
+ }
+
+ function showOverlay(overlay) {
+ closeOverlays()
+ overlay.visible = true
+ }
+
+ MouseArea {
+ id: mouseArea
+ anchors.fill: parent
+ hoverEnabled: true
+ onPositionChanged: {
+ if (!seeker.opacity) {
+ if (videoOutput.fullScreen) {
+ showControls.start()
+ } else {
+ seeker.showSeeker.start()
+ }
+ } else {
+ timer.restart()
+ }
+ }
+ onClicked: root.closeOverlays()
+ }
+
+ Timer {
+ id: timer
+ interval: 3000
+ onTriggered: {
+ if (!seeker.isMediaSliderPressed) {
+ if (videoOutput.fullScreen) {
+ hideControls.start()
+ } else {
+ seeker.hideSeeker.start()
+ }
+ } else {
+ timer.restart()
+ }
+ }
+ }
+
+ ErrorPopup {
+ id: errorPopup
+ }
+
+ Label {
+ text: qsTr("Click <font color=\"#41CD52\">here</font> to open media file.")
+ font.pixelSize: 24
+ color: Config.secondaryColor
+ anchors.centerIn: parent
+ visible: !errorPopup.visible && !videoOutput.visible && !defaultCoverArt.visible
+
+ TapHandler {
+ onTapped: menuBar.openFileMenu.open()
+ }
+ }
+
+ PlayerMenuBar {
+ id: menuBar
+
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ visible: !videoOutput.fullScreen
+
+ onFileOpened: (path) => {
+ ++root.currentFile
+ playlistInfo.addFile(root.currentFile, path)
+ mediaPlayer.source = path
+ mediaPlayer.play()
+ }
+ }
+
+ TouchMenu {
+ id: menuPopup
+ x: (parent.width - width) / 2
+ y: parent.height - height - 32
+ width: root.width - 64
+ openFileMenuItem.onClicked: {
+ menuPopup.close()
+ menuBar.openFileMenu.open()
+ }
+
+ openUrlMenuItem.onClicked: {
+ menuPopup.close()
+ menuBar.openUrlPopup.open()
+ }
+ }
+
+ MediaPlayer {
+ id: mediaPlayer
+
+ playbackRate: playbackControl.playbackRate
+ videoOutput: videoOutput
+ audioOutput: AudioOutput {
+ id: audio
+ volume: playbackControl.volume
+ }
+ source: new URL("https://download.qt.io/learning/videos/media-player-example/Qt_LogoMergeEffect.mp4")
+
+ function updateMetadata() {
+ root.metadataInfo.clear()
+ root.metadataInfo.read(mediaPlayer.metaData)
+ }
+
+ onMetaDataChanged: updateMetadata()
+ onActiveTracksChanged: updateMetadata()
+ onErrorOccurred: {
+ errorPopup.errorMsg = mediaPlayer.errorString
+ errorPopup.open()
+ }
+ onTracksChanged: {
+ settingsInfo.tracksInfo.selectedAudioTrack = mediaPlayer.activeAudioTrack
+ settingsInfo.tracksInfo.selectedVideoTrack = mediaPlayer.activeVideoTrack
+ settingsInfo.tracksInfo.selectedSubtitleTrack = mediaPlayer.activeSubtitleTrack
+ updateMetadata()
+ }
+
+ onMediaStatusChanged: {
+ if ((MediaPlayer.EndOfMedia === mediaStatus && mediaPlayer.loops !== MediaPlayer.Infinite) &&
+ ((root.currentFile < playlistInfo.mediaCount - 1) || playlistInfo.isShuffled)) {
+ if (!playlistInfo.isShuffled) {
+ ++root.currentFile
+ }
+ root.playMedia()
+ } else if (MediaPlayer.EndOfMedia === mediaStatus && root.playlistLooped && playlistInfo.mediaCount) {
+ root.currentFile = 0
+ root.playMedia()
+ }
+ }
+ }
+
+ VideoOutput {
+ id: videoOutput
+
+ anchors.top: fullScreen || Config.isMobileTarget ? parent.top : menuBar.bottom
+ anchors.bottom: fullScreen ? parent.bottom : playbackControl.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.leftMargin: fullScreen ? 0 : 20
+ anchors.rightMargin: fullScreen ? 0 : 20
+ visible: mediaPlayer.hasVideo
+
+ property bool fullScreen: false
+
+ TapHandler {
+ onDoubleTapped: {
+ if (parent.fullScreen) {
+ root.showNormal()
+ } else {
+ root.showFullScreen()
+ }
+ parent.fullScreen = !parent.fullScreen
+ }
+ onTapped: {
+ root.closeOverlays()
+ }
+ }
+ }
+
+ Image {
+ id: defaultCoverArt
+ anchors.horizontalCenter: videoOutput.horizontalCenter
+ anchors.verticalCenter: videoOutput.verticalCenter
+ visible: !videoOutput.visible && mediaPlayer.hasAudio
+ source: Config.iconSource("Default_CoverArt", false)
+ }
+
+ Rectangle {
+ id: background
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ anchors.top: seeker.opacity ? seeker.top : playbackControl.top
+ color: Config.mainColor
+ opacity: videoOutput.fullScreen ? 0.75 : 0.5
+ }
+
+ Image {
+ id: shadow
+ source: `qrc:/qt/qml/MediaControls/icons/Shadow.png`
+ anchors.bottom: parent.bottom
+ anchors.horizontalCenter: parent.horizontalCenter
+ }
+
+ PlaybackSeekControl {
+ id: seeker
+ anchors.left: videoOutput.left
+ anchors.right: videoOutput.right
+ anchors.bottom: playbackControl.top
+ mediaPlayer: mediaPlayer
+
+ fullScreenButton.onClicked: {
+ if (mediaPlayer.hasVideo) {
+ videoOutput.fullScreen ? root.showNormal() : root.showFullScreen()
+ videoOutput.fullScreen = !videoOutput.fullScreen
+ }
+ }
+
+ settingsButton.onClicked: !settingsInfo.visible ? root.showOverlay(settingsInfo) : root.closeOverlays()
+ }
+
+ PlaybackControl {
+ id: playbackControl
+
+ anchors.bottom: parent.bottom
+ anchors.left: parent.left
+ anchors.right: parent.right
+
+ mediaPlayer: mediaPlayer
+ isPlaylistVisible: playlistInfo.visible
+
+ onPlayNextFile: {
+ if (playlistInfo.mediaCount) {
+ if (!playlistInfo.isShuffled){
+ ++root.currentFile
+ if (root.currentFile > playlistInfo.mediaCount - 1 && root.playlistLooped) {
+ root.currentFile = 0
+ } else if (root.currentFile > playlistInfo.mediaCount - 1 && !root.playlistLooped) {
+ --root.currentFile
+ return
+ }
+ }
+ root.playMedia()
+ }
+ }
+
+ onPlayPreviousFile: {
+ if (playlistInfo.mediaCount) {
+ if (!playlistInfo.isShuffled){
+ --root.currentFile
+ if (root.currentFile < 0 && isPlaylistLooped) {
+ root.currentFile = playlistInfo.mediaCount - 1
+ } else if (root.currentFile < 0 && !root.playlistLooped) {
+ ++root.currentFile
+ return
+ }
+ }
+ root.playMedia()
+ }
+ }
+
+ playlistButton.onClicked: !playlistInfo.visible ? root.showOverlay(playlistInfo) : root.closeOverlays()
+ menuButton.onClicked: menuPopup.open()
+ }
+
+ MultiEffect {
+ source: settingsInfo
+ anchors.fill: settingsInfo
+ shadowEnabled: settingsInfo.visible || playlistInfo.visible
+ visible: settingsInfo.visible || playlistInfo.visible
+ }
+
+ PlaylistInfo {
+ id: playlistInfo
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: seeker.opacity ? seeker.top : playbackControl.top
+ anchors.topMargin: 10
+ anchors.rightMargin: 5
+
+ visible: false
+ isShuffled: playbackControl.isPlaylistShuffled
+
+ onPlaylistUpdated: {
+ if (mediaPlayer.playbackState == MediaPlayer.StoppedState && root.currentFile < playlistInfo.mediaCount - 1) {
+ ++root.currentFile
+ root.playMedia()
+ }
+ }
+
+ onCurrentFileRemoved: {
+ mediaPlayer.stop()
+ if (root.currentFile < playlistInfo.mediaCount - 1) {
+ root.playMedia()
+ } else if (playlistInfo.mediaCount) {
+ --root.currentFile
+ root.playMedia()
+ }
+ }
+ }
+
+ SettingsInfo {
+ id: settingsInfo
+
+ anchors.right: parent.right
+ anchors.top: parent.top
+ anchors.bottom: seeker.opacity ? seeker.top : playbackControl.top
+ anchors.topMargin: 10
+ anchors.rightMargin: 5
+
+ mediaPlayer: mediaPlayer
+ selectedAudioTrack: mediaPlayer.activeAudioTrack
+ selectedVideoTrack: mediaPlayer.activeVideoTrack
+ selectedSubtitleTrack: mediaPlayer.activeSubtitleTrack
+ visible: false
+ }
+
+ ParallelAnimation {
+ id: hideControls
+
+ NumberAnimation {
+ targets: [playbackControl, seeker, background, shadow]
+ property: "opacity"
+ to: 0
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ NumberAnimation {
+ target: playbackControl
+ property: "anchors.bottomMargin"
+ to: -playbackControl.height - seeker.height
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ ParallelAnimation {
+ id: showControls
+
+ NumberAnimation {
+ targets: [playbackControl, seeker, shadow]
+ property: "opacity"
+ to: 1
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ NumberAnimation {
+ target: background
+ property: "opacity"
+ to: 0.5
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ NumberAnimation {
+ target: playbackControl
+ property: "anchors.bottomMargin"
+ to: 0
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ Component.onCompleted: {
+ mediaPlayer.play()
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/AudioControl.qml b/examples/demos/mediaplayer/MediaControls/AudioControl.qml
new file mode 100644
index 000000000..76d858781
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/AudioControl.qml
@@ -0,0 +1,38 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+import Config
+
+Item {
+ id: root
+
+ property real volume: volumeSlider.value / 100
+
+ Layout.minimumWidth: 100
+ Layout.maximumWidth: 200
+
+ RowLayout {
+ anchors.fill: root
+ spacing: 10
+
+ Image {
+ source: Config.iconSource("Mute_Icon")
+ }
+
+ CustomSlider {
+ id: volumeSlider
+ enabled: true
+ to: 100.0
+ value: 100.0
+
+ Layout.fillWidth: true
+ Layout.alignment: Qt.AlignVCenter
+ }
+
+ Image {
+ source: Config.iconSource("Volume_Icon")
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/CMakeLists.txt b/examples/demos/mediaplayer/MediaControls/CMakeLists.txt
new file mode 100644
index 000000000..4222e4f8d
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/CMakeLists.txt
@@ -0,0 +1,62 @@
+qt_add_library(MediaControls STATIC)
+
+target_link_libraries(MediaControls PRIVATE Qt6::Quick)
+
+qt_add_qml_module(MediaControls
+ URI "MediaControls"
+ OUTPUT_DIRECTORY MediaControls
+ QML_FILES
+ "AudioControl.qml"
+ "PlaybackSeekControl.qml"
+ "PlaybackRateControl.qml"
+ "PlaybackControl.qml"
+ "CustomSlider.qml"
+ "CustomButton.qml"
+ "CustomRadioButton.qml"
+ RESOURCES
+ "../icons/Rate_Icon.svg"
+ "../icons/Rate_Icon_Dark.svg"
+ "../icons/Loop_Icon.svg"
+ "../icons/Loop_Icon_Dark.svg"
+ "../icons/Play_Icon.svg"
+ "../icons/Previous_Icon.svg"
+ "../icons/Previous_Icon_Dark.svg"
+ "../icons/Next_Icon.svg"
+ "../icons/Next_Icon_Dark.svg"
+ "../icons/Shuffle_Icon.svg"
+ "../icons/Volume_Icon.svg"
+ "../icons/Volume_Icon_Dark.svg"
+ "../icons/Playlist_Icon.svg"
+ "../icons/Playlist_Icon_Dark.svg"
+ "../icons/Settings_Icon.svg"
+ "../icons/Settings_Icon_Dark.svg"
+ "../icons/FullScreen_Icon.svg"
+ "../icons/FullScreen_Icon_Dark.svg"
+ "../icons/Stop_Icon.svg"
+ "../icons/Loop_Playlist.svg"
+ "../icons/Single_Loop.svg"
+ "../icons/Playlist_Active.svg"
+ "../icons/Add_file.svg"
+ "../icons/Add_file_Dark.svg"
+ "../icons/Movie_Icon.svg"
+ "../icons/Movie_Icon_Dark.svg"
+ "../icons/Trash_Icon.svg"
+ "../icons/Trash_Icon_Dark.svg"
+ "../icons/Music_Icon.svg"
+ "../icons/Music_Icon_Dark.svg"
+ "../icons/Music_Active.svg"
+ "../icons/Movie_Active.svg"
+ "../icons/Shuffle_Icon_Dark.svg"
+ "../icons/Shuffle_Active.svg"
+ "../icons/Default_CoverArt.svg"
+ "../icons/Cancel_Button.svg"
+ "../icons/Load_Button.svg"
+ "../icons/Shadow.png"
+ "../icons/Warning_Icon.svg"
+ "../icons/Menu_Icon.svg"
+ "../icons/Menu_Icon_Dark.svg"
+ "../icons/Mute_Icon.svg"
+ "../icons/Mute_Icon_Dark.svg"
+ "../icons/Error.svg"
+
+)
diff --git a/examples/demos/mediaplayer/MediaControls/CustomButton.qml b/examples/demos/mediaplayer/MediaControls/CustomButton.qml
new file mode 100644
index 000000000..abdd189ce
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/CustomButton.qml
@@ -0,0 +1,26 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Effects
+
+Button {
+ id: control
+ flat: true
+
+ contentItem: Image {
+ id: image
+ source: control.icon.source
+ }
+
+ background: MultiEffect {
+ source: image
+ anchors.fill: control
+ visible: control.down
+ opacity: 0.5
+ shadowEnabled: true
+ blurEnabled: true
+ blur: 0.5
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/CustomRadioButton.qml b/examples/demos/mediaplayer/MediaControls/CustomRadioButton.qml
new file mode 100644
index 000000000..4096ca733
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/CustomRadioButton.qml
@@ -0,0 +1,40 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import Config
+
+RadioButton {
+ id: control
+
+ height: 20
+
+ indicator: Rectangle {
+ width: 20
+ height: 20
+ radius: 10
+ x: control.leftPadding
+ y: control.height / 2 - height / 2
+ color: "transparent"
+ border.color: Config.secondaryColor
+ border.width: 2
+
+ Rectangle {
+ width: 10
+ height: 10
+ radius: 5
+ color: Config.secondaryColor
+ anchors.centerIn: parent
+ visible: control.checked
+ }
+ }
+
+ contentItem: Label {
+ text: control.text
+ font.pixelSize: 18
+ verticalAlignment: Text.AlignVCenter
+ leftPadding: control.indicator.width + control.spacing
+ color: Config.secondaryColor
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/CustomSlider.qml b/examples/demos/mediaplayer/MediaControls/CustomSlider.qml
new file mode 100644
index 000000000..34ec6775c
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/CustomSlider.qml
@@ -0,0 +1,44 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+
+Slider {
+ id: slider
+
+ property alias backgroundColor: backgroundRec.color
+ property alias backgroundOpacity: backgroundRec.opacity
+
+ background: Rectangle {
+ id: backgroundRec
+ x: slider.leftPadding
+ y: slider.topPadding + slider.availableHeight / 2 - height / 2
+ implicitWidth: 120
+ implicitHeight: 8
+ width: slider.availableWidth
+ height: implicitHeight
+ radius: 10
+ color: "#41CD52"
+ opacity: 0.2
+ border.color: "#41CD52"
+ border.width: 1
+ }
+
+ handle: Rectangle {
+ x: slider.leftPadding + slider.visualPosition * (slider.availableWidth - width)
+ y: slider.topPadding + slider.availableHeight / 2 - height / 2
+ implicitWidth: 8
+ implicitHeight: 8
+ color: "transparent"
+ }
+
+ Rectangle {
+ width: slider.visualPosition * slider.availableWidth
+ x: slider.leftPadding
+ y: slider.topPadding + slider.availableHeight / 2 - height / 2
+ height: 8
+ color: "#41CD52"
+ radius: 10
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/PlaybackControl.qml b/examples/demos/mediaplayer/MediaControls/PlaybackControl.qml
new file mode 100644
index 000000000..eee729895
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/PlaybackControl.qml
@@ -0,0 +1,191 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Layouts
+import QtMultimedia
+import Config
+
+Item {
+ id: root
+
+ implicitHeight: 100
+
+ required property MediaPlayer mediaPlayer
+ readonly property int mediaPlayerState: root.mediaPlayer.playbackState
+ property bool isPlaylistShuffled: false
+ property bool isPlaylistLooped: false
+ property bool isPlaylistVisible: false
+ property url playlistIcon: !root.isPlaylistVisible ? Config.iconSource("Playlist_Icon") : Config.iconSource("Playlist_Active", false)
+ property url shuffleIcon: !root.isPlaylistShuffled ? Config.iconSource("Shuffle_Icon") : Config.iconSource("Shuffle_Active", false)
+
+ property alias volume: audio.volume
+ property alias playbackRate: rate.playbackRate
+ property alias playlistButton: playlistButton
+ property alias menuButton: menuButton
+
+ signal playNextFile()
+ signal playPreviousFile()
+
+ function changeLoopMode() {
+ if (root.mediaPlayer.loops === 1 && !root.isPlaylistLooped) {
+ root.mediaPlayer.loops = MediaPlayer.Infinite
+ } else if (root.mediaPlayer.loops === MediaPlayer.Infinite) {
+ root.mediaPlayer.loops = 1
+ root.isPlaylistLooped = true
+ } else {
+ root.mediaPlayer.loops = 1
+ root.isPlaylistLooped = false
+ }
+ }
+
+ Item {
+ anchors.fill: root
+
+ RowLayout {
+ id: playerButtons
+ anchors.fill: parent
+
+ Item {
+ CustomButton {
+ id: menuButton
+ icon.source: Config.iconSource("Menu_Icon")
+ visible: Config.isMobileTarget
+ anchors.centerIn: parent
+ }
+
+ Layout.fillWidth: true
+ Layout.minimumWidth: 40
+ Layout.maximumWidth: 95
+ }
+
+ PlaybackRateControl {
+ id: rate
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ RowLayout {
+ id: controlButtons
+ spacing: Screen.primaryOrientation === Qt.LandscapeOrientation ? 25 : 1
+
+ Layout.alignment: Qt.AlignHCenter
+ Layout.fillWidth: true
+
+ CustomButton {
+ id: shuffleButton
+ icon.source: root.shuffleIcon
+ visible: Screen.primaryOrientation === Qt.LandscapeOrientation
+ onClicked: root.isPlaylistShuffled = !root.isPlaylistShuffled
+ }
+
+ CustomButton {
+ id: previousButton
+ icon.source: Config.iconSource("Previous_Icon")
+ onClicked: root.playPreviousFile()
+ }
+
+ CustomButton {
+ id: playButton
+ icon.source: Config.iconSource("Play_Icon", false)
+ onClicked: root.mediaPlayer.play()
+ }
+
+ CustomButton {
+ id: pausedButton
+ icon.source: Config.iconSource("Stop_Icon", false)
+ onClicked: root.mediaPlayer.pause()
+ }
+
+ CustomButton {
+ id: nextButton
+ icon.source: Config.iconSource("Next_Icon")
+ onClicked: root.playNextFile()
+ }
+
+ CustomButton {
+ id: loopButton
+ icon.source: Config.iconSource("Loop_Icon")
+ visible: Screen.primaryOrientation === Qt.LandscapeOrientation
+ onClicked: root.changeLoopMode()
+
+ states: [
+ State {
+ name: "noActiveLooping"
+ when: root.mediaPlayer.loops === 1 && !root.isPlaylistLooped
+ PropertyChanges {
+ loopButton.icon.source: Config.iconSource("Loop_Icon")
+ }
+ },
+ State {
+ name: "singleLoop"
+ when: root.mediaPlayer.loops === MediaPlayer.Infinite
+ PropertyChanges {
+ loopButton.icon.source: Config.iconSource("Single_Loop", false)
+ }
+ },
+ State {
+ name: "playlistLoop"
+ when: root.isPlaylistLooped
+ PropertyChanges {
+ loopButton.icon.source: Config.iconSource("Loop_Playlist", false)
+ }
+ }
+ ]
+ }
+ }
+
+ Item {
+ Layout.fillWidth: true
+ }
+
+ AudioControl {
+ id: audio
+ Layout.fillHeight: true
+ Layout.fillWidth: true
+ }
+
+ Item {
+ Layout.fillWidth: true
+ Layout.minimumWidth:40
+ Layout.maximumWidth: 95
+
+ CustomButton {
+ id: playlistButton
+ anchors.centerIn: parent
+ icon.source: root.playlistIcon
+ }
+ }
+ }
+ }
+
+ states: [
+ State {
+ name: "playing"
+ when: root.mediaPlayerState == MediaPlayer.PlayingState
+
+ PropertyChanges {
+ playButton.visible: false
+ }
+ PropertyChanges {
+ pausedButton.visible: true
+ }
+ },
+ State {
+ name: "paused"
+ when: root.mediaPlayerState == MediaPlayer.PausedState || root.mediaPlayerState == MediaPlayer.StoppedState
+
+ PropertyChanges {
+ playButton.visible: true
+ }
+ PropertyChanges {
+ pausedButton.visible: false
+ }
+ }
+ ]
+}
+
diff --git a/examples/demos/mediaplayer/MediaControls/PlaybackRateControl.qml b/examples/demos/mediaplayer/MediaControls/PlaybackRateControl.qml
new file mode 100644
index 000000000..4ea05424d
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/PlaybackRateControl.qml
@@ -0,0 +1,40 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Layouts
+import Config
+
+Item {
+ id: root
+
+ property alias playbackRate: slider.value
+
+ Layout.minimumWidth: 100
+ Layout.maximumWidth: 200
+
+ RowLayout {
+ anchors.fill: root
+ spacing: 10
+
+ Image {
+ source: Config.iconSource("Rate_Icon")
+ }
+
+ CustomSlider {
+ id: slider
+ Layout.fillWidth: true
+ snapMode: Slider.SnapOnRelease
+ from: 0.5
+ to: 2.5
+ stepSize: 0.5
+ value: 1.0
+ }
+
+ Label {
+ text: slider.value.toFixed(1) + "x"
+ color: "#41CD52"
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/PlaybackSeekControl.qml b/examples/demos/mediaplayer/MediaControls/PlaybackSeekControl.qml
new file mode 100644
index 000000000..141232b32
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/PlaybackSeekControl.qml
@@ -0,0 +1,106 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Layouts
+import QtMultimedia
+import Config
+
+Item {
+ id: root
+ implicitHeight: 40
+
+ required property MediaPlayer mediaPlayer
+ property alias fullScreenButton: fullScreenButton
+ property alias settingsButton: settingsButton
+ property alias isMediaSliderPressed: mediaSlider.pressed
+ property alias showSeeker: showSeekerAnim
+ property alias hideSeeker: hideSeekerAnim
+
+ function getTime(time : int) {
+ const h = Math.floor(time / 3600000).toString()
+ const m = Math.floor(time / 60000).toString()
+ const s = Math.floor(time / 1000 - m * 60).toString()
+ return `${h.padStart(2,'0')}:${m.padStart(2,'0')}:${s.padStart(2, '0')}`
+ }
+
+ RowLayout {
+ anchors.fill: root
+ anchors.leftMargin: 10
+ anchors.rightMargin: 10
+
+ Label {
+ id: mediaTime
+ color: Config.secondaryColor
+ font.bold: true
+ text: root.getTime(root.mediaPlayer.position)
+ }
+
+ CustomSlider {
+ id: mediaSlider
+ backgroundColor: !Config.activeTheme ? "white" : "#41CD52"
+ backgroundOpacity: !Config.activeTheme ? 0.8 : 0.2
+ enabled: root.mediaPlayer.seekable
+ to: 1.0
+ value: root.mediaPlayer.position / root.mediaPlayer.duration
+
+ Layout.fillWidth: true
+
+ onMoved: root.mediaPlayer.setPosition(value * root.mediaPlayer.duration)
+ }
+
+ Label {
+ id: durationTime
+ color: Config.secondaryColor
+ font.bold: true
+ text: root.getTime(root.mediaPlayer.duration)
+ }
+
+ CustomButton {
+ id: settingsButton
+ icon.source: Config.iconSource("Settings_Icon")
+ }
+
+ CustomButton {
+ id: fullScreenButton
+ icon.source: Config.iconSource("FullScreen_Icon")
+ }
+ }
+
+ ParallelAnimation {
+ id: hideSeekerAnim
+ NumberAnimation {
+ target: root
+ properties: "opacity"
+ to: 0
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ NumberAnimation {
+ target: root
+ properties: "anchors.bottomMargin"
+ to: -root.height
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ }
+
+ ParallelAnimation {
+ id: showSeekerAnim
+ PropertyAnimation {
+ target: root
+ properties: "opacity"
+ to: 1
+ duration: 1000
+ easing.type: Easing.InOutQuad
+ }
+ PropertyAnimation {
+ target: root
+ properties: "anchors.bottomMargin"
+ to: 0
+ duration: 500
+ easing.type: Easing.InOutQuad
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/MediaControls/qmldir b/examples/demos/mediaplayer/MediaControls/qmldir
new file mode 100644
index 000000000..b0f1c5363
--- /dev/null
+++ b/examples/demos/mediaplayer/MediaControls/qmldir
@@ -0,0 +1,9 @@
+module MediaControls
+AudioControl 1.0 AudioControl.qml
+CustomButton 1.0 CustomButton.qml
+CustomRadioButton 1.0 CustomRadioButton.qml
+CustomSlider 1.0 CustomSlider.qml
+PlaybackControl 1.0 PlaybackControl.qml
+PlaybackRateControl 1.0 PlaybackRateControl.qml
+PlaybackSeekControl 1.0 PlaybackSeekControl.qml
+
diff --git a/examples/demos/mediaplayer/MetadataInfo.qml b/examples/demos/mediaplayer/MetadataInfo.qml
new file mode 100644
index 000000000..b087b77ba
--- /dev/null
+++ b/examples/demos/mediaplayer/MetadataInfo.qml
@@ -0,0 +1,76 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls.Fusion
+import Config
+
+Item {
+ id: root
+
+ function clear() {
+ elements.clear()
+ }
+
+ function read(metadata) {
+ if (metadata) {
+ for (var key of metadata.keys()) {
+ if (metadata.stringValue(key)) {
+ elements.append({
+ name: metadata.metaDataKeyToString(key),
+ value: metadata.stringValue(key)
+ })
+ }
+ }
+ }
+ }
+
+ ListModel {
+ id: elements
+ }
+
+ Item {
+ anchors.fill: parent
+ anchors.margins: 15
+
+ ListView {
+ id: metadataList
+ anchors.fill: parent
+ model: elements
+ delegate: RowLayout {
+ id: row
+ width: metadataList.width
+
+ required property string name
+ required property string value
+
+ Label {
+ text: row.name + ":"
+ font.pixelSize: 16
+ color: Config.secondaryColor
+
+ Layout.preferredWidth: root.width / 2
+ }
+ Label {
+ text: row.value
+ font.pixelSize: 16
+ wrapMode: Text.WrapAnywhere
+ color: Config.secondaryColor
+
+ Layout.fillWidth: true
+ }
+ }
+ }
+
+ Label {
+ visible: !elements.count
+ font.pixelSize: 16
+ text: qsTr("No metadata present")
+ anchors.centerIn: parent
+ color: Config.secondaryColor
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/PlayerMenuBar.qml b/examples/demos/mediaplayer/PlayerMenuBar.qml
new file mode 100644
index 000000000..38bc3be6f
--- /dev/null
+++ b/examples/demos/mediaplayer/PlayerMenuBar.qml
@@ -0,0 +1,59 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Dialogs
+import Config
+
+Item {
+ id: root
+
+ implicitHeight: menuBar.height
+
+ signal fileOpened(path: url)
+
+ property alias openFileMenu: fileDialog
+ property alias openUrlPopup: urlPopup
+
+ FileDialog {
+ id: fileDialog
+ title: qsTr("Please choose a file")
+ onAccepted: root.fileOpened(fileDialog.selectedFile)
+ }
+
+ UrlPopup {
+ id: urlPopup
+ onPathChanged: root.fileOpened(urlPopup.path)
+ }
+
+ MenuBar {
+ id: menuBar
+ visible: !Config.isMobileTarget
+ anchors.left: root.left
+ leftPadding: 10
+ topPadding: 10
+
+ palette.base: Config.mainColor
+ palette.text: Config.secondaryColor
+ palette.highlightedText: "#41CD52"
+ palette.window: "transparent"
+ palette.highlight: Config.mainColor
+
+ Menu {
+ title: qsTr("&File")
+ palette.text: Config.secondaryColor
+ palette.window: Config.mainColor
+ palette.highlightedText: "#41CD52"
+
+ MenuItem {
+ text: qsTr("Open &file")
+ onTriggered: fileDialog.open()
+ }
+ MenuItem {
+ text: qsTr("Open &URL")
+ onTriggered: urlPopup.open()
+ }
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/PlaylistInfo.qml b/examples/demos/mediaplayer/PlaylistInfo.qml
new file mode 100644
index 000000000..464bac74c
--- /dev/null
+++ b/examples/demos/mediaplayer/PlaylistInfo.qml
@@ -0,0 +1,230 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Dialogs
+import QtQuick.Layouts
+import QtCore
+import MediaControls
+import Config
+
+Rectangle {
+ id: root
+
+ implicitWidth: 380
+ color: Config.mainColor
+ border.color: "lightgrey"
+ radius: 10
+
+ property int currentIndex: -1
+ property bool isShuffled: false
+ property alias mediaCount: files.count
+ signal playlistUpdated()
+ signal currentFileRemoved()
+
+ function getSource() {
+ if (isShuffled) {
+ let randomIndex = Math.floor(Math.random() * mediaCount)
+ while (randomIndex == currentIndex) {
+ randomIndex = Math.floor(Math.random() * mediaCount)
+ }
+ currentIndex = randomIndex
+ }
+ return files.get(currentIndex).path
+ }
+
+ function addFiles(index, selectedFiles) {
+ selectedFiles.forEach(function (file){
+ const url = new URL(file)
+ files.insert(index,
+ {
+ path: url,
+ isMovie: isMovie(url.toString())
+ })
+ })
+ playlistUpdated()
+ }
+
+ function addFile(index, selectedFile) {
+ if (index > mediaCount || index < 0) {
+ index = 0
+ currentIndex = 0
+ }
+ files.insert(index,
+ {
+ path: selectedFile,
+ isMovie: isMovie(selectedFile.toString())
+ })
+
+ }
+
+ function isMovie(path) {
+ const paths = path.split('.')
+ const extension = paths[paths.length - 1]
+ const musicFormats = ["mp3", "wav", "aac"]
+ for (const format of musicFormats) {
+ if (format === extension) {
+ return false
+ }
+ }
+ return true
+ }
+
+ MouseArea {
+ anchors.fill: root
+ preventStealing: true
+ }
+
+ FileDialog {
+ id: folderView
+ title: qsTr("Add files to playlist")
+ currentFolder: StandardPaths.standardLocations(StandardPaths.MoviesLocation)[0]
+ fileMode: FileDialog.OpenFiles
+ onAccepted: {
+ root.addFiles(files.count, folderView.selectedFiles)
+ close()
+ }
+ }
+
+ ListModel {
+ id: files
+ }
+
+ Item {
+ id: playlist
+ anchors.fill: root
+ anchors.margins: 30
+
+ RowLayout {
+ id: header
+ width: playlist.width
+
+ Label {
+ font.bold: true
+ font.pixelSize: 20
+ text: qsTr("Playlist")
+ color: Config.secondaryColor
+
+ Layout.fillWidth: true
+ }
+
+ CustomButton {
+ icon.source: Config.iconSource("Add_file")
+ onClicked: folderView.open()
+ }
+ }
+
+ ListView {
+ id: listView
+ model: files
+ anchors.fill: playlist
+ anchors.topMargin: header.height + 30
+ spacing: 20
+
+ delegate: RowLayout {
+ id: row
+ width: listView.width
+ spacing: 15
+
+ required property string path
+ required property int index
+ required property bool isMovie
+
+ Image {
+ id: mediaIcon
+
+ states: [
+ State {
+ name: "activeMovie"
+ when: root.currentIndex === row.index && row.isMovie
+ PropertyChanges {
+ mediaIcon.source: Config.iconSource("Movie_Active", false)
+ }
+ },
+ State {
+ name: "inactiveMovie"
+ when: root.currentIndex !== row.index && row.isMovie
+ PropertyChanges {
+ mediaIcon.source: Config.iconSource("Movie_Icon")
+ }
+ },
+ State {
+ name: "activeMusic"
+ when: root.currentIndex === row.index && !row.isMovie
+ PropertyChanges {
+ mediaIcon.source: Config.iconSource("Music_Active", false)
+ }
+ },
+ State {
+ name: "inactiveMusic"
+ when: root.currentIndex !== row.index && !row.isMovie
+ PropertyChanges {
+ mediaIcon.source: Config.iconSource("Music_Icon")
+ }
+ }
+ ]
+ }
+
+ Label {
+ Layout.fillWidth: true
+ elide: Text.ElideRight
+ font.bold: root.currentIndex === row.index
+ color: root.currentIndex === row.index ? "#41CD52" : Config.secondaryColor
+ font.pixelSize: 18
+ text: {
+ const paths = row.path.split('/')
+ return paths[paths.length - 1]
+ }
+ }
+
+ CustomButton {
+ icon.source: Config.iconSource("Trash_Icon")
+ onClicked: {
+ const removedIndex = row.index
+ files.remove(row.index)
+ if (root.currentIndex === removedIndex) {
+ root.currentFileRemoved()
+ } else if (root.currentIndex > removedIndex) {
+ --root.currentIndex
+ }
+ }
+ }
+ }
+
+ remove: Transition {
+ NumberAnimation {
+ property: "opacity"
+ from: 1.0
+ to: 0.0
+ duration: 400
+ }
+ }
+
+ add: Transition {
+ NumberAnimation {
+ property: "opacity"
+ from: 0.0
+ to: 1.0
+ duration: 400
+ }
+ NumberAnimation {
+ property: "scale"
+ from: 0.5
+ to: 1.0
+ duration: 400
+ }
+ }
+
+ displaced: Transition {
+ NumberAnimation {
+ properties: "y"
+ duration: 600
+ easing.type: Easing.OutBounce
+ }
+ }
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/SettingsInfo.qml b/examples/demos/mediaplayer/SettingsInfo.qml
new file mode 100644
index 000000000..8dbdc1444
--- /dev/null
+++ b/examples/demos/mediaplayer/SettingsInfo.qml
@@ -0,0 +1,84 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Layouts
+import QtQuick.Controls.Fusion
+import QtMultimedia
+import Config
+
+Rectangle {
+ id: root
+ implicitWidth: 380
+ color: Config.mainColor
+ border.color: "lightgrey"
+ radius: 10
+
+ property alias tracksInfo: tracksInfo
+ property alias metadataInfo: metadataInfo
+ required property MediaPlayer mediaPlayer
+ required property int selectedAudioTrack
+ required property int selectedVideoTrack
+ required property int selectedSubtitleTrack
+
+ MouseArea {
+ anchors.fill: root
+ preventStealing: true
+ }
+
+ TabBar {
+ id: bar
+ width: root.width
+ contentHeight: 60
+
+ Repeater {
+ model: [qsTr("Metadata"), qsTr("Tracks"), qsTr("Theme")]
+
+ TabButton {
+ id: tab
+ required property int index
+ required property string modelData
+ property color shadowColor: bar.currentIndex === index ? "#41CD52" : "black"
+ property color textColor: bar.currentIndex === index ? "#41CD52" : Config.secondaryColor
+
+ background: Rectangle {
+ opacity: 0.15
+ gradient: Gradient {
+ GradientStop { position: 0.0; color: "transparent" }
+ GradientStop { position: 0.5; color: "transparent" }
+ GradientStop { position: 1.0; color: tab.shadowColor }
+ }
+ }
+
+ contentItem: Label {
+ verticalAlignment: Text.AlignVCenter
+ horizontalAlignment: Text.AlignHCenter
+ text: tab.modelData
+ font.pixelSize: 20
+ color: tab.textColor
+ }
+ }
+ }
+ }
+
+ StackLayout {
+ width: root.width
+ anchors.top: bar.bottom
+ anchors.bottom: root.bottom
+ currentIndex: bar.currentIndex
+
+ MetadataInfo { id: metadataInfo }
+
+ TracksInfo {
+ id: tracksInfo
+ mediaPlayer: root.mediaPlayer
+ selectedAudioTrack: root.selectedAudioTrack
+ selectedVideoTrack: root.selectedVideoTrack
+ selectedSubtitleTrack: root.selectedSubtitleTrack
+ }
+
+ ThemeInfo { id: themeInfo }
+ }
+}
diff --git a/examples/demos/mediaplayer/ThemeInfo.qml b/examples/demos/mediaplayer/ThemeInfo.qml
new file mode 100644
index 000000000..f47cadbae
--- /dev/null
+++ b/examples/demos/mediaplayer/ThemeInfo.qml
@@ -0,0 +1,38 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import MediaControls
+import Config
+
+Item {
+ id: root
+
+ Item {
+ anchors.fill: parent
+
+ Column {
+ padding: 15
+ spacing: 20
+
+ ButtonGroup { id: group }
+
+ CustomRadioButton {
+ checked: Config.Theme.Light === Config.activeTheme
+ text: qsTr("Light theme")
+ ButtonGroup.group: group
+ onClicked: Config.activeTheme = Config.Theme.Light
+ }
+
+ CustomRadioButton {
+ checked: Config.Theme.Dark === Config.activeTheme
+ text: qsTr("Dark theme")
+ ButtonGroup.group: group
+ onClicked: Config.activeTheme = Config.Theme.Dark
+ }
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/TouchMenu.qml b/examples/demos/mediaplayer/TouchMenu.qml
new file mode 100644
index 000000000..3c85758cc
--- /dev/null
+++ b/examples/demos/mediaplayer/TouchMenu.qml
@@ -0,0 +1,94 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Layouts
+import Config
+
+Menu {
+ id: menuPopup
+ padding: 0
+ verticalPadding: 15
+
+ property alias openUrlMenuItem: openUrlMenuItem
+ property alias openFileMenuItem: openFileMenuItem
+
+ background: Rectangle {
+ color: Config.mainColor
+ radius: 15
+ border.color: "#41CD52"
+ }
+
+ component MenuItemLabel: Label {
+ font.pixelSize: 24
+ color: "#41CD52"
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ topPadding: 4
+ bottomPadding: 4
+ }
+
+ component CustomMenuItem: MenuItem {
+ id: menuItem
+
+ property bool bold
+
+ text: qsTr("File")
+ contentItem: MenuItemLabel {
+ text: menuItem.text
+ font.bold: menuItem.bold
+ }
+
+ background: Rectangle {
+ color: menuItem.pressed ? "#41CD52" : "transparent"
+ opacity: 0.25
+ }
+ }
+
+ MenuItemLabel {
+ text: qsTr("Load media file from:")
+ color: Config.secondaryColor
+ bottomPadding: 12
+
+ width: parent.width
+ }
+
+ Rectangle {
+ width: parent.width
+ implicitHeight: 1
+ color: "#41CD52"
+ opacity: 0.25
+ }
+
+ CustomMenuItem {
+ id: openFileMenuItem
+ text: qsTr("File")
+ bold: true
+ }
+
+ Rectangle {
+ width: parent.width
+ implicitHeight: 1
+ color: "#41CD52"
+ opacity: 0.25
+ }
+
+ CustomMenuItem {
+ id: openUrlMenuItem
+ text: qsTr("URL")
+ bold: true
+ }
+
+ Rectangle {
+ implicitHeight: 1
+ color: "#41CD52"
+
+ Layout.fillWidth: true
+ }
+
+ CustomMenuItem {
+ id: cancelButtonBackground
+ text: qsTr("Cancel")
+ }
+}
diff --git a/examples/demos/mediaplayer/TracksInfo.qml b/examples/demos/mediaplayer/TracksInfo.qml
new file mode 100644
index 000000000..0344ffcdd
--- /dev/null
+++ b/examples/demos/mediaplayer/TracksInfo.qml
@@ -0,0 +1,55 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtMultimedia
+
+Item {
+ id: root
+
+ required property int selectedAudioTrack
+ required property int selectedVideoTrack
+ required property int selectedSubtitleTrack
+ required property MediaPlayer mediaPlayer
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: column.implicitWidth
+ contentHeight: column.implicitHeight
+ boundsBehavior: Flickable.DragAndOvershootBounds
+ flickableDirection: Flickable.VerticalFlick
+ clip: true
+
+ Column {
+ id: column
+ anchors.fill: parent
+ clip: true
+ padding: 15
+ spacing: 20
+
+ TracksOptions {
+ id: audioTracks
+ headerText: qsTr("Audio Tracks")
+ selectedTrack: root.selectedVideoTrack
+ metaData: root.mediaPlayer.audioTracks
+ onSelectedTrackChanged: root.mediaPlayer.activeAudioTrack = audioTracks.selectedTrack
+ }
+
+ TracksOptions {
+ id: videoTracks
+ headerText: qsTr("Video Tracks")
+ selectedTrack: root.selectedVideoTrack
+ metaData: root.mediaPlayer.videoTracks
+ onSelectedTrackChanged: root.mediaPlayer.activeVideoTrack = videoTracks.selectedTrack
+ }
+
+ TracksOptions {
+ id: subtitleTracks
+ headerText: qsTr("Subtitle Tracks")
+ selectedTrack: root.selectedSubtitleTrack
+ metaData: root.mediaPlayer.subtitleTracks
+ onSelectedTrackChanged: root.mediaPlayer.activeSubtitleTrack = subtitleTracks.selectedTrack
+ }
+ }
+ }
+}
diff --git a/examples/demos/mediaplayer/TracksOptions.qml b/examples/demos/mediaplayer/TracksOptions.qml
new file mode 100644
index 000000000..4b2e646b3
--- /dev/null
+++ b/examples/demos/mediaplayer/TracksOptions.qml
@@ -0,0 +1,81 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+pragma ComponentBehavior: Bound
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtMultimedia
+import MediaControls
+import Config
+
+Item {
+ id: root
+
+ implicitWidth: 380
+ implicitHeight: elements.count ? (elements.count + 1) * 40 : 20
+
+ required property int selectedTrack
+ required property list<mediaMetaData> metaData
+ property string headerText: ""
+
+ function readTracks(metadataList : list<mediaMetaData>) {
+ const LanguageKey = 6
+ elements.clear()
+ if (!metadataList || !metadataList.length)
+ return
+
+ elements.append({
+ language: "No Track",
+ trackNumber: -1
+ })
+
+ metadataList.forEach(function (metadata, index) {
+ const language = metadata.stringValue(LanguageKey)
+ const label = language ? language : "Track " + (index + 1)
+ elements.append({
+ language: label,
+ trackNumber: index
+ })
+ });
+ }
+
+ ListModel { id: elements }
+
+ ButtonGroup { id: group }
+
+ Column {
+ spacing: 16
+ anchors.fill: root
+
+ Label {
+ id: header
+ text: elements.count ? qsTr(root.headerText) : qsTr("No " + root.headerText + " present")
+ font.pixelSize: 18
+ font.bold: true
+ color: Config.secondaryColor
+ }
+
+ ListView {
+ id: trackList
+ model: elements
+ spacing: 18
+ height: root.implicitHeight - header.height
+ width: parent.width
+ clip: true
+ delegate: CustomRadioButton {
+ checked: trackNumber === root.selectedTrack
+ text: language
+
+ required property int trackNumber
+ required property string language
+
+ ButtonGroup.group: group
+
+ onClicked: root.selectedTrack = trackNumber
+ }
+ }
+ }
+
+ onMetaDataChanged: readTracks(root.metaData)
+}
diff --git a/examples/demos/mediaplayer/UrlPopup.qml b/examples/demos/mediaplayer/UrlPopup.qml
new file mode 100644
index 000000000..670c205f7
--- /dev/null
+++ b/examples/demos/mediaplayer/UrlPopup.qml
@@ -0,0 +1,138 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+import QtQuick
+import QtQuick.Controls.Fusion
+import QtQuick.Layouts
+import MediaControls
+import Config
+
+Popup {
+ id: urlPopup
+ anchors.centerIn: Overlay.overlay
+ padding: 30
+ width: 500
+ height: column.height + 60
+
+ property url path: ""
+ readonly property color borderColor: urlText.text ? (!errorMsg.visible ? "#41CD52" : "red") : Config.secondaryColor
+
+ background: Rectangle {
+ color: Config.mainColor
+ opacity: 0.9
+ radius: 15
+ border.color: "grey"
+ }
+
+ function setUrl(urlPath: url) {
+ path = urlPath
+ urlPopup.close()
+ }
+
+ function validateUrl(urlText: string) {
+ const urlPattern = /^((http)|(https)|(rtp)|(rtsp)|(udp)):\/\//
+ return urlPattern.test(urlText)
+ }
+
+ Column {
+ id: column
+ spacing: 20
+
+ Label {
+ text: qsTr("Load from URL")
+ font.pixelSize: 18
+ anchors.horizontalCenter: parent.horizontalCenter
+ color: Config.secondaryColor
+ }
+
+ ColumnLayout {
+ spacing: 0
+ TextField {
+ id: urlText
+ leftPadding: 15
+ verticalAlignment: TextInput.AlignVCenter
+ font.pixelSize: 16
+ placeholderText: qsTr("URL:")
+ placeholderTextColor: Config.secondaryColor
+ color: Config.secondaryColor
+ text: "https://download.qt.io/learning/videos/media-player-example/Qt_LogoMergeEffect.mp4"
+
+ Layout.preferredHeight: 40
+ Layout.preferredWidth: 440
+
+ background: Rectangle {
+ color: Config.mainColor
+ border.color: urlPopup.borderColor
+ }
+ }
+
+ Rectangle {
+ id: errorMsg
+ visible: false
+ color: "#FF3A3A"
+
+ Layout.minimumHeight: 40
+ Layout.minimumWidth: 130
+ Layout.alignment: Qt.AlignLeft
+
+ Row {
+ anchors.centerIn: parent
+ spacing: 10
+
+ Image {
+ source: Config.iconSource("Warning_Icon", false)
+ }
+
+ Label {
+ text: qsTr("Wrong URL")
+ font.pixelSize: 16
+ color: "white"
+ }
+ }
+
+ onVisibleChanged: showError.start()
+
+ NumberAnimation {
+ id: showError
+ target: errorMsg
+ properties: "opacity"
+ from: 0
+ to: 1
+ duration: 1000
+ }
+ }
+ }
+
+
+ RowLayout {
+ spacing: 20
+ anchors.horizontalCenter: parent.horizontalCenter
+
+ CustomButton {
+ icon.source: Config.iconSource("Cancel_Button", false)
+ onClicked: {
+ urlText.text = ""
+ urlPopup.close()
+ }
+ }
+
+ CustomButton {
+ icon.source: Config.iconSource("Load_Button", false)
+ enabled: urlText.text
+ opacity: urlText.text ? 1 : 0.5
+ onClicked: {
+ if (urlPopup.validateUrl(urlText.text)) {
+ urlPopup.setUrl(new URL(urlText.text))
+ } else {
+ errorMsg.visible = true
+ }
+ }
+ }
+ }
+ }
+ onOpened: urlPopup.forceActiveFocus()
+ onClosed: {
+ urlText.text = ""
+ errorMsg.visible = false
+ }
+}
diff --git a/examples/demos/mediaplayer/doc/images/mediaplayer.png b/examples/demos/mediaplayer/doc/images/mediaplayer.png
new file mode 100644
index 000000000..649d421df
--- /dev/null
+++ b/examples/demos/mediaplayer/doc/images/mediaplayer.png
Binary files differ
diff --git a/examples/demos/mediaplayer/doc/src/mediaplayer.qdoc b/examples/demos/mediaplayer/doc/src/mediaplayer.qdoc
new file mode 100644
index 000000000..410fddd9e
--- /dev/null
+++ b/examples/demos/mediaplayer/doc/src/mediaplayer.qdoc
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
+
+/*!
+ \example video/mediaplayer
+ \title Media Player Example
+ \ingroup multimedia_examples
+ \ingroup video_examples_qml
+ \example demos/mediaplayer
+ \brief Playing audio and video using Qt Quick.
+ \meta {tag} {quick,player,multimedia}
+ \image mediaplayer.jpg
+
+ This example demonstrates a simple multimedia player that can play
+ audio and video files using various codecs.
+
+ \include examples-run.qdocinc
+
+ \section1 Overview
+ At its core this is a QML application, see
+ \l{Getting Started Programming with Qt Quick} for information specific to
+ that. This documentation is focused on how this example utilizes the
+ \l{Qt Multimedia QML types}.
+
+*/
diff --git a/examples/demos/mediaplayer/icons/Add_file.svg b/examples/demos/mediaplayer/icons/Add_file.svg
new file mode 100644
index 000000000..4e5cb5e10
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Add_file.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M8.5 13.5H9.5V9.5H13.5V8.5H9.5V4.5H8.5V8.5H4.5V9.5H8.5V13.5ZM9 18C7.75 18 6.57933 17.7627 5.488 17.288C4.396 16.8127 3.446 16.1707 2.638 15.362C1.82933 14.554 1.18733 13.604 0.712 12.512C0.237333 11.4207 0 10.25 0 9C0 7.75 0.237333 6.579 0.712 5.487C1.18733 4.39567 1.82933 3.44567 2.638 2.637C3.446 1.829 4.396 1.18733 5.488 0.712C6.57933 0.237333 7.75 0 9 0C10.25 0 11.421 0.237333 12.513 0.712C13.6043 1.18733 14.5543 1.829 15.363 2.637C16.171 3.44567 16.8127 4.39567 17.288 5.487C17.7627 6.579 18 7.75 18 9C18 10.25 17.7627 11.4207 17.288 12.512C16.8127 13.604 16.171 14.554 15.363 15.362C14.5543 16.1707 13.6043 16.8127 12.513 17.288C11.421 17.7627 10.25 18 9 18ZM9 17C11.2333 17 13.125 16.225 14.675 14.675C16.225 13.125 17 11.2333 17 9C17 6.76667 16.225 4.875 14.675 3.325C13.125 1.775 11.2333 1 9 1C6.76667 1 4.875 1.775 3.325 3.325C1.775 4.875 1 6.76667 1 9C1 11.2333 1.775 13.125 3.325 14.675C4.875 16.225 6.76667 17 9 17Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Add_file_Dark.svg b/examples/demos/mediaplayer/icons/Add_file_Dark.svg
new file mode 100644
index 000000000..492763884
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Add_file_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M8.5 13.5H9.5V9.5H13.5V8.5H9.5V4.5H8.5V8.5H4.5V9.5H8.5V13.5ZM9 18C7.75 18 6.57933 17.7627 5.488 17.288C4.396 16.8127 3.446 16.1707 2.638 15.362C1.82933 14.554 1.18733 13.604 0.712 12.512C0.237333 11.4207 0 10.25 0 9C0 7.75 0.237333 6.579 0.712 5.487C1.18733 4.39567 1.82933 3.44567 2.638 2.637C3.446 1.829 4.396 1.18733 5.488 0.712C6.57933 0.237333 7.75 0 9 0C10.25 0 11.421 0.237333 12.513 0.712C13.6043 1.18733 14.5543 1.829 15.363 2.637C16.171 3.44567 16.8127 4.39567 17.288 5.487C17.7627 6.579 18 7.75 18 9C18 10.25 17.7627 11.4207 17.288 12.512C16.8127 13.604 16.171 14.554 15.363 15.362C14.5543 16.1707 13.6043 16.8127 12.513 17.288C11.421 17.7627 10.25 18 9 18ZM9 17C11.2333 17 13.125 16.225 14.675 14.675C16.225 13.125 17 11.2333 17 9C17 6.76667 16.225 4.875 14.675 3.325C13.125 1.775 11.2333 1 9 1C6.76667 1 4.875 1.775 3.325 3.325C1.775 4.875 1 6.76667 1 9C1 11.2333 1.775 13.125 3.325 14.675C4.875 16.225 6.76667 17 9 17Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Cancel_Button.svg b/examples/demos/mediaplayer/icons/Cancel_Button.svg
new file mode 100644
index 000000000..6d0b0374d
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Cancel_Button.svg
@@ -0,0 +1,4 @@
+<svg width="150" height="40" viewBox="0 0 150 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0.5 10.2071L10.2071 0.5H149.5V29.7929L139.793 39.5H0.5V10.2071Z" stroke="#41CD52"/>
+<path d="M58.0795 25.78C56.7062 26.06 55.4729 26.2 54.3795 26.2C53.2862 26.2 52.3995 26.0533 51.7195 25.76C51.0529 25.4533 50.5329 24.9867 50.1595 24.36C49.7995 23.72 49.5462 22.9933 49.3995 22.18C49.2662 21.3533 49.1995 20.3267 49.1995 19.1C49.1995 17.8733 49.2662 16.8467 49.3995 16.02C49.5462 15.18 49.7995 14.44 50.1595 13.8C50.5329 13.16 51.0529 12.6933 51.7195 12.4C52.3862 12.1067 53.2529 11.96 54.3195 11.96C55.3862 11.96 56.6395 12.1067 58.0795 12.4L58.0195 13.7C56.6729 13.46 55.4729 13.34 54.4195 13.34C52.9529 13.34 51.9795 13.78 51.4995 14.66C51.0329 15.5267 50.7995 17.0133 50.7995 19.12C50.7995 20.1733 50.8395 21.02 50.9195 21.66C51.0129 22.3 51.1862 22.88 51.4395 23.4C51.6929 23.9067 52.0595 24.2733 52.5395 24.5C53.0329 24.7133 53.7462 24.82 54.6795 24.82C55.6262 24.82 56.7395 24.7 58.0195 24.46L58.0795 25.78ZM67.3984 19.02V24.14C67.4384 24.6333 67.8251 24.9267 68.5584 25.02L68.4984 26.2C67.4451 26.2 66.6518 25.9333 66.1184 25.4C64.9184 25.9333 63.7184 26.2 62.5184 26.2C61.5984 26.2 60.8984 25.94 60.4184 25.42C59.9384 24.9 59.6984 24.1533 59.6984 23.18C59.6984 22.2067 59.9451 21.4933 60.4384 21.04C60.9318 20.5733 61.7051 20.2867 62.7584 20.18L65.8984 19.88V19.02C65.8984 18.34 65.7518 17.8533 65.4584 17.56C65.1651 17.2667 64.7651 17.12 64.2584 17.12C63.1918 17.12 62.0851 17.1867 60.9384 17.32L60.3184 17.38L60.2584 16.24C61.7251 15.9467 63.0251 15.8 64.1584 15.8C65.2918 15.8 66.1118 16.06 66.6184 16.58C67.1384 17.1 67.3984 17.9133 67.3984 19.02ZM61.2384 23.1C61.2384 24.3267 61.7451 24.94 62.7584 24.94C63.6651 24.94 64.5584 24.7867 65.4384 24.48L65.8984 24.32V21.02L62.9384 21.3C62.3384 21.3533 61.9051 21.5267 61.6384 21.82C61.3718 22.1133 61.2384 22.54 61.2384 23.1ZM71.858 26H70.358V16H71.838V16.7C72.918 16.1 73.9513 15.8 74.938 15.8C76.2713 15.8 77.1646 16.16 77.618 16.88C78.0846 17.6 78.318 18.88 78.318 20.72V26H76.838V20.76C76.838 19.3733 76.698 18.4267 76.418 17.92C76.1513 17.4 75.5713 17.14 74.678 17.14C74.2513 17.14 73.798 17.2067 73.318 17.34C72.8513 17.46 72.4913 17.58 72.238 17.7L71.858 17.88V26ZM84.8402 15.8C85.2802 15.8 86.0268 15.88 87.0802 16.04L87.5602 16.1L87.5002 17.32C86.4335 17.2 85.6468 17.14 85.1402 17.14C84.0068 17.14 83.2335 17.4133 82.8202 17.96C82.4202 18.4933 82.2202 19.4933 82.2202 20.96C82.2202 22.4133 82.4068 23.4267 82.7802 24C83.1668 24.5733 83.9602 24.86 85.1602 24.86L87.5202 24.68L87.5802 25.92C86.3402 26.1067 85.4135 26.2 84.8002 26.2C83.2402 26.2 82.1602 25.8 81.5602 25C80.9735 24.2 80.6802 22.8533 80.6802 20.96C80.6802 19.0533 81.0002 17.72 81.6402 16.96C82.2802 16.1867 83.3468 15.8 84.8402 15.8ZM96.4939 24.76L97.0739 24.7L97.1139 25.88C95.5939 26.0933 94.2939 26.2 93.2139 26.2C91.7739 26.2 90.7539 25.7867 90.1539 24.96C89.5539 24.12 89.2539 22.82 89.2539 21.06C89.2539 17.5533 90.6472 15.8 93.4339 15.8C94.7806 15.8 95.7872 16.18 96.4539 16.94C97.1206 17.6867 97.4539 18.8667 97.4539 20.48L97.3739 21.62H90.7739C90.7739 22.7267 90.9739 23.5467 91.3739 24.08C91.7739 24.6133 92.4672 24.88 93.4539 24.88C94.4539 24.88 95.4672 24.84 96.4939 24.76ZM95.9539 20.42C95.9539 19.1933 95.7539 18.3267 95.3539 17.82C94.9672 17.3133 94.3272 17.06 93.4339 17.06C92.5539 17.06 91.8872 17.3267 91.4339 17.86C90.9939 18.3933 90.7672 19.2467 90.7539 20.42H95.9539ZM99.9116 26V11.64H101.412V26H99.9116Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Default_CoverArt.svg b/examples/demos/mediaplayer/icons/Default_CoverArt.svg
new file mode 100644
index 000000000..ae10ae9cc
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Default_CoverArt.svg
@@ -0,0 +1,29 @@
+<svg width="612" height="612" viewBox="0 0 612 612" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_d_378_616)">
+<rect x="50" y="10" width="512" height="512" rx="20" fill="#41CD52"/>
+<rect x="50" y="10" width="512" height="512" rx="20" fill="url(#paint0_linear_378_616)" fill-opacity="0.2"/>
+<rect x="50" y="10" width="512" height="512" rx="20" fill="url(#paint1_linear_378_616)" fill-opacity="0.2"/>
+</g>
+<path opacity="0.2" d="M214.385 354.782C221.966 362.261 230.991 366 241.462 366C252.145 366 261.226 362.261 268.705 354.782C276.184 347.303 279.923 338.222 279.923 327.538V198.372H395.307V299.654C392.102 296.235 388.256 293.615 383.769 291.795C379.282 289.983 374.581 289.077 369.666 289.077C359.196 289.077 350.17 292.872 342.589 300.462C335 308.043 331.205 317.068 331.205 327.538C331.205 338.222 335 347.303 342.589 354.782C350.17 362.261 359.196 366 369.666 366C380.35 366 389.431 362.261 396.91 354.782C404.388 347.303 408.128 338.222 408.128 327.538V166H267.103V299.654C263.897 296.235 260.051 293.615 255.564 291.795C251.077 289.983 246.376 289.077 241.462 289.077C230.991 289.077 221.966 292.872 214.385 300.462C206.795 308.043 203 317.068 203 327.538C203 338.222 206.795 347.303 214.385 354.782Z" fill="white"/>
+<defs>
+<filter id="filter0_d_378_616" x="0" y="0" width="612" height="612" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feMorphology radius="10" operator="erode" in="SourceAlpha" result="effect1_dropShadow_378_616"/>
+<feOffset dy="40"/>
+<feGaussianBlur stdDeviation="30"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.254902 0 0 0 0 0.803922 0 0 0 0 0.321569 0 0 0 0.25 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_378_616"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_378_616" result="shape"/>
+</filter>
+<linearGradient id="paint0_linear_378_616" x1="58.5" y1="16" x2="562" y2="515.5" gradientUnits="userSpaceOnUse">
+<stop stop-opacity="0"/>
+<stop offset="1"/>
+</linearGradient>
+<linearGradient id="paint1_linear_378_616" x1="56.5" y1="10" x2="562" y2="514.5" gradientUnits="userSpaceOnUse">
+<stop stop-color="white"/>
+<stop offset="0.519416" stop-color="white" stop-opacity="0"/>
+</linearGradient>
+</defs>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Error.svg b/examples/demos/mediaplayer/icons/Error.svg
new file mode 100644
index 000000000..646144ea1
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Error.svg
@@ -0,0 +1,3 @@
+<svg width="42" height="35" viewBox="0 0 42 35" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0.730957 34.9998L21.0001 0L41.2692 34.9998H0.730957ZM4.66161 32.7306H37.3385L21.0001 4.53835L4.66161 32.7306ZM21.1515 29.7268C21.5082 29.7268 21.8042 29.6061 22.0395 29.3647C22.2747 29.1234 22.3924 28.8244 22.3924 28.4677C22.3924 28.1109 22.2717 27.8149 22.0304 27.5797C21.789 27.3444 21.49 27.2268 21.1333 27.2268C20.7765 27.2268 20.4805 27.3475 20.2453 27.5888C20.01 27.8301 19.8924 28.1291 19.8924 28.4858C19.8924 28.8426 20.013 29.1386 20.2544 29.3738C20.4957 29.6091 20.7947 29.7268 21.1515 29.7268ZM20.0078 24.8307H22.277V13.9383H20.0078V24.8307Z" fill="#FFE353"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/FullScreen_Icon.svg b/examples/demos/mediaplayer/icons/FullScreen_Icon.svg
new file mode 100644
index 000000000..7550bac0b
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/FullScreen_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 14V9H1V13H5V14H0ZM0 5V0H5V1H1V5H0ZM9 14V13H13V9H14V14H9ZM13 5V1H9V0H14V5H13Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/FullScreen_Icon_Dark.svg b/examples/demos/mediaplayer/icons/FullScreen_Icon_Dark.svg
new file mode 100644
index 000000000..7c8c6e9ab
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/FullScreen_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 14V9H1V13H5V14H0ZM0 5V0H5V1H1V5H0ZM9 14V13H13V9H14V14H9ZM13 5V1H9V0H14V5H13Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Load_Button.svg b/examples/demos/mediaplayer/icons/Load_Button.svg
new file mode 100644
index 000000000..22c1048ad
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Load_Button.svg
@@ -0,0 +1,18 @@
+<svg width="150" height="40" viewBox="0 0 150 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g filter="url(#filter0_d_378_942)">
+<path d="M10 0H150V30L140 40H0V10L10 0Z" fill="#41CD52"/>
+</g>
+<path d="M64.4977 26H56.8777V12.16H58.4177V24.62H64.4977V26ZM65.6504 20.98C65.6504 19.1533 65.9771 17.8333 66.6304 17.02C67.2837 16.2067 68.3837 15.8 69.9304 15.8C71.4904 15.8 72.5904 16.2067 73.2304 17.02C73.8837 17.8333 74.2104 19.1533 74.2104 20.98C74.2104 22.8067 73.9037 24.1333 73.2904 24.96C72.6771 25.7867 71.5571 26.2 69.9304 26.2C68.3037 26.2 67.1837 25.7867 66.5704 24.96C65.9571 24.1333 65.6504 22.8067 65.6504 20.98ZM67.1904 20.96C67.1904 22.4133 67.3637 23.4333 67.7104 24.02C68.0704 24.6067 68.8104 24.9 69.9304 24.9C71.0637 24.9 71.8037 24.6133 72.1504 24.04C72.4971 23.4533 72.6704 22.4267 72.6704 20.96C72.6704 19.4933 72.4771 18.4867 72.0904 17.94C71.7037 17.38 70.9837 17.1 69.9304 17.1C68.8904 17.1 68.1704 17.38 67.7704 17.94C67.3837 18.4867 67.1904 19.4933 67.1904 20.96ZM83.7168 19.02V24.14C83.7568 24.6333 84.1435 24.9267 84.8768 25.02L84.8168 26.2C83.7635 26.2 82.9701 25.9333 82.4368 25.4C81.2368 25.9333 80.0368 26.2 78.8368 26.2C77.9168 26.2 77.2168 25.94 76.7368 25.42C76.2568 24.9 76.0168 24.1533 76.0168 23.18C76.0168 22.2067 76.2635 21.4933 76.7568 21.04C77.2501 20.5733 78.0235 20.2867 79.0768 20.18L82.2168 19.88V19.02C82.2168 18.34 82.0701 17.8533 81.7768 17.56C81.4835 17.2667 81.0835 17.12 80.5768 17.12C79.5101 17.12 78.4035 17.1867 77.2568 17.32L76.6368 17.38L76.5768 16.24C78.0435 15.9467 79.3435 15.8 80.4768 15.8C81.6101 15.8 82.4301 16.06 82.9368 16.58C83.4568 17.1 83.7168 17.9133 83.7168 19.02ZM77.5568 23.1C77.5568 24.3267 78.0635 24.94 79.0768 24.94C79.9835 24.94 80.8768 24.7867 81.7568 24.48L82.2168 24.32V21.02L79.2568 21.3C78.6568 21.3533 78.2235 21.5267 77.9568 21.82C77.6901 22.1133 77.5568 22.54 77.5568 23.1ZM94.3563 11.64V26H92.8763V25.32C91.8497 25.9067 90.8363 26.2 89.8363 26.2C89.303 26.2 88.8363 26.1333 88.4363 26C88.0363 25.8667 87.663 25.6267 87.3163 25.28C86.5963 24.56 86.2363 23.2333 86.2363 21.3C86.2363 19.3533 86.5563 17.9533 87.1963 17.1C87.8497 16.2333 88.923 15.8 90.4163 15.8C91.1897 15.8 92.0097 15.8867 92.8763 16.06V11.64H94.3563ZM88.4763 24.2C88.6897 24.4533 88.9163 24.6267 89.1563 24.72C89.3963 24.8133 89.703 24.86 90.0763 24.86C90.463 24.86 90.8897 24.8 91.3563 24.68C91.8363 24.5467 92.2097 24.42 92.4763 24.3L92.8763 24.12V17.34C92.023 17.18 91.2297 17.1 90.4963 17.1C89.483 17.1 88.7763 17.4267 88.3763 18.08C87.9763 18.72 87.7763 19.72 87.7763 21.08C87.7763 22.6267 88.0097 23.6667 88.4763 24.2Z" fill="white"/>
+<defs>
+<filter id="filter0_d_378_942" x="-10" y="-2" width="170" height="60" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
+<feFlood flood-opacity="0" result="BackgroundImageFix"/>
+<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"/>
+<feOffset dy="8"/>
+<feGaussianBlur stdDeviation="5"/>
+<feComposite in2="hardAlpha" operator="out"/>
+<feColorMatrix type="matrix" values="0 0 0 0 0.254902 0 0 0 0 0.803922 0 0 0 0 0.321569 0 0 0 0.2 0"/>
+<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_378_942"/>
+<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_378_942" result="shape"/>
+</filter>
+</defs>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Loop_Icon.svg b/examples/demos/mediaplayer/icons/Loop_Icon.svg
new file mode 100644
index 000000000..ba70a660a
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Loop_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12 35.208L6.45801 29.667L12 24.167L13 25.208L9.20801 28.958H29.083V22.292H30.5V30.375H9.20801L13 34.167L12 35.208ZM9.50001 17.708V9.62499H30.792L27 5.83299L28 4.79199L33.542 10.333L28 15.833L27 14.792L30.792 11.042H10.917V17.708H9.50001Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Loop_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Loop_Icon_Dark.svg
new file mode 100644
index 000000000..ae7b38ea4
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Loop_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12 35.208L6.45801 29.667L12 24.167L13 25.208L9.20801 28.958H29.083V22.292H30.5V30.375H9.20801L13 34.167L12 35.208ZM9.50001 17.708V9.62499H30.792L27 5.83299L28 4.79199L33.542 10.333L28 15.833L27 14.792L30.792 11.042H10.917V17.708H9.50001Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Loop_Playlist.svg b/examples/demos/mediaplayer/icons/Loop_Playlist.svg
new file mode 100644
index 000000000..24be50541
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Loop_Playlist.svg
@@ -0,0 +1,6 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12 35.208L6.45801 29.667L12 24.167L13 25.208L9.20801 28.958H29.083V22.292H30.5V30.375H9.20801L13 34.167L12 35.208ZM9.50001 17.708V9.62499H30.792L27 5.83299L28 4.79199L33.542 10.333L28 15.833L27 14.792L30.792 11.042H10.917V17.708H9.50001Z" fill="#41CD52"/>
+<path d="M15 15.5H25" stroke="#41CD52" stroke-width="1.5"/>
+<path d="M15 20H25" stroke="#41CD52" stroke-width="1.5"/>
+<path d="M15 24.5H25" stroke="#41CD52" stroke-width="1.5"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Menu_Icon.svg b/examples/demos/mediaplayer/icons/Menu_Icon.svg
new file mode 100644
index 000000000..3d2785216
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Menu_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.5 17.2751V16.2751H20.5V17.2751H3.5ZM3.5 12.5001V11.5001H20.5V12.5001H3.5ZM3.5 7.7251V6.7251H20.5V7.7251H3.5Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Menu_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Menu_Icon_Dark.svg
new file mode 100644
index 000000000..47e4c84b4
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Menu_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M3.5 17.2751V16.2751H20.5V17.2751H3.5ZM3.5 12.5001V11.5001H20.5V12.5001H3.5ZM3.5 7.7251V6.7251H20.5V7.7251H3.5Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Movie_Active.svg b/examples/demos/mediaplayer/icons/Movie_Active.svg
new file mode 100644
index 000000000..017aad4a5
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Movie_Active.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M6.125 8L4.625 5C4.15833 5 3.771 5.15433 3.463 5.463C3.15433 5.771 3 6.15833 3 6.625V17.375C3 17.8417 3.15433 18.2293 3.463 18.538C3.771 18.846 4.15833 19 4.625 19H15C15 18.6575 15.0344 18.3231 15.1 18H4.625C4.44167 18 4.29167 17.9417 4.175 17.825C4.05833 17.7083 4 17.5583 4 17.375V9H20V14C20.3425 14 20.6769 14.0344 21 14.1V6.625C21 6.15833 20.846 5.771 20.538 5.463C20.2293 5.15433 19.8417 5 19.375 5H17.625L19.125 8H16.125L14.625 5H12.625L14.125 8H11.125L9.625 5H7.625L9.125 8H6.125Z" fill="#41CD52"/>
+<path d="M23 19L18 16V22L23 19Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Movie_Icon.svg b/examples/demos/mediaplayer/icons/Movie_Icon.svg
new file mode 100644
index 000000000..02032e29d
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Movie_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.625 5L6.125 8H9.125L7.625 5H9.625L11.125 8H14.125L12.625 5H14.625L16.125 8H19.125L17.625 5H19.375C19.8417 5 20.2293 5.15433 20.538 5.463C20.846 5.771 21 6.15833 21 6.625V17.375C21 17.8417 20.846 18.2293 20.538 18.538C20.2293 18.846 19.8417 19 19.375 19H4.625C4.15833 19 3.771 18.846 3.463 18.538C3.15433 18.2293 3 17.8417 3 17.375V6.625C3 6.15833 3.15433 5.771 3.463 5.463C3.771 5.15433 4.15833 5 4.625 5ZM4 9V17.375C4 17.5583 4.05833 17.7083 4.175 17.825C4.29167 17.9417 4.44167 18 4.625 18H19.375C19.5583 18 19.7083 17.9417 19.825 17.825C19.9417 17.7083 20 17.5583 20 17.375V9H4ZM4 9V18V17.375V9Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Movie_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Movie_Icon_Dark.svg
new file mode 100644
index 000000000..65e9f01a0
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Movie_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.625 5L6.125 8H9.125L7.625 5H9.625L11.125 8H14.125L12.625 5H14.625L16.125 8H19.125L17.625 5H19.375C19.8417 5 20.2293 5.15433 20.538 5.463C20.846 5.771 21 6.15833 21 6.625V17.375C21 17.8417 20.846 18.2293 20.538 18.538C20.2293 18.846 19.8417 19 19.375 19H4.625C4.15833 19 3.771 18.846 3.463 18.538C3.15433 18.2293 3 17.8417 3 17.375V6.625C3 6.15833 3.15433 5.771 3.463 5.463C3.771 5.15433 4.15833 5 4.625 5ZM4 9V17.375C4 17.5583 4.05833 17.7083 4.175 17.825C4.29167 17.9417 4.44167 18 4.625 18H19.375C19.5583 18 19.7083 17.9417 19.825 17.825C19.9417 17.7083 20 17.5583 20 17.375V9H4ZM4 9V18V17.375V9Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Music_Active.svg b/examples/demos/mediaplayer/icons/Music_Active.svg
new file mode 100644
index 000000000..b7fc0845e
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Music_Active.svg
@@ -0,0 +1,4 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path fill-rule="evenodd" clip-rule="evenodd" d="M7 19.8002C6.18333 19.8002 5.47933 19.5085 4.888 18.9252C4.296 18.3419 4 17.6335 4 16.8002C4 15.9835 4.296 15.2795 4.888 14.6882C5.47933 14.0962 6.18333 13.8002 7 13.8002C7.38333 13.8002 7.75 13.8709 8.1 14.0122C8.45 14.1542 8.75 14.3585 9 14.6252V4.2002H20V14C19.6575 14 19.3231 14.0344 19 14.1V6.7252H10V16.8002C10 17.6335 9.70833 18.3419 9.125 18.9252C8.54167 19.5085 7.83333 19.8002 7 19.8002ZM18.5148 14.2243C18.3853 14.1426 18.2471 14.0719 18.1 14.0122C17.75 13.8709 17.3833 13.8002 17 13.8002C16.1833 13.8002 15.4793 14.0962 14.888 14.6882C14.296 15.2795 14 15.9835 14 16.8002C14 17.6335 14.296 18.3419 14.888 18.9252C14.9249 18.9616 14.9623 18.9969 15.0001 19.0311C15 19.0207 15 19.0104 15 19C15 16.7557 16.4786 14.8568 18.5148 14.2243Z" fill="#41CD52"/>
+<path d="M23 19L18 16V22L23 19Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Music_Icon.svg b/examples/demos/mediaplayer/icons/Music_Icon.svg
new file mode 100644
index 000000000..31e0e3644
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Music_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.888 18.9252C5.47933 19.5085 6.18333 19.8002 7 19.8002C7.83333 19.8002 8.54167 19.5085 9.125 18.9252C9.70833 18.3419 10 17.6335 10 16.8002V6.7252H19V14.6252C18.75 14.3585 18.45 14.1542 18.1 14.0122C17.75 13.8709 17.3833 13.8002 17 13.8002C16.1833 13.8002 15.4793 14.0962 14.888 14.6882C14.296 15.2795 14 15.9835 14 16.8002C14 17.6335 14.296 18.3419 14.888 18.9252C15.4793 19.5085 16.1833 19.8002 17 19.8002C17.8333 19.8002 18.5416 19.5085 19.125 18.9252C19.7083 18.3419 20 17.6335 20 16.8002V4.2002H9V14.6252C8.75 14.3585 8.45 14.1542 8.1 14.0122C7.75 13.8709 7.38333 13.8002 7 13.8002C6.18333 13.8002 5.47933 14.0962 4.888 14.6882C4.296 15.2795 4 15.9835 4 16.8002C4 17.6335 4.296 18.3419 4.888 18.9252Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Music_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Music_Icon_Dark.svg
new file mode 100644
index 000000000..c0b517dd1
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Music_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M4.888 18.9252C5.47933 19.5085 6.18333 19.8002 7 19.8002C7.83333 19.8002 8.54167 19.5085 9.125 18.9252C9.70833 18.3419 10 17.6335 10 16.8002V6.7252H19V14.6252C18.75 14.3585 18.45 14.1542 18.1 14.0122C17.75 13.8709 17.3833 13.8002 17 13.8002C16.1833 13.8002 15.4793 14.0962 14.888 14.6882C14.296 15.2795 14 15.9835 14 16.8002C14 17.6335 14.296 18.3419 14.888 18.9252C15.4793 19.5085 16.1833 19.8002 17 19.8002C17.8333 19.8002 18.5416 19.5085 19.125 18.9252C19.7083 18.3419 20 17.6335 20 16.8002V4.2002H9V14.6252C8.75 14.3585 8.45 14.1542 8.1 14.0122C7.75 13.8709 7.38333 13.8002 7 13.8002C6.18333 13.8002 5.47933 14.0962 4.888 14.6882C4.296 15.2795 4 15.9835 4 16.8002C4 17.6335 4.296 18.3419 4.888 18.9252Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Mute_Icon.svg b/examples/demos/mediaplayer/icons/Mute_Icon.svg
new file mode 100644
index 000000000..4a6a4ca42
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Mute_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="7" height="12" viewBox="0 0 7 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 7.9998V3.9998H3.425L7 0.424805V11.5748L3.425 7.9998H0ZM1 6.9998H3.85L6 9.1498V2.8498L3.85 4.9998H1V6.9998Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Mute_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Mute_Icon_Dark.svg
new file mode 100644
index 000000000..57f0d7263
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Mute_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="7" height="12" viewBox="0 0 7 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 7.9998V3.9998H3.425L7 0.424805V11.5748L3.425 7.9998H0ZM1 6.9998H3.85L6 9.1498V2.8498L3.85 4.9998H1V6.9998Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Next_Icon.svg b/examples/demos/mediaplayer/icons/Next_Icon.svg
new file mode 100644
index 000000000..4eaf0ced6
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Next_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M16.375 15.708V0.291992H17.792V15.708H16.375ZM0.208008 15.708V0.291992L11.583 7.99999L0.208008 15.708ZM1.62501 13.042L9.08301 7.99999L1.62501 2.95799V13.042Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Next_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Next_Icon_Dark.svg
new file mode 100644
index 000000000..e7c64346d
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Next_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M16.375 15.708V0.291992H17.792V15.708H16.375ZM0.208008 15.708V0.291992L11.583 7.99999L0.208008 15.708ZM1.62501 13.042L9.08301 7.99999L1.62501 2.95799V13.042Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Play_Icon.svg b/examples/demos/mediaplayer/icons/Play_Icon.svg
new file mode 100644
index 000000000..7361042a7
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Play_Icon.svg
@@ -0,0 +1,4 @@
+<svg width="52" height="52" viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="26" cy="26" r="26" fill="#41CD52"/>
+<path d="M21 34.625V17.292L34.583 25.958L21 34.625ZM22.417 32L32 25.958L22.417 19.917V32Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Playlist_Active.svg b/examples/demos/mediaplayer/icons/Playlist_Active.svg
new file mode 100644
index 000000000..c7ef7c489
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Playlist_Active.svg
@@ -0,0 +1,3 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.29199 21.5C7.59733 21.5 7.86099 21.389 8.08299 21.167C8.30566 20.9443 8.41699 20.6663 8.41699 20.333C8.41699 19.9997 8.30566 19.722 8.08299 19.5C7.86099 19.278 7.58333 19.167 7.24999 19.167C6.94466 19.167 6.68066 19.278 6.45799 19.5C6.23599 19.722 6.12499 19.9997 6.12499 20.333C6.12499 20.6663 6.23599 20.9443 6.45799 21.167C6.68066 21.389 6.95866 21.5 7.29199 21.5ZM7.29199 15.167C7.59733 15.167 7.86099 15.0557 8.08299 14.833C8.30566 14.611 8.41699 14.3333 8.41699 14C8.41699 13.6667 8.30566 13.389 8.08299 13.167C7.86099 12.9443 7.58333 12.833 7.24999 12.833C6.94466 12.833 6.68066 12.9443 6.45799 13.167C6.23599 13.389 6.12499 13.6667 6.12499 14C6.12499 14.3333 6.23599 14.611 6.45799 14.833C6.68066 15.0557 6.95866 15.167 7.29199 15.167ZM7.29199 8.83299C7.59733 8.83299 7.86099 8.72199 8.08299 8.49999C8.30566 8.27799 8.41699 8.00033 8.41699 7.66699C8.41699 7.33366 8.30566 7.05566 8.08299 6.83299C7.86099 6.61099 7.58333 6.49999 7.24999 6.49999C6.94466 6.49999 6.68066 6.61099 6.45799 6.83299C6.23599 7.05566 6.12499 7.33366 6.12499 7.66699C6.12499 8.00033 6.23599 8.27799 6.45799 8.49999C6.68066 8.72199 6.95866 8.83299 7.29199 8.83299ZM12.542 21.042H21.583V19.625H12.542V21.042ZM12.542 14.708H21.583V13.292H12.542V14.708ZM12.542 8.37499H21.583V6.95799H12.542V8.37499ZM3.08299 27.333C2.41633 27.333 1.84699 27.097 1.37499 26.625C0.902992 26.153 0.666992 25.5837 0.666992 24.917V3.08299C0.666992 2.41633 0.902992 1.84699 1.37499 1.37499C1.84699 0.902992 2.41633 0.666992 3.08299 0.666992H24.917C25.5837 0.666992 26.153 0.902992 26.625 1.37499C27.097 1.84699 27.333 2.41633 27.333 3.08299V24.917C27.333 25.5837 27.097 26.153 26.625 26.625C26.153 27.097 25.5837 27.333 24.917 27.333H3.08299ZM3.08299 25.917H24.917C25.167 25.917 25.396 25.8127 25.604 25.604C25.8127 25.396 25.917 25.167 25.917 24.917V3.08299C25.917 2.83299 25.8127 2.60399 25.604 2.39599C25.396 2.18733 25.167 2.08299 24.917 2.08299H3.08299C2.83299 2.08299 2.60399 2.18733 2.39599 2.39599C2.18733 2.60399 2.08299 2.83299 2.08299 3.08299V24.917C2.08299 25.167 2.18733 25.396 2.39599 25.604C2.60399 25.8127 2.83299 25.917 3.08299 25.917Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Playlist_Icon.svg b/examples/demos/mediaplayer/icons/Playlist_Icon.svg
new file mode 100644
index 000000000..90289a2f0
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Playlist_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.29199 21.5C7.59733 21.5 7.86099 21.389 8.08299 21.167C8.30566 20.9443 8.41699 20.6663 8.41699 20.333C8.41699 19.9997 8.30566 19.722 8.08299 19.5C7.86099 19.278 7.58333 19.167 7.24999 19.167C6.94466 19.167 6.68066 19.278 6.45799 19.5C6.23599 19.722 6.12499 19.9997 6.12499 20.333C6.12499 20.6663 6.23599 20.9443 6.45799 21.167C6.68066 21.389 6.95866 21.5 7.29199 21.5ZM7.29199 15.167C7.59733 15.167 7.86099 15.0557 8.08299 14.833C8.30566 14.611 8.41699 14.3333 8.41699 14C8.41699 13.6667 8.30566 13.389 8.08299 13.167C7.86099 12.9443 7.58333 12.833 7.24999 12.833C6.94466 12.833 6.68066 12.9443 6.45799 13.167C6.23599 13.389 6.12499 13.6667 6.12499 14C6.12499 14.3333 6.23599 14.611 6.45799 14.833C6.68066 15.0557 6.95866 15.167 7.29199 15.167ZM7.29199 8.83299C7.59733 8.83299 7.86099 8.72199 8.08299 8.49999C8.30566 8.27799 8.41699 8.00033 8.41699 7.66699C8.41699 7.33366 8.30566 7.05566 8.08299 6.83299C7.86099 6.61099 7.58333 6.49999 7.24999 6.49999C6.94466 6.49999 6.68066 6.61099 6.45799 6.83299C6.23599 7.05566 6.12499 7.33366 6.12499 7.66699C6.12499 8.00033 6.23599 8.27799 6.45799 8.49999C6.68066 8.72199 6.95866 8.83299 7.29199 8.83299ZM12.542 21.042H21.583V19.625H12.542V21.042ZM12.542 14.708H21.583V13.292H12.542V14.708ZM12.542 8.37499H21.583V6.95799H12.542V8.37499ZM3.08299 27.333C2.41633 27.333 1.84699 27.097 1.37499 26.625C0.902992 26.153 0.666992 25.5837 0.666992 24.917V3.08299C0.666992 2.41633 0.902992 1.84699 1.37499 1.37499C1.84699 0.902992 2.41633 0.666992 3.08299 0.666992H24.917C25.5837 0.666992 26.153 0.902992 26.625 1.37499C27.097 1.84699 27.333 2.41633 27.333 3.08299V24.917C27.333 25.5837 27.097 26.153 26.625 26.625C26.153 27.097 25.5837 27.333 24.917 27.333H3.08299ZM3.08299 25.917H24.917C25.167 25.917 25.396 25.8127 25.604 25.604C25.8127 25.396 25.917 25.167 25.917 24.917V3.08299C25.917 2.83299 25.8127 2.60399 25.604 2.39599C25.396 2.18733 25.167 2.08299 24.917 2.08299H3.08299C2.83299 2.08299 2.60399 2.18733 2.39599 2.39599C2.18733 2.60399 2.08299 2.83299 2.08299 3.08299V24.917C2.08299 25.167 2.18733 25.396 2.39599 25.604C2.60399 25.8127 2.83299 25.917 3.08299 25.917Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Playlist_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Playlist_Icon_Dark.svg
new file mode 100644
index 000000000..e427211dc
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Playlist_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.29199 21.5C7.59733 21.5 7.86099 21.389 8.08299 21.167C8.30566 20.9443 8.41699 20.6663 8.41699 20.333C8.41699 19.9997 8.30566 19.722 8.08299 19.5C7.86099 19.278 7.58333 19.167 7.24999 19.167C6.94466 19.167 6.68066 19.278 6.45799 19.5C6.23599 19.722 6.12499 19.9997 6.12499 20.333C6.12499 20.6663 6.23599 20.9443 6.45799 21.167C6.68066 21.389 6.95866 21.5 7.29199 21.5ZM7.29199 15.167C7.59733 15.167 7.86099 15.0557 8.08299 14.833C8.30566 14.611 8.41699 14.3333 8.41699 14C8.41699 13.6667 8.30566 13.389 8.08299 13.167C7.86099 12.9443 7.58333 12.833 7.24999 12.833C6.94466 12.833 6.68066 12.9443 6.45799 13.167C6.23599 13.389 6.12499 13.6667 6.12499 14C6.12499 14.3333 6.23599 14.611 6.45799 14.833C6.68066 15.0557 6.95866 15.167 7.29199 15.167ZM7.29199 8.83299C7.59733 8.83299 7.86099 8.72199 8.08299 8.49999C8.30566 8.27799 8.41699 8.00033 8.41699 7.66699C8.41699 7.33366 8.30566 7.05566 8.08299 6.83299C7.86099 6.61099 7.58333 6.49999 7.24999 6.49999C6.94466 6.49999 6.68066 6.61099 6.45799 6.83299C6.23599 7.05566 6.12499 7.33366 6.12499 7.66699C6.12499 8.00033 6.23599 8.27799 6.45799 8.49999C6.68066 8.72199 6.95866 8.83299 7.29199 8.83299ZM12.542 21.042H21.583V19.625H12.542V21.042ZM12.542 14.708H21.583V13.292H12.542V14.708ZM12.542 8.37499H21.583V6.95799H12.542V8.37499ZM3.08299 27.333C2.41633 27.333 1.84699 27.097 1.37499 26.625C0.902992 26.153 0.666992 25.5837 0.666992 24.917V3.08299C0.666992 2.41633 0.902992 1.84699 1.37499 1.37499C1.84699 0.902992 2.41633 0.666992 3.08299 0.666992H24.917C25.5837 0.666992 26.153 0.902992 26.625 1.37499C27.097 1.84699 27.333 2.41633 27.333 3.08299V24.917C27.333 25.5837 27.097 26.153 26.625 26.625C26.153 27.097 25.5837 27.333 24.917 27.333H3.08299ZM3.08299 25.917H24.917C25.167 25.917 25.396 25.8127 25.604 25.604C25.8127 25.396 25.917 25.167 25.917 24.917V3.08299C25.917 2.83299 25.8127 2.60399 25.604 2.39599C25.396 2.18733 25.167 2.08299 24.917 2.08299H3.08299C2.83299 2.08299 2.60399 2.18733 2.39599 2.39599C2.18733 2.60399 2.08299 2.83299 2.08299 3.08299V24.917C2.08299 25.167 2.18733 25.396 2.39599 25.604C2.60399 25.8127 2.83299 25.917 3.08299 25.917Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Previous_Icon.svg b/examples/demos/mediaplayer/icons/Previous_Icon.svg
new file mode 100644
index 000000000..6d4cfd050
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Previous_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.62499 0.292006L1.62499 15.708L0.207993 15.708L0.207994 0.292006L1.62499 0.292006ZM17.792 0.292007L17.792 15.708L6.41699 8.00001L17.792 0.292007ZM16.375 2.95801L8.91699 8.00001L16.375 13.042L16.375 2.95801Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Previous_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Previous_Icon_Dark.svg
new file mode 100644
index 000000000..a75f568ec
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Previous_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="16" viewBox="0 0 18 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.62499 0.292006L1.62499 15.708L0.207993 15.708L0.207994 0.292006L1.62499 0.292006ZM17.792 0.292007L17.792 15.708L6.41699 8.00001L17.792 0.292007ZM16.375 2.95801L8.91699 8.00001L16.375 13.042L16.375 2.95801Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Rate_Icon.svg b/examples/demos/mediaplayer/icons/Rate_Icon.svg
new file mode 100644
index 000000000..f87e60974
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Rate_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="14" viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.75 10.2C8.06667 10.5 8.46667 10.6377 8.95 10.613C9.43333 10.5877 9.79167 10.4167 10.025 10.1L15.275 2.775L7.9 7.975C7.56667 8.20833 7.38333 8.55833 7.35 9.025C7.31667 9.49167 7.45 9.88333 7.75 10.2ZM9 0C9.91667 0 10.754 0.112666 11.512 0.338C12.2707 0.562666 13.025 0.9 13.775 1.35L12.85 1.975C12.2667 1.65833 11.6583 1.41667 11.025 1.25C10.3917 1.08333 9.71667 1 9 1C6.78333 1 4.896 1.779 3.338 3.337C1.77933 4.89567 1 6.78333 1 9C1 9.7 1.09567 10.3917 1.287 11.075C1.479 11.7583 1.75 12.4 2.1 13H15.9C16.2833 12.3667 16.5627 11.7083 16.738 11.025C16.9127 10.3417 17 9.63333 17 8.9C17 8.3 16.921 7.66667 16.763 7C16.6043 6.33333 16.3583 5.71667 16.025 5.15L16.65 4.225C17.15 5.05833 17.5 5.84567 17.7 6.587C17.9 7.329 18 8.1 18 8.9C18 9.75 17.904 10.55 17.712 11.3C17.5207 12.05 17.2167 12.8 16.8 13.55C16.7167 13.6833 16.596 13.7917 16.438 13.875C16.2793 13.9583 16.1 14 15.9 14H2.1C1.91667 14 1.746 13.9543 1.588 13.863C1.42933 13.771 1.3 13.6417 1.2 13.475C0.866666 12.8917 0.583333 12.2333 0.35 11.5C0.116667 10.7667 0 9.93333 0 9C0 7.76667 0.233333 6.604 0.7 5.512C1.16667 4.42067 1.80433 3.46667 2.613 2.65C3.421 1.83333 4.375 1.18767 5.475 0.713C6.575 0.237666 7.75 0 9 0Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Rate_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Rate_Icon_Dark.svg
new file mode 100644
index 000000000..723204715
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Rate_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="14" viewBox="0 0 18 14" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.75 10.2C8.06667 10.5 8.46667 10.6377 8.95 10.613C9.43333 10.5877 9.79167 10.4167 10.025 10.1L15.275 2.775L7.9 7.975C7.56667 8.20833 7.38333 8.55833 7.35 9.025C7.31667 9.49167 7.45 9.88333 7.75 10.2ZM9 0C9.91667 0 10.754 0.112666 11.512 0.338C12.2707 0.562666 13.025 0.9 13.775 1.35L12.85 1.975C12.2667 1.65833 11.6583 1.41667 11.025 1.25C10.3917 1.08333 9.71667 1 9 1C6.78333 1 4.896 1.779 3.338 3.337C1.77933 4.89567 1 6.78333 1 9C1 9.7 1.09567 10.3917 1.287 11.075C1.479 11.7583 1.75 12.4 2.1 13H15.9C16.2833 12.3667 16.5627 11.7083 16.738 11.025C16.9127 10.3417 17 9.63333 17 8.9C17 8.3 16.921 7.66667 16.763 7C16.6043 6.33333 16.3583 5.71667 16.025 5.15L16.65 4.225C17.15 5.05833 17.5 5.84567 17.7 6.587C17.9 7.329 18 8.1 18 8.9C18 9.75 17.904 10.55 17.712 11.3C17.5207 12.05 17.2167 12.8 16.8 13.55C16.7167 13.6833 16.596 13.7917 16.438 13.875C16.2793 13.9583 16.1 14 15.9 14H2.1C1.91667 14 1.746 13.9543 1.588 13.863C1.42933 13.771 1.3 13.6417 1.2 13.475C0.866666 12.8917 0.583333 12.2333 0.35 11.5C0.116667 10.7667 0 9.93333 0 9C0 7.76667 0.233333 6.604 0.7 5.512C1.16667 4.42067 1.80433 3.46667 2.613 2.65C3.421 1.83333 4.375 1.18767 5.475 0.713C6.575 0.237666 7.75 0 9 0Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Settings_Icon.svg b/examples/demos/mediaplayer/icons/Settings_Icon.svg
new file mode 100644
index 000000000..57b6b365b
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Settings_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.125 18L6.775 15.1C6.45833 15.0167 6.11267 14.871 5.738 14.663C5.36267 14.4543 5.05 14.2333 4.8 14L2.125 15.125L0.25 11.875L2.575 10.125C2.54167 9.95833 2.51267 9.779 2.488 9.587C2.46267 9.39567 2.45 9.20833 2.45 9.025C2.45 8.85833 2.46267 8.679 2.488 8.487C2.51267 8.29567 2.54167 8.09167 2.575 7.875L0.25 6.125L2.125 2.925L4.775 4.025C5.075 3.775 5.396 3.55 5.738 3.35C6.07933 3.15 6.41667 3 6.75 2.9L7.125 0H10.875L11.225 2.9C11.6083 3.05 11.946 3.20833 12.238 3.375C12.5293 3.54167 12.8333 3.75833 13.15 4.025L15.875 2.925L17.75 6.125L15.35 7.925C15.4167 8.125 15.45 8.31267 15.45 8.488V9C15.45 9.15 15.446 9.31267 15.438 9.488C15.4293 9.66267 15.4 9.875 15.35 10.125L17.7 11.875L15.825 15.125L13.15 13.975C12.8333 14.2417 12.521 14.4667 12.213 14.65C11.9043 14.8333 11.575 14.9833 11.225 15.1L10.875 18H7.125ZM8.975 11.5C9.675 11.5 10.2667 11.2583 10.75 10.775C11.2333 10.2917 11.475 9.7 11.475 9C11.475 8.3 11.2333 7.70833 10.75 7.225C10.2667 6.74167 9.675 6.5 8.975 6.5C8.275 6.5 7.68333 6.74167 7.2 7.225C6.71667 7.70833 6.475 8.3 6.475 9C6.475 9.7 6.71667 10.2917 7.2 10.775C7.68333 11.2583 8.275 11.5 8.975 11.5ZM8.975 10.5C8.55833 10.5 8.20433 10.354 7.913 10.062C7.621 9.77067 7.475 9.41667 7.475 9C7.475 8.58333 7.621 8.22933 7.913 7.938C8.20433 7.646 8.55833 7.5 8.975 7.5C9.39167 7.5 9.746 7.646 10.038 7.938C10.3293 8.22933 10.475 8.58333 10.475 9C10.475 9.41667 10.3293 9.77067 10.038 10.062C9.746 10.354 9.39167 10.5 8.975 10.5ZM8 17H9.95L10.325 14.3C10.825 14.1667 11.2793 13.9833 11.688 13.75C12.096 13.5167 12.5083 13.1917 12.925 12.775L15.4 13.85L16.4 12.15L14.225 10.5C14.3083 10.2167 14.3627 9.954 14.388 9.712C14.4127 9.47067 14.425 9.23333 14.425 9C14.425 8.75 14.4127 8.51233 14.388 8.287C14.3627 8.06233 14.3083 7.80833 14.225 7.525L16.45 5.85L15.45 4.15L12.9 5.225C12.6 4.89167 12.2043 4.579 11.713 4.287C11.221 3.99567 10.75 3.8 10.3 3.7L10 1H8L7.7 3.7C7.2 3.8 6.73733 3.97067 6.312 4.212C5.88733 4.454 5.46667 4.78333 5.05 5.2L2.55 4.15L1.55 5.85L3.725 7.475C3.64167 7.69167 3.58333 7.93333 3.55 8.2C3.51667 8.46667 3.5 8.74167 3.5 9.025C3.5 9.275 3.51667 9.525 3.55 9.775C3.58333 10.025 3.63333 10.2667 3.7 10.5L1.55 12.15L2.55 13.85L5.025 12.8C5.425 13.2 5.83333 13.5167 6.25 13.75C6.66667 13.9833 7.14167 14.1667 7.675 14.3L8 17Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Settings_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Settings_Icon_Dark.svg
new file mode 100644
index 000000000..28aa32a96
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Settings_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="18" height="18" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M7.125 18L6.775 15.1C6.45833 15.0167 6.11267 14.871 5.738 14.663C5.36267 14.4543 5.05 14.2333 4.8 14L2.125 15.125L0.25 11.875L2.575 10.125C2.54167 9.95833 2.51267 9.779 2.488 9.587C2.46267 9.39567 2.45 9.20833 2.45 9.025C2.45 8.85833 2.46267 8.679 2.488 8.487C2.51267 8.29567 2.54167 8.09167 2.575 7.875L0.25 6.125L2.125 2.925L4.775 4.025C5.075 3.775 5.396 3.55 5.738 3.35C6.07933 3.15 6.41667 3 6.75 2.9L7.125 0H10.875L11.225 2.9C11.6083 3.05 11.946 3.20833 12.238 3.375C12.5293 3.54167 12.8333 3.75833 13.15 4.025L15.875 2.925L17.75 6.125L15.35 7.925C15.4167 8.125 15.45 8.31267 15.45 8.488V9C15.45 9.15 15.446 9.31267 15.438 9.488C15.4293 9.66267 15.4 9.875 15.35 10.125L17.7 11.875L15.825 15.125L13.15 13.975C12.8333 14.2417 12.521 14.4667 12.213 14.65C11.9043 14.8333 11.575 14.9833 11.225 15.1L10.875 18H7.125ZM8.975 11.5C9.675 11.5 10.2667 11.2583 10.75 10.775C11.2333 10.2917 11.475 9.7 11.475 9C11.475 8.3 11.2333 7.70833 10.75 7.225C10.2667 6.74167 9.675 6.5 8.975 6.5C8.275 6.5 7.68333 6.74167 7.2 7.225C6.71667 7.70833 6.475 8.3 6.475 9C6.475 9.7 6.71667 10.2917 7.2 10.775C7.68333 11.2583 8.275 11.5 8.975 11.5ZM8.975 10.5C8.55833 10.5 8.20433 10.354 7.913 10.062C7.621 9.77067 7.475 9.41667 7.475 9C7.475 8.58333 7.621 8.22933 7.913 7.938C8.20433 7.646 8.55833 7.5 8.975 7.5C9.39167 7.5 9.746 7.646 10.038 7.938C10.3293 8.22933 10.475 8.58333 10.475 9C10.475 9.41667 10.3293 9.77067 10.038 10.062C9.746 10.354 9.39167 10.5 8.975 10.5ZM8 17H9.95L10.325 14.3C10.825 14.1667 11.2793 13.9833 11.688 13.75C12.096 13.5167 12.5083 13.1917 12.925 12.775L15.4 13.85L16.4 12.15L14.225 10.5C14.3083 10.2167 14.3627 9.954 14.388 9.712C14.4127 9.47067 14.425 9.23333 14.425 9C14.425 8.75 14.4127 8.51233 14.388 8.287C14.3627 8.06233 14.3083 7.80833 14.225 7.525L16.45 5.85L15.45 4.15L12.9 5.225C12.6 4.89167 12.2043 4.579 11.713 4.287C11.221 3.99567 10.75 3.8 10.3 3.7L10 1H8L7.7 3.7C7.2 3.8 6.73733 3.97067 6.312 4.212C5.88733 4.454 5.46667 4.78333 5.05 5.2L2.55 4.15L1.55 5.85L3.725 7.475C3.64167 7.69167 3.58333 7.93333 3.55 8.2C3.51667 8.46667 3.5 8.74167 3.5 9.025C3.5 9.275 3.51667 9.525 3.55 9.775C3.58333 10.025 3.63333 10.2667 3.7 10.5L1.55 12.15L2.55 13.85L5.025 12.8C5.425 13.2 5.83333 13.5167 6.25 13.75C6.66667 13.9833 7.14167 14.1667 7.675 14.3L8 17Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Shadow.png b/examples/demos/mediaplayer/icons/Shadow.png
new file mode 100644
index 000000000..a3678ca60
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Shadow.png
Binary files differ
diff --git a/examples/demos/mediaplayer/icons/Shadow@2x.png b/examples/demos/mediaplayer/icons/Shadow@2x.png
new file mode 100644
index 000000000..a0d490825
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Shadow@2x.png
Binary files differ
diff --git a/examples/demos/mediaplayer/icons/Shuffle_Active.svg b/examples/demos/mediaplayer/icons/Shuffle_Active.svg
new file mode 100644
index 000000000..9f4c876dc
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Shuffle_Active.svg
@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M24.25 32.625V31.208H30.125L22.958 24.083L23.958 23.083L31.042 30.167V24.417H32.458V32.625H24.25ZM8.54199 32.292L7.54199 31.292L30.042 8.792H24.25V7.375H32.458V15.542H31.042V9.792L8.54199 32.292ZM15.75 16.875L7.58299 8.667L8.54199 7.667L16.75 15.875L15.75 16.875Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Shuffle_Icon.svg b/examples/demos/mediaplayer/icons/Shuffle_Icon.svg
new file mode 100644
index 000000000..e7c37569f
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Shuffle_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M24.25 32.625V31.208H30.125L22.958 24.083L23.958 23.083L31.042 30.167V24.417H32.458V32.625H24.25ZM8.54199 32.292L7.54199 31.292L30.042 8.792H24.25V7.375H32.458V15.542H31.042V9.792L8.54199 32.292ZM15.75 16.875L7.58299 8.667L8.54199 7.667L16.75 15.875L15.75 16.875Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Shuffle_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Shuffle_Icon_Dark.svg
new file mode 100644
index 000000000..d896b24b3
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Shuffle_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M24.25 32.625V31.208H30.125L22.958 24.083L23.958 23.083L31.042 30.167V24.417H32.458V32.625H24.25ZM8.54199 32.292L7.54199 31.292L30.042 8.792H24.25V7.375H32.458V15.542H31.042V9.792L8.54199 32.292ZM15.75 16.875L7.58299 8.667L8.54199 7.667L16.75 15.875L15.75 16.875Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Single_Loop.svg b/examples/demos/mediaplayer/icons/Single_Loop.svg
new file mode 100644
index 000000000..5511af87f
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Single_Loop.svg
@@ -0,0 +1,3 @@
+<svg width="40" height="40" viewBox="0 0 40 40" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M12 35.208L6.45801 29.667L12 24.167L13 25.208L9.20801 28.958H29.083V22.292H30.5V30.375H9.20801L13 34.167L12 35.208ZM9.50001 17.708V9.62499H30.792L27 5.83299L28 4.79199L33.542 10.333L28 15.833L27 14.792L30.792 11.042H10.917V17.708H9.50001Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Stop_Icon.svg b/examples/demos/mediaplayer/icons/Stop_Icon.svg
new file mode 100644
index 000000000..38a98edae
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Stop_Icon.svg
@@ -0,0 +1,4 @@
+<svg width="52" height="52" viewBox="0 0 52 52" fill="none" xmlns="http://www.w3.org/2000/svg">
+<circle cx="26" cy="26" r="25.5" stroke="#41CD52"/>
+<path d="M17.667 34.333V17.667H34.333V34.333H17.667ZM19.083 32.917H32.917V19.083H19.083V32.917Z" fill="#41CD52"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Trash_Icon.svg b/examples/demos/mediaplayer/icons/Trash_Icon.svg
new file mode 100644
index 000000000..c771ee5d1
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Trash_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="14" height="16" viewBox="0 0 14 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.625 16.0001C2.175 16.0001 1.79167 15.8418 1.475 15.5251C1.15833 15.2084 1 14.8251 1 14.3751V2.0001H0V1.0001H4V0.225098H10V1.0001H14V2.0001H13V14.3751C13 14.8418 12.846 15.2294 12.538 15.5381C12.2293 15.8461 11.8417 16.0001 11.375 16.0001H2.625ZM12 2.0001H2V14.3751C2 14.5584 2.05833 14.7084 2.175 14.8251C2.29167 14.9418 2.44167 15.0001 2.625 15.0001H11.375C11.5417 15.0001 11.6873 14.9374 11.812 14.8121C11.9373 14.6874 12 14.5418 12 14.3751V2.0001ZM4.8 13.0001H5.8V4.0001H4.8V13.0001ZM8.2 13.0001H9.2V4.0001H8.2V13.0001ZM2 2.0001V15.0001V14.3751V2.0001Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Trash_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Trash_Icon_Dark.svg
new file mode 100644
index 000000000..e425c354c
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Trash_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="14" height="16" viewBox="0 0 14 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2.625 16.0001C2.175 16.0001 1.79167 15.8418 1.475 15.5251C1.15833 15.2084 1 14.8251 1 14.3751V2.0001H0V1.0001H4V0.225098H10V1.0001H14V2.0001H13V14.3751C13 14.8418 12.846 15.2294 12.538 15.5381C12.2293 15.8461 11.8417 16.0001 11.375 16.0001H2.625ZM12 2.0001H2V14.3751C2 14.5584 2.05833 14.7084 2.175 14.8251C2.29167 14.9418 2.44167 15.0001 2.625 15.0001H11.375C11.5417 15.0001 11.6873 14.9374 11.812 14.8121C11.9373 14.6874 12 14.5418 12 14.3751V2.0001ZM4.8 13.0001H5.8V4.0001H4.8V13.0001ZM8.2 13.0001H9.2V4.0001H8.2V13.0001ZM2 2.0001V15.0001V14.3751V2.0001Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Volume_Icon.svg b/examples/demos/mediaplayer/icons/Volume_Icon.svg
new file mode 100644
index 000000000..69b18fa08
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Volume_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.075 15.5002V14.4502C11.4584 13.9669 12.575 13.1335 13.425 11.9502C14.275 10.7669 14.7 9.44186 14.7 7.9752C14.7 6.50853 14.275 5.18353 13.425 4.0002C12.575 2.81686 11.4584 1.98353 10.075 1.5002V0.450195C11.725 0.983529 13.075 1.93753 14.125 3.3122C15.175 4.68753 15.7 6.24186 15.7 7.9752C15.7 9.70853 15.175 11.2625 14.125 12.6372C13.075 14.0125 11.725 14.9669 10.075 15.5002ZM0.300049 10.0002V6.0002H3.72505L7.30005 2.4252V13.5752L3.72505 10.0002H0.300049ZM10.075 11.3002V4.6502C10.6417 5.01686 11.071 5.5002 11.363 6.1002C11.6544 6.7002 11.8 7.33353 11.8 8.0002C11.8 8.66686 11.65 9.29186 11.35 9.8752C11.05 10.4585 10.625 10.9335 10.075 11.3002ZM6.30005 4.8502L4.15005 7.0002H1.30005V9.0002H4.15005L6.30005 11.1502V4.8502Z" fill="#09102B"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Volume_Icon_Dark.svg b/examples/demos/mediaplayer/icons/Volume_Icon_Dark.svg
new file mode 100644
index 000000000..883125831
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Volume_Icon_Dark.svg
@@ -0,0 +1,3 @@
+<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M10.075 15.5002V14.4502C11.4584 13.9669 12.575 13.1335 13.425 11.9502C14.275 10.7669 14.7 9.44186 14.7 7.9752C14.7 6.50853 14.275 5.18353 13.425 4.0002C12.575 2.81686 11.4584 1.98353 10.075 1.5002V0.450195C11.725 0.983529 13.075 1.93753 14.125 3.3122C15.175 4.68753 15.7 6.24186 15.7 7.9752C15.7 9.70853 15.175 11.2625 14.125 12.6372C13.075 14.0125 11.725 14.9669 10.075 15.5002ZM0.300049 10.0002V6.0002H3.72505L7.30005 2.4252V13.5752L3.72505 10.0002H0.300049ZM10.075 11.3002V4.6502C10.6417 5.01686 11.071 5.5002 11.363 6.1002C11.6544 6.7002 11.8 7.33353 11.8 8.0002C11.8 8.66686 11.65 9.29186 11.35 9.8752C11.05 10.4585 10.625 10.9335 10.075 11.3002ZM6.30005 4.8502L4.15005 7.0002H1.30005V9.0002H4.15005L6.30005 11.1502V4.8502Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/icons/Warning_Icon.svg b/examples/demos/mediaplayer/icons/Warning_Icon.svg
new file mode 100644
index 000000000..a5ba71678
--- /dev/null
+++ b/examples/demos/mediaplayer/icons/Warning_Icon.svg
@@ -0,0 +1,3 @@
+<svg width="21" height="19" viewBox="0 0 21 19" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M0 18.2499L10.1346 0.75L20.2691 18.2499H0ZM2.58455 16.7499H17.6846L10.1346 3.74992L2.58455 16.7499ZM10.1346 15.5576C10.3634 15.5576 10.5552 15.4802 10.71 15.3254C10.8648 15.1706 10.9422 14.9788 10.9422 14.7499C10.9422 14.5211 10.8648 14.3293 10.71 14.1745C10.5552 14.0197 10.3634 13.9423 10.1346 13.9423C9.9057 13.9423 9.71387 14.0197 9.55908 14.1745C9.40427 14.3293 9.32688 14.5211 9.32688 14.7499C9.32688 14.9788 9.40427 15.1706 9.55908 15.3254C9.71387 15.4802 9.9057 15.5576 10.1346 15.5576ZM9.38458 12.9423H10.8845V7.94225H9.38458V12.9423Z" fill="white"/>
+</svg>
diff --git a/examples/demos/mediaplayer/main.cpp b/examples/demos/mediaplayer/main.cpp
new file mode 100644
index 000000000..b1ed11591
--- /dev/null
+++ b/examples/demos/mediaplayer/main.cpp
@@ -0,0 +1,37 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
+
+#include <QGuiApplication>
+#include <QQmlApplicationEngine>
+#include <QCommandLineParser>
+#include <QDir>
+
+using namespace Qt::Literals::StringLiterals;
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication app(argc, argv);
+
+ QCoreApplication::setApplicationName("MediaPlayer Example");
+ QCoreApplication::setOrganizationName("QtProject");
+ QCoreApplication::setApplicationVersion(QT_VERSION_STR);
+ QCommandLineParser parser;
+ parser.setApplicationDescription(QCoreApplication::translate("main", "Qt Quick MediaPlayer Example"));
+ parser.addHelpOption();
+ parser.addVersionOption();
+ parser.addPositionalArgument("url", QCoreApplication::translate("main", "The URL(s) to open."));
+ parser.process(app);
+
+ QQmlApplicationEngine engine;
+ QObject::connect(&engine, &QQmlApplicationEngine::quit, &app, &QGuiApplication::quit);
+
+ if (!parser.positionalArguments().isEmpty()) {
+ QUrl source = QUrl::fromUserInput(parser.positionalArguments().at(0), QDir::currentPath());
+ engine.setInitialProperties({
+ { "source", source },
+ });
+ }
+ engine.loadFromModule("MediaPlayerModule", "Main");
+
+ return app.exec();
+}