summaryrefslogtreecommitdiffstats
path: root/app
diff options
context:
space:
mode:
authorTasuku Suzuki <tasuku.suzuki@qt.io>2018-01-04 23:43:58 +0900
committerTasuku Suzuki <tasuku.suzuki@qt.io>2018-01-05 10:35:23 +0900
commit64551c373988866607cc4af49e8b3e55aa0d218e (patch)
tree057e812bb7c6fe571da864cef74192abc233f0aa /app
parent338e945a4315a3951211290eb2ae248faadb1535 (diff)
Change-Id: I4fb664a8520f02bc8e8eb8a87aa14c52d0fe8800 Signed-off-by: Tasuku Suzuki <tasuku.suzuki@qt.io>
Diffstat (limited to 'app')
-rw-r--r--app/VideoPlayer.qml232
-rw-r--r--app/api/MediaScanner.qml117
-rw-r--r--app/app.pri3
-rw-r--r--app/app.pro11
-rw-r--r--app/images/AGL_MediaPlayer_BackArrow.svg29
-rw-r--r--app/images/AGL_MediaPlayer_DividingLine.svg60
-rw-r--r--app/images/AGL_MediaPlayer_ForwardArrow.svg29
-rw-r--r--app/images/AGL_MediaPlayer_Loop_Active.svg58
-rw-r--r--app/images/AGL_MediaPlayer_Loop_Inactive.svg58
-rw-r--r--app/images/AGL_MediaPlayer_Player_Pause.svg37
-rw-r--r--app/images/AGL_MediaPlayer_Player_Play.svg36
-rw-r--r--app/images/AGL_MediaPlayer_Shuffle_Active.svg56
-rw-r--r--app/images/AGL_MediaPlayer_Shuffle_Inactive.svg56
-rw-r--r--app/images/images.qrc13
-rw-r--r--app/main.cpp26
-rw-r--r--app/videoplayer.qrc6
16 files changed, 827 insertions, 0 deletions
diff --git a/app/VideoPlayer.qml b/app/VideoPlayer.qml
new file mode 100644
index 0000000..7eb252e
--- /dev/null
+++ b/app/VideoPlayer.qml
@@ -0,0 +1,232 @@
+/*
+ * Copyright (C) 2018 The Qt Company Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import QtQuick 2.6
+import QtQuick.Layouts 1.1
+import QtQuick.Controls 2.0
+import QtMultimedia 5.6
+import AGL.Demo.Controls 1.0
+import 'api' as API
+
+ApplicationWindow {
+ id: root
+
+ API.MediaScanner {
+ id: scanner
+ url: bindingAddress
+
+ property var titles: Object
+ onAdded: {
+ playlist.addItem(media.path)
+ titles[media.path] = media.title
+ }
+ onRemoved: {
+ playlist.removeItem(index)
+ }
+ }
+
+ MediaPlayer {
+ id: player
+ audioRole: MediaPlayer.MusicRole
+ autoLoad: true
+ playlist: playlist
+ function time2str(value) {
+ return Qt.formatTime(new Date(value), 'mm:ss')
+ }
+ onPositionChanged: slider.value = player.position
+ }
+
+ Playlist {
+ id: playlist
+ playbackMode: Playlist.Loop
+
+// PlaylistItem { source: 'file:///home/root/Videos/Qt_Mashup_DO_NOT_MODIFY.mp4' }
+// PlaylistItem { source: 'file:///home/root/Videos/Qt_is_everywhere-071116.mp4' }
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.preferredHeight: 1080
+ clip: true
+ VideoOutput {
+ source: player
+ anchors.top: parent.top
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: controls.top
+ Rectangle {
+ anchors.fill: parent
+ color: 'black'
+ opacity: 0.75
+ z: -1
+ }
+ }
+
+ Item {
+ id: controls
+ anchors.left: parent.left
+ anchors.right: parent.right
+ anchors.bottom: parent.bottom
+ height: 307
+ Rectangle {
+ anchors.fill: parent
+ color: 'black'
+ opacity: 0.75
+ }
+
+ ColumnLayout {
+ anchors.fill: parent
+ anchors.margins: root.width * 0.02
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Row {
+ spacing: 20
+ ToggleButton {
+ id: random
+ offImage: './images/AGL_MediaPlayer_Shuffle_Inactive.svg'
+ onImage: './images/AGL_MediaPlayer_Shuffle_Active.svg'
+ }
+ ToggleButton {
+ id: loop
+ offImage: './images/AGL_MediaPlayer_Loop_Inactive.svg'
+ onImage: './images/AGL_MediaPlayer_Loop_Active.svg'
+ }
+ }
+ ColumnLayout {
+ anchors.fill: parent
+ Label {
+ id: title
+ Layout.alignment: Layout.Center
+ text: player.metaData.title ? player.metaData.title : ''
+ horizontalAlignment: Label.AlignHCenter
+ verticalAlignment: Label.AlignVCenter
+ }
+ Label {
+ id: artist
+ Layout.alignment: Layout.Center
+ text: player.metaData.author ? player.metaData.author : ''
+ horizontalAlignment: Label.AlignHCenter
+ verticalAlignment: Label.AlignVCenter
+ font.pixelSize: title.font.pixelSize * 0.6
+ }
+ }
+ }
+ Slider {
+ id: slider
+ Layout.fillWidth: true
+ to: player.duration
+ Label {
+ id: position
+ anchors.left: parent.left
+ anchors.bottom: parent.top
+ font.pixelSize: 32
+ text: player.time2str(player.position)
+ }
+ Label {
+ id: duration
+ anchors.right: parent.right
+ anchors.bottom: parent.top
+ font.pixelSize: 32
+ text: player.time2str(player.duration)
+ }
+ onPressedChanged: player.seek(value)
+ }
+ RowLayout {
+ Layout.fillHeight: true
+ Item { Layout.fillWidth: true }
+ ImageButton {
+ offImage: './images/AGL_MediaPlayer_BackArrow.svg'
+ onClicked: playlist.previous()
+ }
+ ImageButton {
+ id: play
+ offImage: './images/AGL_MediaPlayer_Player_Play.svg'
+ onClicked: player.play()
+ states: [
+ State {
+ when: player.playbackState === MediaPlayer.PlayingState
+ PropertyChanges {
+ target: play
+ offImage: './images/AGL_MediaPlayer_Player_Pause.svg'
+ onClicked: player.pause()
+ }
+ }
+ ]
+ }
+ ImageButton {
+ offImage: './images/AGL_MediaPlayer_ForwardArrow.svg'
+ onClicked: playlist.next()
+ }
+
+ Item { Layout.fillWidth: true }
+ }
+ }
+ }
+ }
+ Item {
+ Layout.fillWidth: true
+ Layout.fillHeight: true
+ Layout.preferredHeight: 407
+ ListView {
+ anchors.fill: parent
+ clip: true
+ header: Label {
+ x: 50
+ text: 'PLAYLIST'
+ opacity: 0.5
+ }
+ model: playlist
+ currentIndex: playlist.currentIndex
+
+ delegate: MouseArea {
+ id: delegate
+ width: ListView.view.width
+ height: ListView.view.height / 4
+ RowLayout {
+ anchors.fill: parent
+ anchors.leftMargin: 50
+ anchors.rightMargin: 50
+ ColumnLayout {
+ Layout.fillWidth: true
+ Label {
+ Layout.fillWidth: true
+ text: scanner.titles[model.source] ? scanner.titles[model.source] : model.source.toString().split('/').reverse()[0]
+ }
+ }
+ Label {
+ text: player.time2str(model.duration)
+ color: '#66FF99'
+ font.pixelSize: 32
+ }
+ }
+ property var m: model
+ onClicked: {
+ playlist.currentIndex = model.index
+ player.play()
+ }
+ }
+
+ highlight: Rectangle {
+ color: 'white'
+ opacity: 0.25
+ }
+ }
+ }
+ }
+}
diff --git a/app/api/MediaScanner.qml b/app/api/MediaScanner.qml
new file mode 100644
index 0000000..add261b
--- /dev/null
+++ b/app/api/MediaScanner.qml
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2018 The Qt Company Ltd.
+ * Copyright (C) 2017 Konsulko Group
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import QtQuick 2.6
+import QtWebSockets 1.0
+
+WebSocket {
+ id: root
+ active: true
+ url: bindingAddress
+
+ property string statusString: "waiting..."
+ property string apiString: "mediascanner"
+ property var verbs: []
+ property string payloadLength: "9999"
+
+ readonly property var msgid: {
+ "call": 2,
+ "retok": 3,
+ "reterr": 4,
+ "event": 5
+ }
+
+ signal added(var media)
+ signal removed(var index)
+
+ property var cache: []
+ function add(files) {
+ for (var i = 0; i < files.length; i++) {
+ var media = files[i]
+
+ if (cache.indexOf(media.path) < 0) {
+ root.added(media)
+ cache.push(media.path)
+ }
+ }
+ }
+
+ function remove(prefix) {
+ for (var i = cache.length - 1; i > -1; i--) {
+ var media = cache[i]
+ if (media.substr(0, prefix.length) === prefix) {
+ root.removed(i)
+ cache.splice(i, 1)
+ }
+ }
+ }
+
+ onTextMessageReceived: {
+ console.debug("Raw response: " + message)
+ var json = JSON.parse(message)
+ var request = json[2].request
+ var response = json[2].response
+// console.debug("response: " + JSON.stringify(response))
+ switch (json[0]) {
+ case msgid.call:
+ break
+ case msgid.retok:
+ root.statusString = request.status
+ var verb = verbs.shift()
+ if (verb === "media_result") {
+ root.add(response.Media)
+ }
+ break
+ case msgid.reterr:
+ root.statusString = "Bad return value, binding probably not installed"
+ var verb = verbs.shift()
+ break
+ case msgid.event:
+ var payload = JSON.parse(JSON.stringify(json[2]))
+ var event = payload.event
+ if (event == "mediascanner/media_added") {
+ console.debug("Media playlist is updated")
+ root.add(json[2].data.Media)
+ } else if (event == "mediascanner/media_removed") {
+ root.remove(json[2].data.Path)
+ }
+ break
+ }
+ }
+
+ onStatusChanged: {
+ switch (status) {
+ case WebSocket.Open:
+ console.debug("onStatusChanged: Open")
+ sendSocketMessage("subscribe", { value: "media_added" })
+ sendSocketMessage("subscribe", { value: "media_removed" })
+ sendSocketMessage("media_result", { type: 'video' })
+ break
+ case WebSocket.Error:
+ root.statusString = "WebSocket error: " + root.errorString
+ break
+ }
+ }
+
+ function sendSocketMessage(verb, parameter) {
+ var requestJson = [ msgid.call, payloadLength, apiString + '/'
+ + verb, parameter ]
+ console.debug("sendSocketMessage: " + JSON.stringify(requestJson))
+ verbs.push(verb)
+ sendTextMessage(JSON.stringify(requestJson))
+ }
+}
diff --git a/app/app.pri b/app/app.pri
new file mode 100644
index 0000000..f22f540
--- /dev/null
+++ b/app/app.pri
@@ -0,0 +1,3 @@
+TEMPLATE = app
+
+DESTDIR = $${OUT_PWD}/../package/root/bin
diff --git a/app/app.pro b/app/app.pro
new file mode 100644
index 0000000..eeb139c
--- /dev/null
+++ b/app/app.pro
@@ -0,0 +1,11 @@
+TARGET = videoplayer
+QT = quick aglextras multimedia
+
+SOURCES = main.cpp
+
+RESOURCES += \
+ videoplayer.qrc \
+ images/images.qrc
+
+include(app.pri)
+
diff --git a/app/images/AGL_MediaPlayer_BackArrow.svg b/app/images/AGL_MediaPlayer_BackArrow.svg
new file mode 100644
index 0000000..061c6ec
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_BackArrow.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+]>
+<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 80 80"
+ style="enable-background:new 0 0 80 80;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#0DF9FF;}
+</style>
+<switch>
+ <g i:extraneous="self">
+ <g id="previous_1_">
+ <g>
+ <path class="st0" d="M68,38.4H18.3c3.4-3.4,11.1-11,11.1-11c0-0.1-1.6-3.2-1.6-3.2L12,40l15.8,15.8c0,0,1.6-3.2,1.6-3.2
+ c0,0-7.7-7.7-11-11.1H68V38.4z"/>
+ </g>
+ </g>
+ </g>
+</switch>
+</svg>
diff --git a/app/images/AGL_MediaPlayer_DividingLine.svg b/app/images/AGL_MediaPlayer_DividingLine.svg
new file mode 100644
index 0000000..51ed1ee
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_DividingLine.svg
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 1080 2"
+ style="enable-background:new 0 0 1080 2;"
+ xml:space="preserve"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="AGL_MediaPlayer_DividingLine.svg"><metadata
+ id="metadata18"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs16" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview14"
+ showgrid="false"
+ inkscape:zoom="0.62222222"
+ inkscape:cx="-183.21429"
+ inkscape:cy="1"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><style
+ type="text/css"
+ id="style3">
+ .st0{opacity:0.302;}
+ .st1{fill-rule:evenodd;clip-rule:evenodd;fill:#A8A8A8;}
+</style><switch
+ id="switch5"><g
+ i:extraneous="self"
+ id="g7"><g
+ id="Divider"
+ class="st0"><g
+ id="g10"><rect
+ y="1.1"
+ class="st1"
+ width="1080"
+ height="1.1"
+ id="rect12" /></g></g></g></switch></svg> \ No newline at end of file
diff --git a/app/images/AGL_MediaPlayer_ForwardArrow.svg b/app/images/AGL_MediaPlayer_ForwardArrow.svg
new file mode 100644
index 0000000..ea17210
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_ForwardArrow.svg
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+]>
+<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 80 80"
+ style="enable-background:new 0 0 80 80;" xml:space="preserve">
+<style type="text/css">
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#0DF9FF;}
+</style>
+<switch>
+ <g i:extraneous="self">
+ <g id="previous_1_">
+ <g>
+ <path class="st0" d="M52.2,24.2c0,0-1.6,3.2-1.6,3.2c0,0,7.7,7.6,11.1,11H12v3.2h49.7c-3.4,3.4-11,11.1-11,11.1
+ c0,0,1.6,3.2,1.6,3.2L68,40L52.2,24.2z"/>
+ </g>
+ </g>
+ </g>
+</switch>
+</svg>
diff --git a/app/images/AGL_MediaPlayer_Loop_Active.svg b/app/images/AGL_MediaPlayer_Loop_Active.svg
new file mode 100644
index 0000000..fed253d
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_Loop_Active.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 50 50"
+ style="enable-background:new 0 0 50 50;"
+ xml:space="preserve"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="AGL_MediaPlayer_Loop_Active.svg"><metadata
+ id="metadata19"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs17" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview15"
+ showgrid="false"
+ inkscape:zoom="4.72"
+ inkscape:cx="-75.529661"
+ inkscape:cy="25"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><style
+ type="text/css"
+ id="style3">
+ .st0{fill:#EAEAEA;}
+</style><switch
+ id="switch5"><g
+ i:extraneous="self"
+ id="g7"><g
+ id="g9"><path
+ class="st0"
+ d="M31.5,15.3v4.4c0,0.4,0.2,0.7,0.6,0.9c0.1,0.1,0.3,0.1,0.5,0.1c0.2,0,0.4-0.1,0.6-0.2l9.4-6.8 c0.3-0.2,0.4-0.5,0.4-0.8c0-0.3-0.2-0.6-0.4-0.8l-9.4-6.8C32.8,5,32.4,5,32,5.2c-0.3,0.2-0.6,0.5-0.6,0.9v4.4H10.9 C5.1,10.5,0.3,15.2,0.3,21V29c0,1.3,1.1,2.4,2.4,2.4c1.3,0,2.4-1.1,2.4-2.4V21c0-3.2,2.6-5.8,5.8-5.8H31.5z"
+ id="path11" /><path
+ class="st0"
+ d="M47.3,18.7c-1.3,0-2.4,1.1-2.4,2.4V29c0,3.2-2.6,5.8-5.8,5.8H18.4v-4.4c0-0.4-0.2-0.7-0.6-0.9 c-0.3-0.2-0.8-0.1-1.1,0.1l-9.4,6.8C7.2,36.5,7,36.8,7,37.1c0,0.3,0.2,0.6,0.4,0.8l9.4,6.8c0.2,0.1,0.4,0.2,0.6,0.2 c0.2,0,0.3,0,0.5-0.1c0.3-0.2,0.6-0.5,0.6-0.9v-4.4h20.7c5.8,0,10.5-4.7,10.5-10.5V21C49.7,19.7,48.6,18.7,47.3,18.7z"
+ id="path13" /></g></g></switch></svg> \ No newline at end of file
diff --git a/app/images/AGL_MediaPlayer_Loop_Inactive.svg b/app/images/AGL_MediaPlayer_Loop_Inactive.svg
new file mode 100644
index 0000000..27ae317
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_Loop_Inactive.svg
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 50 50"
+ style="enable-background:new 0 0 50 50;"
+ xml:space="preserve"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="AGL_MediaPlayer_Loop_Inactive.svg"><metadata
+ id="metadata19"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs17" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview15"
+ showgrid="false"
+ inkscape:zoom="4.72"
+ inkscape:cx="-74.682203"
+ inkscape:cy="25"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><style
+ type="text/css"
+ id="style3">
+ .st0{fill:#7A787D;}
+</style><switch
+ id="switch5"><g
+ i:extraneous="self"
+ id="g7"><g
+ id="g9"><path
+ class="st0"
+ d="M31.5,15.3v4.4c0,0.4,0.2,0.7,0.6,0.9c0.1,0.1,0.3,0.1,0.5,0.1c0.2,0,0.4-0.1,0.6-0.2l9.4-6.8 c0.3-0.2,0.4-0.5,0.4-0.8c0-0.3-0.2-0.6-0.4-0.8l-9.4-6.8C32.8,5,32.4,5,32,5.2c-0.3,0.2-0.6,0.5-0.6,0.9v4.4H10.9 C5.1,10.5,0.3,15.2,0.3,21V29c0,1.3,1.1,2.4,2.4,2.4c1.3,0,2.4-1.1,2.4-2.4V21c0-3.2,2.6-5.8,5.8-5.8H31.5z"
+ id="path11" /><path
+ class="st0"
+ d="M47.3,18.7c-1.3,0-2.4,1.1-2.4,2.4V29c0,3.2-2.6,5.8-5.8,5.8H18.4v-4.4c0-0.4-0.2-0.7-0.6-0.9 c-0.3-0.2-0.8-0.1-1.1,0.1l-9.4,6.8C7.2,36.5,7,36.8,7,37.1c0,0.3,0.2,0.6,0.4,0.8l9.4,6.8c0.2,0.1,0.4,0.2,0.6,0.2 c0.2,0,0.3,0,0.5-0.1c0.3-0.2,0.6-0.5,0.6-0.9v-4.4h20.7c5.8,0,10.5-4.7,10.5-10.5V21C49.7,19.7,48.6,18.7,47.3,18.7z"
+ id="path13" /></g></g></switch></svg> \ No newline at end of file
diff --git a/app/images/AGL_MediaPlayer_Player_Pause.svg b/app/images/AGL_MediaPlayer_Player_Pause.svg
new file mode 100644
index 0000000..03eacc1
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_Player_Pause.svg
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+]>
+<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100"
+ style="enable-background:new 0 0 100 100;" xml:space="preserve">
+<style type="text/css">
+ .st0{opacity:0.851;}
+ .st1{fill:none;stroke:#0DF9FF;stroke-width:2;stroke-miterlimit:10;}
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<switch>
+ <g i:extraneous="self">
+ <g id="button_2_" class="st0">
+ <g>
+ <ellipse class="st1" cx="49.3" cy="49.6" rx="46" ry="46"/>
+ </g>
+ </g>
+ <g id="pause_2_">
+ <g>
+ <path class="st2" d="M43.1,29.8h-5.6c-1.6,0-2.8,1.2-2.8,2.8v33.2c0,1.5,1.3,2.8,2.8,2.8h5.6c1.6,0,2.8-1.2,2.8-2.8V32.5
+ C45.9,31,44.6,29.8,43.1,29.8z M60,29.8h-5.6c-1.6,0-2.8,1.2-2.8,2.8v33.2c0,1.5,1.3,2.8,2.8,2.8H60c1.6,0,2.8-1.2,2.8-2.8V32.5
+ C62.8,31,61.6,29.8,60,29.8z"/>
+ </g>
+ </g>
+ </g>
+</switch>
+</svg>
diff --git a/app/images/AGL_MediaPlayer_Player_Play.svg b/app/images/AGL_MediaPlayer_Player_Play.svg
new file mode 100644
index 0000000..7e89297
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_Player_Play.svg
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 21.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
+ <!ENTITY ns_extend "http://ns.adobe.com/Extensibility/1.0/">
+ <!ENTITY ns_ai "http://ns.adobe.com/AdobeIllustrator/10.0/">
+ <!ENTITY ns_graphs "http://ns.adobe.com/Graphs/1.0/">
+ <!ENTITY ns_vars "http://ns.adobe.com/Variables/1.0/">
+ <!ENTITY ns_imrep "http://ns.adobe.com/ImageReplacement/1.0/">
+ <!ENTITY ns_sfw "http://ns.adobe.com/SaveForWeb/1.0/">
+ <!ENTITY ns_custom "http://ns.adobe.com/GenericCustomNamespace/1.0/">
+ <!ENTITY ns_adobe_xpath "http://ns.adobe.com/XPath/1.0/">
+]>
+<svg version="1.1" id="Layer_1" xmlns:x="&ns_extend;" xmlns:i="&ns_ai;" xmlns:graph="&ns_graphs;"
+ xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 100 100"
+ style="enable-background:new 0 0 100 100;" xml:space="preserve">
+<style type="text/css">
+ .st0{opacity:0.851;}
+ .st1{fill:none;stroke:#0DF9FF;stroke-width:2;stroke-miterlimit:10;}
+ .st2{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
+</style>
+<switch>
+ <g i:extraneous="self">
+ <g id="button_2_" class="st0">
+ <g>
+ <ellipse class="st1" cx="49.3" cy="49.6" rx="46" ry="46"/>
+ </g>
+ </g>
+ <g id="play_icon_2_">
+ <g>
+ <path class="st2" d="M65,48L43.3,33.9c-1.3-0.7-2.8-0.6-2.8,1.9v27.7c0,2.3,1.6,2.7,2.8,1.9L65,51.3C65.9,50.4,65.9,48.9,65,48z
+ "/>
+ </g>
+ </g>
+ </g>
+</switch>
+</svg>
diff --git a/app/images/AGL_MediaPlayer_Shuffle_Active.svg b/app/images/AGL_MediaPlayer_Shuffle_Active.svg
new file mode 100644
index 0000000..c2c04f8
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_Shuffle_Active.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 45 45"
+ style="enable-background:new 0 0 45 45;"
+ xml:space="preserve"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="AGL_MediaPlayer_Shuffle_Active.svg"><metadata
+ id="metadata18"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs16" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview14"
+ showgrid="false"
+ inkscape:zoom="5.2444444"
+ inkscape:cx="-69.978814"
+ inkscape:cy="22.5"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><style
+ type="text/css"
+ id="style3">
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#EAEAEA;}
+</style><switch
+ id="switch5"><g
+ i:extraneous="self"
+ id="g7"><g
+ id="repeat_1_"><g
+ id="g10"><path
+ class="st0"
+ d="M2.1,12h6.5l5.7,7.8l2.1-2.6c0,0-5.7-7.9-6.1-8.4H2.1c-0.9,0-1.6,0.9-1.6,1.8C0.5,11.4,1.2,12,2.1,12z M34.7,12v4.4c0.5,0.5,2,0.7,2.5,0.2l6.9-5.2c0.5-0.5,0.5-1.3,0-1.7l-6.9-5.2c-0.5-0.5-2-0.8-2.5-0.3v4.6h-8.2L8.6,33.1H2.1 c-0.9,0-1.6,0.6-1.6,1.5c0,0.9,0.7,1.8,1.6,1.8h8.2L28.2,12H34.7z M37.2,28.5c-0.5-0.5-2-0.4-2.5,0.1v4.5h-6.5l-5.8-7.8 l-2.1,2.6l6.2,8.3h8.2v4.7c0.5,0.5,2,0.3,2.5-0.2l6.9-5.2c0.5-0.5,0.5-1.3,0-1.7L37.2,28.5z"
+ id="path12" /></g></g></g></switch></svg> \ No newline at end of file
diff --git a/app/images/AGL_MediaPlayer_Shuffle_Inactive.svg b/app/images/AGL_MediaPlayer_Shuffle_Inactive.svg
new file mode 100644
index 0000000..068370a
--- /dev/null
+++ b/app/images/AGL_MediaPlayer_Shuffle_Inactive.svg
@@ -0,0 +1,56 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 21.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
+
+<svg
+ xmlns:i="&amp;ns_ai;"
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ version="1.1"
+ id="Layer_1"
+ x="0px"
+ y="0px"
+ viewBox="0 0 45 45"
+ style="enable-background:new 0 0 45 45;"
+ xml:space="preserve"
+ inkscape:version="0.91 r13725"
+ sodipodi:docname="AGL_MediaPlayer_Shuffle_Inactive.svg"><metadata
+ id="metadata18"><rdf:RDF><cc:Work
+ rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" /></cc:Work></rdf:RDF></metadata><defs
+ id="defs16" /><sodipodi:namedview
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1"
+ objecttolerance="10"
+ gridtolerance="10"
+ guidetolerance="10"
+ inkscape:pageopacity="0"
+ inkscape:pageshadow="2"
+ inkscape:window-width="2560"
+ inkscape:window-height="1464"
+ id="namedview14"
+ showgrid="false"
+ inkscape:zoom="5.2444444"
+ inkscape:cx="-79.417373"
+ inkscape:cy="22.5"
+ inkscape:window-x="0"
+ inkscape:window-y="0"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="Layer_1" /><style
+ type="text/css"
+ id="style3">
+ .st0{fill-rule:evenodd;clip-rule:evenodd;fill:#7A787D;}
+</style><switch
+ id="switch5"><g
+ i:extraneous="self"
+ id="g7"><g
+ id="repeat_1_"><g
+ id="g10"><path
+ class="st0"
+ d="M2.1,12h6.5l5.7,7.8l2.1-2.6c0,0-5.7-7.9-6.1-8.4H2.1c-0.9,0-1.6,0.9-1.6,1.8C0.5,11.4,1.2,12,2.1,12z M34.7,12v4.4c0.5,0.5,2,0.7,2.5,0.2l6.9-5.2c0.5-0.5,0.5-1.3,0-1.7l-6.9-5.2c-0.5-0.5-2-0.8-2.5-0.3v4.6h-8.2L8.6,33.1H2.1 c-0.9,0-1.6,0.6-1.6,1.5c0,0.9,0.7,1.8,1.6,1.8h8.2L28.2,12H34.7z M37.2,28.5c-0.5-0.5-2-0.4-2.5,0.1v4.5h-6.5l-5.8-7.8 l-2.1,2.6l6.2,8.3h8.2v4.7c0.5,0.5,2,0.3,2.5-0.2l6.9-5.2c0.5-0.5,0.5-1.3,0-1.7L37.2,28.5z"
+ id="path12" /></g></g></g></switch></svg> \ No newline at end of file
diff --git a/app/images/images.qrc b/app/images/images.qrc
new file mode 100644
index 0000000..fe8a58d
--- /dev/null
+++ b/app/images/images.qrc
@@ -0,0 +1,13 @@
+<RCC>
+ <qresource prefix="/images">
+ <file>AGL_MediaPlayer_BackArrow.svg</file>
+ <file>AGL_MediaPlayer_DividingLine.svg</file>
+ <file>AGL_MediaPlayer_ForwardArrow.svg</file>
+ <file>AGL_MediaPlayer_Loop_Active.svg</file>
+ <file>AGL_MediaPlayer_Loop_Inactive.svg</file>
+ <file>AGL_MediaPlayer_Player_Pause.svg</file>
+ <file>AGL_MediaPlayer_Player_Play.svg</file>
+ <file>AGL_MediaPlayer_Shuffle_Active.svg</file>
+ <file>AGL_MediaPlayer_Shuffle_Inactive.svg</file>
+ </qresource>
+</RCC>
diff --git a/app/main.cpp b/app/main.cpp
new file mode 100644
index 0000000..7fdff20
--- /dev/null
+++ b/app/main.cpp
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2018 The Qt Company Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#include <QtAGLExtras/AGLApplication>
+#include <QtQml/QQmlApplicationEngine>
+
+int main(int argc, char *argv[])
+{
+ AGLApplication app(argc, argv);
+ app.setApplicationName("VideoPlayer");
+ app.setupApplicationRole("Video");
+ app.load(QUrl(QStringLiteral("qrc:/VideoPlayer.qml")));
+ return app.exec();
+}
diff --git a/app/videoplayer.qrc b/app/videoplayer.qrc
new file mode 100644
index 0000000..a1bbeb0
--- /dev/null
+++ b/app/videoplayer.qrc
@@ -0,0 +1,6 @@
+<RCC>
+ <qresource prefix="/">
+ <file>VideoPlayer.qml</file>
+ <file>api/MediaScanner.qml</file>
+ </qresource>
+</RCC>