7eb252e7686f4ff08685b145194e870af65cc6ca
[apps/videoplayer.git] / app / VideoPlayer.qml
1 /*
2  * Copyright (C) 2018 The Qt Company Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 import QtQuick 2.6
17 import QtQuick.Layouts 1.1
18 import QtQuick.Controls 2.0
19 import QtMultimedia 5.6
20 import AGL.Demo.Controls 1.0
21 import 'api' as API
22
23 ApplicationWindow {
24     id: root
25
26     API.MediaScanner {
27         id: scanner
28         url: bindingAddress
29
30         property var titles: Object
31         onAdded: {
32             playlist.addItem(media.path)
33             titles[media.path] = media.title
34         }
35         onRemoved: {
36             playlist.removeItem(index)
37         }
38     }
39
40     MediaPlayer {
41         id: player
42         audioRole: MediaPlayer.MusicRole
43         autoLoad: true
44         playlist: playlist
45         function time2str(value) {
46             return Qt.formatTime(new Date(value), 'mm:ss')
47         }
48         onPositionChanged: slider.value = player.position
49     }
50
51     Playlist {
52         id: playlist
53         playbackMode: Playlist.Loop
54
55 //        PlaylistItem { source: 'file:///home/root/Videos/Qt_Mashup_DO_NOT_MODIFY.mp4' }
56 //        PlaylistItem { source: 'file:///home/root/Videos/Qt_is_everywhere-071116.mp4' }
57     }
58
59     ColumnLayout {
60         anchors.fill: parent
61         Item {
62             Layout.fillWidth: true
63             Layout.fillHeight: true
64             Layout.preferredHeight: 1080
65             clip: true
66             VideoOutput {
67                 source: player
68                 anchors.top: parent.top
69                 anchors.left: parent.left
70                 anchors.right: parent.right
71                 anchors.bottom: controls.top
72                 Rectangle {
73                     anchors.fill: parent
74                     color: 'black'
75                     opacity: 0.75
76                     z: -1
77                 }
78             }
79
80             Item {
81                 id: controls
82                 anchors.left: parent.left
83                 anchors.right: parent.right
84                 anchors.bottom: parent.bottom
85                 height: 307
86                 Rectangle {
87                     anchors.fill: parent
88                     color: 'black'
89                     opacity: 0.75
90                 }
91
92                 ColumnLayout {
93                     anchors.fill: parent
94                     anchors.margins: root.width * 0.02
95                     Item {
96                         Layout.fillWidth: true
97                         Layout.fillHeight: true
98                         Row {
99                             spacing: 20
100                             ToggleButton {
101                                 id: random
102                                 offImage: './images/AGL_MediaPlayer_Shuffle_Inactive.svg'
103                                 onImage: './images/AGL_MediaPlayer_Shuffle_Active.svg'
104                             }
105                             ToggleButton {
106                                 id: loop
107                                 offImage: './images/AGL_MediaPlayer_Loop_Inactive.svg'
108                                 onImage: './images/AGL_MediaPlayer_Loop_Active.svg'
109                             }
110                         }
111                         ColumnLayout {
112                             anchors.fill: parent
113                             Label {
114                                 id: title
115                                 Layout.alignment: Layout.Center
116                                 text: player.metaData.title ? player.metaData.title : ''
117                                 horizontalAlignment: Label.AlignHCenter
118                                 verticalAlignment: Label.AlignVCenter
119                             }
120                             Label {
121                                 id: artist
122                                 Layout.alignment: Layout.Center
123                                 text: player.metaData.author ? player.metaData.author : ''
124                                 horizontalAlignment: Label.AlignHCenter
125                                 verticalAlignment: Label.AlignVCenter
126                                 font.pixelSize: title.font.pixelSize * 0.6
127                             }
128                         }
129                     }
130                     Slider {
131                         id: slider
132                         Layout.fillWidth: true
133                         to: player.duration
134                         Label {
135                             id: position
136                             anchors.left: parent.left
137                             anchors.bottom: parent.top
138                             font.pixelSize: 32
139                             text: player.time2str(player.position)
140                         }
141                         Label {
142                             id: duration
143                             anchors.right: parent.right
144                             anchors.bottom: parent.top
145                             font.pixelSize: 32
146                             text: player.time2str(player.duration)
147                         }
148                         onPressedChanged: player.seek(value)
149                     }
150                     RowLayout {
151                         Layout.fillHeight: true
152                         Item { Layout.fillWidth: true }
153                         ImageButton {
154                             offImage: './images/AGL_MediaPlayer_BackArrow.svg'
155                             onClicked: playlist.previous()
156                         }
157                         ImageButton {
158                             id: play
159                             offImage: './images/AGL_MediaPlayer_Player_Play.svg'
160                             onClicked: player.play()
161                             states: [
162                                 State {
163                                     when: player.playbackState === MediaPlayer.PlayingState
164                                     PropertyChanges {
165                                         target: play
166                                         offImage: './images/AGL_MediaPlayer_Player_Pause.svg'
167                                         onClicked: player.pause()
168                                     }
169                                 }
170                             ]
171                         }
172                         ImageButton {
173                             offImage: './images/AGL_MediaPlayer_ForwardArrow.svg'
174                             onClicked: playlist.next()
175                         }
176
177                         Item { Layout.fillWidth: true }
178                     }
179                 }
180             }
181         }
182         Item {
183             Layout.fillWidth: true
184             Layout.fillHeight: true
185             Layout.preferredHeight: 407
186             ListView {
187                 anchors.fill: parent
188                 clip: true
189                 header: Label {
190                     x: 50
191                     text: 'PLAYLIST'
192                     opacity: 0.5
193                 }
194                 model: playlist
195                 currentIndex: playlist.currentIndex
196
197                 delegate: MouseArea {
198                     id: delegate
199                     width: ListView.view.width
200                     height: ListView.view.height / 4
201                     RowLayout {
202                         anchors.fill: parent
203                         anchors.leftMargin: 50
204                         anchors.rightMargin: 50
205                         ColumnLayout {
206                             Layout.fillWidth: true
207                             Label {
208                                 Layout.fillWidth: true
209                                 text: scanner.titles[model.source] ? scanner.titles[model.source] : model.source.toString().split('/').reverse()[0]
210                             }
211                         }
212                         Label {
213                             text: player.time2str(model.duration)
214                             color: '#66FF99'
215                             font.pixelSize: 32
216                         }
217                     }
218                     property var m: model
219                     onClicked: {
220                         playlist.currentIndex = model.index
221                         player.play()
222                     }
223                 }
224
225                 highlight: Rectangle {
226                     color: 'white'
227                     opacity: 0.25
228                 }
229             }
230         }
231     }
232 }