Adding back in tizen.vehicle reference. Also adding a check for which menu should...
[profile/ivi/MediaPlayer.git] / js / audioPlayer.js
1 /*
2  * Copyright (c) 2013, Intel Corporation.
3  *
4  * This program is licensed under the terms and conditions of the
5  * Apache License, version 2.0.  The full text of the Apache License is at
6  * http://www.apache.org/licenses/LICENSE-2.0
7  *
8  */
9
10 var mainArtistText;
11 var songDurationSec;
12
13 AudioPlayer = function()
14 {
15         this.clearAudioTimeInterval = undefined;
16         this.currentAudioContent = undefined;
17 }
18
19 /*
20  * Play function for when play button is clicked
21  */
22
23 AudioPlayer.prototype.play = function()
24 {
25         console.log("MediaPlayer in AudioPlayer::play");
26
27         if (this.currentFileLoaded)
28         {
29                 if (this.playerControls.paused)
30                 {
31                         this.playerControls.play();
32
33                         //Start tracking the current time of the media.  This is used to play from previous position on restart.
34                         //Currently this isn't supported for remote files
35                         if (!this.content[this.listIndex].remoteFile)
36                         {
37                                 var timeoutFunction = function()
38                                 {
39                                         localStorage.prevAudioTime = this.playerControls.currentTime;
40                                         this.updateTrackTime();
41                                 }
42
43                                 this.clearAudioTimeInterval = setInterval(timeoutFunction.bind(this),500);
44                         }
45                 }
46         }
47         else
48                 console.log(this.content[this.listIndex].artists[0] + " : " + this.content[this.listIndex].title + " can't play yet, it hasn't loaded");
49 }
50
51 /*
52  * Pause function for when pause button is clicked
53  */
54
55 AudioPlayer.prototype.pause = function()
56 {
57         if (!this.playerControls.paused)
58         {
59                 this.playerControls.pause();
60                 clearInterval(this.clearAudioTimeInterval);
61         }
62 }
63
64 /*
65  * Next function for when next button is clicked
66  */
67
68 AudioPlayer.prototype.next = function()
69 {
70         if (this.content)
71         {
72                 if (this.content.length > (this.listIndex + 1))
73                         this.listIndex++;
74                 else
75                         this.listIndex = 0;
76
77                 this.load(this.listIndex, true);
78         }
79 }
80
81 /*
82  * Previous function for when previous button is clicked
83  */
84
85 AudioPlayer.prototype.previous = function()
86 {
87         if (this.content)
88         {
89                 if (this.listIndex > 0 )
90                         this.listIndex--;
91                 else
92                         this.listIndex = this.content.length - 1;
93
94                 this.load(this.listIndex, true);
95         }
96 }
97
98 /*
99  * Returns play state
100  */
101
102 AudioPlayer.prototype.playing = function()
103 {
104         return !(this.playerControls.paused);
105 }
106
107 /*
108  * Load the file located at the index.  If play is true, play immediately once file is loaded
109  */
110
111 AudioPlayer.prototype.load = function(index, play)
112 {
113         this.listIndex = index;
114         this.loadAndPlay = play;
115         this.playerControls.pause();
116         this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt);
117         $("#audioSrc").attr("src", this.content[this.listIndex].contentURI);
118         this.playerControls.load();
119 }
120
121 /*
122  * Redraws the media bar with the new artist, title, and cover album
123  */
124
125 AudioPlayer.prototype.updateMediaName = function(newArtist, newTitle, newCover)
126 {
127         playBarHeight = mediaNameCanvas.height;
128         boxWidth = playBarHeight * 0.75;
129         textStartX = boxWidth + 50;
130         songDurationSec = this.playerControls.duration;
131         mediaNameCTX.clearRect(0,0,mediaNameCanvas.width, mediaNameCanvas.height);
132
133         mediaNameCTX.fillStyle="rgba(30,30,30,0.5)";
134         mediaNameCTX.strokeStyle="rgba(130,130,130,1)";
135         mediaNameCTX.lineWidth = 5;
136         mediaNameCTX.fillRect(0,0,mediaNameCanvas.width, playBarHeight);
137         mediaNameCTX.strokeRect(-20,0,mediaNameCanvas.width + 40, playBarHeight);
138
139         if (newCover === undefined || newCover.naturalWidth === undefined || newCover.naturalWidth <= 0)
140         {
141                 newCover = musicIcon;
142         }
143
144         mediaNameCTX.drawImage(newCover, 20, (playBarHeight - boxWidth) / 2, boxWidth, boxWidth);
145
146         if (screenOrientation === "portrait")
147         {
148                 var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 70 , "zLoc" : 0,
149                                                         "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 65, "wordWrap" : true});
150
151                 trackText.applyTemplate(mainMenuTitleTemplate);
152
153                 mainArtistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 70, "zLoc" : 0,
154                                                                 "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 50, "wordWrap" : true});
155
156                 mainArtistText.applyTemplate(mainTrackTemplate);
157         }
158         else
159         {
160                 var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 50 , "zLoc" : 0,
161                                                                 "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true});
162                 trackText.applyTemplate(mainMenuTitleTemplateLandscape);
163                 mainArtistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 50, "zLoc" : 0,
164                                                                 "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true});
165                 mainArtistText.applyTemplate(mainTrackTemplateLandscape);
166         }
167
168         trackText.drawObj();
169         trackText.drawLargeShadow();
170         mainArtistText.yLoc += trackText.height;
171         mainArtistText.drawObj();
172
173         this.updateTrackTime();
174 }
175
176 /*
177  * Redraws the current track time
178  */
179
180 AudioPlayer.prototype.updateTrackTime = function()
181 {
182         playBarHeight = mediaNameCanvas.height;
183         boxWidth = playBarHeight * 0.75;
184         textStartX = boxWidth + 50;
185         var timeText = '';
186         var songDurationSec = Math.floor(this.playerControls.duration % 60) > 9 ? Math.floor(this.playerControls.duration % 60) : '0' + Math.floor(this.playerControls.duration % 60);
187         var songDurationMin = Math.floor(this.playerControls.duration / 60) > 9 ?  Math.floor(this.playerControls.duration / 60) : '0' +  Math.floor(this.playerControls.duration / 60);
188         var songCurrentMin = Math.floor(this.playerControls.currentTime / 60) > 9 ? Math.floor(this.playerControls.currentTime / 60) :  '0' + Math.floor(this.playerControls.currentTime / 60);
189         var songCurrentSec = Math.floor(this.playerControls.currentTime % 60) > 9 ? Math.floor(this.playerControls.currentTime % 60) : '0' + Math.floor(this.playerControls.currentTime % 60);
190
191         if ((songCurrentMin !== undefined && songCurrentSec !== undefined) && (!isNaN(songCurrentMin) && !isNaN(songCurrentSec)))
192                 timeText += songCurrentMin + ':' + songCurrentSec + ' / ';
193         else
194                 timeText += "00:00 / ";
195
196         if ((songDurationSec !== undefined && songDurationMin !== undefined) && (!isNaN(songDurationMin) && !isNaN(songDurationSec)))
197                 timeText += songDurationMin + ':' + songDurationSec;
198         else
199                 timeText += "00:00";
200
201         var trackTimeText = new TextObject(trackTimeCTX,{"text" : timeText, "xLoc" : textStartX, "yLoc" : 50, "zLoc" : 0,
202                                                                 "width" : mediaNameCanvas.width - textStartX, "height" : 20, "lineHeight" : 20, "wordWrap" : false});
203
204         if (screenOrientation === "portrait")
205         {
206                 trackTimeText.applyTemplate(timeTemplate);
207         }
208         else
209                 trackTimeText.applyTemplate(timeTemplateLandscape);
210
211         trackTimeCTX.clearRect(0, 0, trackTimeCanvas.width, trackTimeCanvas.height);
212
213         trackTimeText.yLoc = ((playBarHeight - boxWidth) / 2) + boxWidth;
214         trackTimeText.drawObj();
215 }
216
217 /*
218  * Plays the currently loaded media file
219  */
220
221 AudioPlayer.prototype.playLoadedMedia = function()
222 {
223         console.log("MediaPlayer in playLoadedMedia");
224         this.currentFileLoaded = true;
225
226         //Only store track to localStorage if it's a local file, and current menu is the Audio menu
227         if (!this.content[this.listIndex].remoteFile && localStorage.prevMenu === "mainMusicButton")
228         {
229                 localStorage.prevAudioTrack = this.content[this.listIndex].contentURI;
230         }
231         else
232         {
233                 localStorage.prevAudioTime = undefined;
234                 localStorage.prevAudioTrack = undefined;
235         }
236
237         this.currentAudioContent = this.content[this.listIndex];
238
239         if (this.loadPrevAudio)
240         {
241                 this.playerControls.currentTime = localStorage.prevAudioTime;
242                 this.loadPrevAudio = false;
243                 this.play();
244         }
245
246         if (this.loadAndPlay)
247         {
248                 this.play();
249                 this.loadAndPlay = false;
250         }
251
252         this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt);
253         this.currentFileLoaded = true;
254 }
255
256 /*
257  * Sort the file list alphabetically
258  */
259
260 AudioPlayer.prototype.sortByAlpha = function()
261 {
262         console.log("MediaPlayer in sortByAlpha");
263
264         this.emptyTimeouts();
265
266         this.content.sort(function (a,b)
267         {
268                 var first = a.title.toLowerCase();
269                 var second = b.title.toLowerCase();
270
271                 if (first < second)
272                         return -1;
273                 if (first > second)
274                         return 1;
275
276                 return 0;
277         });
278
279         this.fillMediaList();
280 }
281
282 /*
283  * Sort the file list by artist name
284  */
285
286 AudioPlayer.prototype.sortByArtist = function()
287 {
288         console.log("MediaPlayer in sortByArtist");
289
290         this.emptyTimeouts();
291
292         this.content.sort(function (a,b)
293         {
294                 var first = a.artists[0].toLowerCase();
295                 var second = b.artists[0].toLowerCase();
296
297                 if (first < second)
298                         return -1;
299                 if (first > second)
300                         return 1;
301
302                 return 0;
303         });
304
305         this.fillMediaList();
306 }
307
308 /*
309  * Sort the file list by album name
310  */
311
312 AudioPlayer.prototype.sortByAlbum =function()
313 {
314         console.log("MediaPlayer in sortByAlbum");
315
316         this.emptyTimeouts();
317
318         this.content.sort(function (a,b)
319         {
320                 var first = a.album.toLowerCase();
321                 var second = b.album.toLowerCase();
322
323                 if (first < second)
324                         return -1;
325                 if (first > second)
326                         return 1;
327
328                 return 0;
329         });
330
331         this.fillMediaList();
332 }
333
334 /*
335  * Callback for when the local content has been successfully read using tizen.content.
336  */
337
338 AudioPlayer.prototype.onContentLoaded = function()
339 {
340         try
341         {
342                 if (localStorage.prevAudioTrack && localStorage.prevAudioTrack !== "undefined")
343                 {
344                         for (var i = 0; i < this.content.length; i++)
345                         {
346
347                                 if (this.content[i].contentURI === localStorage.prevAudioTrack)
348                                 {
349                                         this.listIndex = i;
350                                         console.log("MediaPlayer: Previous audio found, loading " + this.content[this.listIndex].contentURI);
351                                         this.loadPrevAudio = true;
352                                         this.fillMediaList();
353                                         this.load(i, true);
354                                 }
355                         }
356                 }
357                 else
358                 {
359                         console.log("MediaPlayer: No previous audio found, loading first");
360                         this.load(0, false);
361                         this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt);
362
363                         if (currentMenu === "audio")
364                                 this.fillMediaList();
365                 }
366
367                 var imgSources = [];
368
369                 for (var i = 0; i < this.content.length; i++)
370                 {
371                         var iconURI = (this.content[i].thumbnailURIs !== undefined && this.content[i].thumbnailURIs !== null) ? this.content[i].thumbnailURIs[0] : "images/musicIcon.png";
372                         this.content[i].coverArtURI = iconURI;
373                 }
374
375                 loadImages();
376         }
377         catch (err)
378         {
379                 console.log("MediaPlayer: Error when parsing audioContent");
380         }
381 }
382
383 /*
384  * Create and draw an item in the media list
385  */
386
387 AudioPlayer.prototype.makeListItem = function(j, k)
388 {
389         var canvasH = mediaListItemH * 0.95 ;
390
391     for (var i = j; (i < (j+k) && i < this.content.length); i++)
392     {
393                 if (typeof this.content[i].title !== "string")
394                         this.content[i].title = "Unknown";
395
396             //Check if album art is done loading, if not draw default until it is
397              if (this.content[i].artists === undefined)
398              {
399                 this.content[i].artists = new Array();
400                 this.content[i].artists[0] = "Unknown";
401              }
402
403              else if (typeof this.content[i].artists[0] !== "string")
404                         this.content[i].artists[0] = "Unknown";
405
406             var trackText = {"text" : this.content[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0};
407             var artistText = {"text" : this.content[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0};
408
409             if (this.content[i].coverArt && this.content[i].coverArt.complete && (this.content[i].coverArt.naturalWidth !== 0 || this.content[i].coverArt.naturalHeight !== 0) )
410                 this.makeListBar(this.content[i].coverArt, i, artistText, trackText);
411             else
412                 this.makeListBar(musicIcon, i, artistText, trackText);
413
414                 // Set callback function for the new list item
415                 $("#" + this.type + "CanvasNum" + i).click(function () {
416                         try
417                         {
418                                 audioPlayer.load($(this).parent().parent().index(), true);
419                         }
420                         catch(err)
421                         {
422                                 console.log("MediaPlayer: load audio error " + err.message);
423                         }
424                 });
425     }
426 }