2 * Copyright (C) 2016 The Qt Company Ltd.
3 * Copyright (C) 2017 Toyota Motor Corporation
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
19 import QtQuick.Layouts 1.1
20 import QtQuick.Controls 2.0
21 import QtMultimedia 5.6
22 import AGL.Demo.Controls 1.0
23 import MediaPlayer 1.0
29 property int sourceID: 0
30 property bool registered_media: false
31 property int connectionID
32 property int sourceIndex
34 API.LightMediaScanner {
39 API.BluetoothManager {
46 audioRole: MediaPlayer.MusicRole
50 function time2str(value) {
51 return Qt.formatTime(new Date(value), 'mm:ss')
54 function stopMediaplayer(){
55 console.log("stop mediaplayer from C++")
59 function slotReply(msg){
60 var jstr = JSON.stringify(msg)
61 console.log("mediaplayer: Json jstr:" + jstr)
62 var content = JSON.parse(jstr);
63 var verb = content.response.verb
64 var err = content.response.error
65 console.log("mediaplayer: verb: " + verb)
66 console.log("mediaplayer: content.response.error: " + err)
70 console.log("mediaplayer: replied by connect")
72 connectionID = content.response.mainConnectionID
73 console.log("mediaplayer: mainConnectionID is " + connectionID)
76 case "registerSource":
77 console.log("mediaplayer: replied by registerSource")
79 sourceID = content.response.sourceID
80 registered_media = true
85 function slotEvent(event,msg){
86 var jstr = JSON.stringify(msg)
87 var content = JSON.parse(jstr);
88 var eventName = content.event
89 console.log("mediaplayer: event qml: event" + eventName + " msg: " + jstr)
92 case "soundmanager\/asyncSetSourceState":
93 // This event doesn't come for now
94 console.log("mediaplayer: soundmanager\/asyncSetSourceState")
95 console.log("mediaplayer: my soundID:" + sourceID + "handle:" + content.data.handle + ",sourceID:" + content.data.sourceID + ",sourceState:" + content.data.sourceState)
96 if(sourceID == content.data.sourceID){
97 console.log("mediaplayer: call ackSetSourceState")
98 var arg = JSON.stringify({handle:content.data.handle, error:0})
99 smw.call("ackSetSourceState", arg)
100 switch(content.data.sourceState){
115 case "soundmanager\/asyncConnect":
116 // In reality, device should be opened in this timing
117 if(connectionID == content.data.connectionID){
118 //player.open_device()
121 case "soundmanager\/asyncDisconnect":
122 // In reality, device should be closed in this timing
123 if(connectionID == content.data.connectionID){
124 // player.close_device()
135 running: (bluetooth.av_connected && bluetooth.state == "playing")
138 bluetooth.position = bluetooth.position + 250
139 slider.value = bluetooth.position
145 playbackMode: random.checked ? Playlist.Random : loop.checked ? Playlist.Loop : Playlist.Sequential
152 Layout.fillWidth: true
153 Layout.fillHeight: true
154 Layout.preferredHeight: 1080
158 anchors.left: parent.left
159 anchors.right: parent.right
160 anchors.bottom: parent.bottom
161 height: sourceSize.height * width / sourceSize.width
162 fillMode: Image.PreserveAspectCrop
163 source: player.metaData.coverArtImage ? player.metaData.coverArtImage : ''
164 visible: bluetooth.av_connected == false
168 anchors.left: parent.left
169 anchors.right: parent.right
170 anchors.bottom: parent.bottom
180 anchors.margins: root.width * 0.02
182 Layout.fillWidth: true
183 Layout.fillHeight: true
188 visible: bluetooth.connected == false
189 offImage: './images/AGL_MediaPlayer_Shuffle_Inactive.svg'
190 onImage: './images/AGL_MediaPlayer_Shuffle_Active.svg'
194 visible: bluetooth.connected == false
195 offImage: './images/AGL_MediaPlayer_Loop_Inactive.svg'
196 onImage: './images/AGL_MediaPlayer_Loop_Active.svg'
203 Layout.alignment: Layout.Center
204 text: bluetooth.av_connected ? bluetooth.title : (player.metaData.title ? player.metaData.title : '')
205 horizontalAlignment: Label.AlignHCenter
206 verticalAlignment: Label.AlignVCenter
209 Layout.alignment: Layout.Center
210 text: bluetooth.av_connected ? bluetooth.artist : (player.metaData.contributingArtist ? player.metaData.contributingArtist : '')
211 horizontalAlignment: Label.AlignHCenter
212 verticalAlignment: Label.AlignVCenter
213 font.pixelSize: title.font.pixelSize * 0.6
219 Layout.fillWidth: true
220 to: bluetooth.av_connected ? bluetooth.duration : player.duration
221 enabled: bluetooth.av_connected == false
222 value: bluetooth.av_connected ? bluetooth.position : player.position
223 function getPosition() {
224 if (bluetooth.av_connected) {
225 return player.time2str(bluetooth.position)
227 return player.time2str(player.position)
231 anchors.left: parent.left
232 anchors.bottom: parent.top
234 text: slider.getPosition()
238 anchors.right: parent.right
239 anchors.bottom: parent.top
241 text: bluetooth.av_connected ? player.time2str(bluetooth.duration) : player.time2str(player.duration)
243 onPressedChanged: player.seek(value)
246 Layout.fillHeight: true
248 // source: './images/AGL_MediaPlayer_Playlist_Inactive.svg'
251 // source: './images/AGL_MediaPlayer_CD_Inactive.svg'
253 Item { Layout.fillWidth: true }
256 offImage: './images/AGL_MediaPlayer_BackArrow.svg'
258 if (bluetooth.av_connected) {
259 bluetooth.sendMediaCommand("Previous")
260 bluetooth.position = 0
268 offImage: './images/AGL_MediaPlayer_Player_Play.svg'
270 if (bluetooth.av_connected) {
271 bluetooth.sendMediaCommand("Play")
273 console.log("mediaplayer: registered_media is " + registered_media)
276 console.log("mediaplayer: call connect")
277 var JsonArg = JSON.stringify({sourceID:sourceID, sinkID: 1})
278 smw.call("connect", JsonArg)
284 when: player.playbackState === MediaPlayer.PlayingState
287 offImage: './images/AGL_MediaPlayer_Player_Pause.svg'
289 var JsonArg = JSON.stringify({mainConnectionID: connectionID})
291 smw.call("disconnect",JsonArg)
296 when: bluetooth.av_connected && bluetooth.state == "playing"
299 offImage: './images/AGL_MediaPlayer_Player_Pause.svg'
300 onClicked: bluetooth.sendMediaCommand("Pause")
308 offImage: './images/AGL_MediaPlayer_ForwardArrow.svg'
310 if (bluetooth.av_connected) {
311 bluetooth.sendMediaCommand("Next")
318 Item { Layout.fillWidth: true }
321 visible: bluetooth.connected
322 checked: bluetooth.av_connected
323 offImage: './images/AGL_MediaPlayer_Bluetooth_Inactive.svg'
324 onImage: './images/AGL_MediaPlayer_Bluetooth_Active.svg'
327 if (bluetooth.av_connected) {
328 bluetooth.disconnect_profiles()
330 bluetooth.connect_profiles()
339 Layout.fillWidth: true
340 Layout.fillHeight: true
341 Layout.preferredHeight: 407
343 PlaylistWithMetadata {
351 visible: bluetooth.av_connected == false
359 currentIndex: playlist.currentIndex
361 delegate: MouseArea {
363 width: ListView.view.width
364 height: ListView.view.height / 4
367 anchors.leftMargin: 50
368 anchors.rightMargin: 50
370 source: model.coverArt
371 fillMode: Image.PreserveAspectFit
372 Layout.preferredWidth: delegate.height
373 Layout.preferredHeight: delegate.height
376 Layout.fillWidth: true
378 Layout.fillWidth: true
382 Layout.fillWidth: true
389 text: player.time2str(model.duration)
395 playlist.currentIndex = model.index
396 sourceIndex = model.index;
397 console.log("mediaplayer: call connect")
398 var JsonArg = JSON.stringify({sourceID:sourceID, sinkID: 1})
399 smw.call("connect", JsonArg)
403 highlight: Rectangle {
409 Component.onCompleted: {
410 var media = JSON.stringify({appname:"mediaplayer"})
411 var bta = JSON.stringify({appname:"bluetooth_audio"})
412 smw.call("registerSource",media)