From: brianjjones Date: Thu, 10 Oct 2013 20:46:26 +0000 (-0700) Subject: Re-organizing the code so that the players are object based. X-Git-Tag: submit/tizen_ivi_genivi/20140131.070555 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=8501f7059d8e7f75b2ef6221eee2ef08ebdbb691;p=profile%2Fivi%2FMediaPlayer.git Re-organizing the code so that the players are object based. Adding code to remember what page you were on as well as the previous media Signed-off-by: brianjjones Change-Id: I50598dfa71b59ad5c67aa68415933ff497c98e36 --- diff --git a/css/main.css b/css/main.css index dbe5ee9..e161441 100644 --- a/css/main.css +++ b/css/main.css @@ -21,16 +21,19 @@ html #mainMusicButton { + display:none; content:url(../images/musicButton.png); } #mainVideoButton { + display:none; content:url(../images/videoButton.png); } #mainImageButton { + display:none; content:url(../images/imageButton.png); } @@ -118,6 +121,11 @@ html height: 10%; } +#mediaName +{ + display:none; +} + #audioPlayer { position:absolute; diff --git a/index.html b/index.html index 594944c..709da72 100644 --- a/index.html +++ b/index.html @@ -13,6 +13,10 @@ + + + + diff --git a/js/audioPlayer.js b/js/audioPlayer.js new file mode 100644 index 0000000..49e30f0 --- /dev/null +++ b/js/audioPlayer.js @@ -0,0 +1,340 @@ +/* + * Copyright (c) 2013, Intel Corporation. + * + * This program is licensed under the terms and conditions of the + * Apache License, version 2.0. The full text of the Apache License is at + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ + +AudioPlayer = function() +{ + this.clearAudioTimeInterval = undefined; + this.currentAudioContent = undefined; +} + +AudioPlayer.prototype.play = function() +{ + console.log("MediaPlayer in AudioPlayer::play"); + + if (this.currentFileLoaded) + { + if (this.playerControls.paused) + { + this.playerControls.play(); + + //Start tracking the current time of the media. This is used to play from previous position on restart. + //Currently this isn't supported for remote files + if (!this.content[this.listIndex].remoteFile) + { + var timeoutFunction = function() + { + localStorage.prevAudioTime = this.playerControls.currentTime; + } + + this.clearAudioTimeInterval = setInterval(timeoutFunction.bind(this),500); + } + } + else + { + this.pause(); + } + } + else + console.log(this.content[this.listIndex].artists[0] + " : " + this.content[this.listIndex].title + " can't play yet, it hasn't loaded"); +} + +AudioPlayer.prototype.pause = function() +{ + if (!this.playerControls.paused) + { + this.playerControls.pause(); + clearInterval(this.clearAudioTimeInterval); + } +} + +AudioPlayer.prototype.playing = function() +{ + return !(this.playerControls.paused); +} + +AudioPlayer.prototype.next = function() +{ + if (this.content) + { + if (this.content.length > (this.listIndex + 1)) + this.listIndex++; + else + this.listIndex = 0; + + this.load(this.listIndex, true); + } +} + +AudioPlayer.prototype.previous = function() +{ + if (this.content) + { + if (this.listIndex > 0 ) + this.listIndex--; + else + this.listIndex = this.content.length - 1; + + this.load(this.listIndex, true); + } +} + +AudioPlayer.prototype.load = function(index, play) +{ + this.listIndex = index; + this.loadAndPlay = play; + this.playerControls.pause(); + this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt); + $("#audioSrc").attr("src", this.content[this.listIndex].contentURI); + + if (!this.content[this.listIndex].remoteFile) + { + localStorage.prevAudioTrack = this.content[this.listIndex].contentURI; + } + else + { + localStorage.prevAudioTime = undefined; + localStorage.prevAudioTrack = undefined; + } + + this.playerControls.load(); +} + +AudioPlayer.prototype.updateMediaName = function(newArtist, newTitle, newCover) +{ + var playBarHeight = mediaNameCanvas.height; + var boxWidth = playBarHeight * 0.75; + mediaNameCTX.clearRect(0,0,mediaNameCanvas.width, mediaNameCanvas.height); + + var shadeJump = 10; + var alphaJump = 0.01; + var currColor = 255; + var currAlpha = 1.0; + + mediaNameCTX.fillStyle="rgba(30,30,30,0.5)"; + mediaNameCTX.strokeStyle="rgba(130,130,130,1)"; + mediaNameCTX.lineWidth = 5; + mediaNameCTX.fillRect(0,0,mediaNameCanvas.width, playBarHeight); + mediaNameCTX.strokeRect(-20,0,mediaNameCanvas.width + 40, playBarHeight); + + if (newCover === undefined || newCover.naturalWidth === undefined || newCover.naturalWidth <= 0) + { + newCover = musicIcon; + } + + mediaNameCTX.drawImage(newCover, 20, (playBarHeight - boxWidth) / 2, boxWidth, boxWidth); + + if (screenOrientation === "portrait") + { + var textStartX = boxWidth + 50; + + var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 70 , "zLoc" : 0, + "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 65, "wordWrap" : true}); + + trackText.applyTemplate(mainMenuTitleTemplate); + + var artistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 70, "zLoc" : 0, + "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 50, "wordWrap" : true}); + + artistText.applyTemplate(mainTrackTemplate); + } + else + { + var textStartX = boxWidth + 50; + var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 50 , "zLoc" : 0, + "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true}); + trackText.applyTemplate(mainMenuTitleTemplateLandscape); + var artistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 50, "zLoc" : 0, + "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true}); + artistText.applyTemplate(mainTrackTemplateLandscape); + } + + trackText.drawObj(); + trackText.drawLargeShadow(); + artistText.yLoc += trackText.height; + artistText.drawObj(); +} + +AudioPlayer.prototype.playLoadedMedia = function() +{ + console.log("MediaPlayer in playLoadedMedia"); + this.currentFileLoaded = true; + + this.currentAudioContent = this.content[this.listIndex]; + + if (this.loadPrevAudio) + { + this.playerControls.currentTime = localStorage.prevAudioTime; + this.loadPrevAudio = false; + this.play(); + } + + if (this.loadAndPlay) + { + this.play(); + this.loadAndPlay = false; + } + + this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt); + this.currentFileLoaded = true; +} + + +AudioPlayer.prototype.sortByAlpha = function() +{ + console.log("MediaPlayer in sortByAlpha"); + + this.emptyTimeouts(); + + this.content.sort(function (a,b) + { + var first = a.title.toLowerCase(); + var second = b.title.toLowerCase(); + + if (first < second) + return -1; + if (first > second) + return 1; + + return 0; + }); + + this.fillMediaList(); +} + +AudioPlayer.prototype.sortByArtist = function() +{ + console.log("MediaPlayer in sortByArtist"); + + this.emptyTimeouts(); + + this.content.sort(function (a,b) + { + var first = a.artists[0].toLowerCase(); + var second = b.artists[0].toLowerCase(); + + if (first < second) + return -1; + if (first > second) + return 1; + + return 0; + }); + + this.fillMediaList(); +} + +AudioPlayer.prototype.sortByAlbum =function() +{ + console.log("MediaPlayer in sortByAlbum"); + + this.emptyTimeouts(); + + this.content.sort(function (a,b) + { + var first = a.album.toLowerCase(); + var second = b.album.toLowerCase(); + + if (first < second) + return -1; + if (first > second) + return 1; + + return 0; + }); + + this.fillMediaList(); +} + +AudioPlayer.prototype.onContentLoaded = function() +{ + try + { + if (localStorage.prevAudioTrack && localStorage.prevAudioTrack !== "undefined") + { + for (var i = 0; i < this.content.length; i++) + { + + if (this.content[i].contentURI === localStorage.prevAudioTrack) + { + this.listIndex = i; + console.log("MediaPlayer: Previous audio found, loading " + this.content[this.listIndex].contentURI); + this.loadPrevAudio = true; + $("#audioSrc").attr("src", this.content[this.listIndex].contentURI); + this.playerControls.load(); + this.fillMediaList(); + } + } + } + else + { + console.log("MediaPlayer: No previous audio found, loading first"); + $("#audioSrc").attr("src", this.content[0].contentURI); + localStorage.prevAudioTrack = this.content[0].contentURI; + this.playerControls.load(); + this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt); + + if (currentMenu === "audio") + this.fillMediaList(); + } + + var imgSources = []; + + for (var i = 0; i < this.content.length; i++) + { + var iconURI = (this.content[i].thumbnailURIs !== undefined && this.content[i].thumbnailURIs !== null) ? this.content[i].thumbnailURIs[0] : "images/musicIcon.png"; + this.content[i].coverArtURI = iconURI; + } + + loadImages(); + } + catch (err) + { + console.log("MediaPlayer: Error when parsing audioContent"); + } +} + +AudioPlayer.prototype.redrawMediaName = function() +{ + this.updateMediaName(this.content[this.listIndex].artists[0], this.content[this.listIndex].title, this.content[this.listIndex].coverArt); +} + +AudioPlayer.prototype.makeListItem = function(j, k) +{ + var canvasH = mediaListItemH * 0.95 ; + + for (var i = j; (i < (j+k) && i < this.content.length); i++) + { + //Check if album art is done loading, if not draw default until it is + if (this.content[i].artists === undefined) + { + this.content[i].artists = new Array(); + this.content[i].artists[0] = "Unknown"; + } + + var trackText = {"text" : this.content[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0}; + var artistText = {"text" : this.content[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0}; + + if (this.content[i].coverArt && this.content[i].coverArt.complete) + this.makeListBar(this.content[i].coverArt, i, artistText, trackText); + else + this.makeListBar(musicIcon, i, artistText, trackText); + + // Set callback function for the new list item + $("#" + this.type + "CanvasNum" + i).click(function () { + try + { + audioPlayer.load($(this).parent().parent().index(), true); + } + catch(err) + { + console.log("MediaPlayer: load audio error " + err.message); + } + }); + } +} diff --git a/js/dlna.js b/js/dlna.js index 41fab32..64b6a15 100644 --- a/js/dlna.js +++ b/js/dlna.js @@ -82,6 +82,9 @@ function findAllCallback(medias) stopConnectionSearch = undefined; var itemsAdded = 0; + var audioContent = new Array(); + var videoContent = new Array(); + var imageContent = new Array(); for (var i=0; i < medias.length; i++) { @@ -89,22 +92,22 @@ function findAllCallback(medias) if (current) { - switch(current.type) - { - case "AUDIO": - audioContent.push(current); - itemsAdded += 1; - break; - case "VIDEO": - videoContent.push(current); - itemsAdded += 1; - break; - case "IMAGE": - imageContent.push(current); - itemsAdded += 1; - break; - default: - } + switch(current.type) + { + case "AUDIO": + audioContent.push(current); + itemsAdded += 1; + break; + case "VIDEO": + videoContent.push(current); + itemsAdded += 1; + break; + case "IMAGE": + imageContent.push(current); + itemsAdded += 1; + break; + default: + } } } @@ -112,13 +115,10 @@ function findAllCallback(medias) audioMediaListLoaded = false; videoMediaListLoaded = false; imageMediaListLoaded = false; -} -function restartMedia (medias) -{ - clearInterval(stopConnectionSearch); - loadPrevVideo = true; - $("#videoSrc").attr("src", videoContent[videoIndex].contentURI); + audioPlayer.updateContent(audioContent, true); + videoPlayer.updateContent(videoContent, true); + imagePlayer.updateContent(imageContent, true); } function foundMediaServer(srv) @@ -135,22 +135,13 @@ function foundMediaServer(srv) srv.browse(srv.root.id, "+DisplayName", 0, 0, browseCallback); srv.find(srv.root.id, "*", "+DisplayName", 0, 0, findAllCallback); - if (stopConnectionSearch !== undefined) - clearInterval(stopConnectionSearch); + // Removing this for now to keep from spamming. Note Rygel must be running when launched or it will never find it + // if (stopConnectionSearch !== undefined) + // clearInterval(stopConnectionSearch); - stopConnectionSearch = setInterval(function(){console.log("MediaPlayer searching for remote media..."); tizen.mediaserver.scanNetwork(foundMediaServer);}, 3000); - } - else - console.log("MediaServer not browsable"); -} + // stopConnectionSearch = setInterval(function(){console.log("MediaPlayer searching for remote media..."); tizen.mediaserver.scanNetwork(foundMediaServer);}, 3000); -function reconnectServer(srv) -{ - if (srv.root) - { - srv.find(srv.root.id, "*", "+DisplayName", 0, 0, restartMedia); - stopConnectionSearch = setInterval(function(){console.log("MediaPlayer searching for remote media for reconnect..."); tizen.mediaserver.scanNetwork(reconnectServer);}, 1000); } else - console.log("MediaServer not reloadable"); + console.log("MediaServer not browsable"); } diff --git a/js/imagePlayer.js b/js/imagePlayer.js new file mode 100644 index 0000000..9733323 --- /dev/null +++ b/js/imagePlayer.js @@ -0,0 +1,108 @@ + +/* + * Copyright (c) 2013, Intel Corporation. + * + * This program is licensed under the terms and conditions of the + * Apache License, version 2.0. The full text of the Apache License is at + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ + +ImagePlayer = function() +{ + +} + +ImagePlayer.prototype.play = function() +{ + console.log("MediaPlayer in ImagePlayer::play"); + if (this.playerControls.paused) + this.playerControls.play(); +} + +ImagePlayer.prototype.pause = function() +{ + if (!this.playerControls.paused) + this.playerControls.pause(); +} + +ImagePlayer.prototype.playing = function() +{ + return !(this.playerControls.paused); +} + +ImagePlayer.prototype.next = function() +{ + if (this.content) + { + if (this.content.length > (this.listIndex + 1)) + this.listIndex++; + else + this.listIndex = 0; + + $("#imagePlayer").css("background", "url(" + this.content[this.listIndex].contentURI + ") no-repeat center"); + $("#imagePlayer").css("background-size", "contain"); + } +} + +ImagePlayer.prototype.previous = function() +{ + if (this.content) + { + if (this.listIndex > 0 ) + this.listIndex--; + else + this.listIndex = this.content.length - 1; + + $("#imagePlayer").css("background", "url(" + this.content[this.listIndex].contentURI + ") no-repeat center"); + $("#imagePlayer").css("background-size", "contain"); + } +} + +ImagePlayer.prototype.onContentLoaded = function() +{ + try + { + $("#imagePlayer").css("background", "url(" + this.content[0].contentURI + ") no-repeat center"); + $("#imagePlayer").css("background-size", "contain"); + } + + catch (err) + { + console.log("MediaPlayer: Error when parsing imageContent"); + } +} + +ImagePlayer.prototype.load = function(index) +{ + this.listIndex = index; + $("#imagePlayer").css("background", "url(" + this.content[this.listIndex].contentURI + ") no-repeat center"); + $("#imagePlayer").css("background-size", "contain"); +} + +ImagePlayer.prototype.makeListItem = function(j, k) +{ + var canvasH = mediaListItemH * 0.95 ; + + for (var i = j; (i < (j+k) && i < this.content.length); i++) + { + var artistText = {"text" : this.content[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0}; + var trackText = {"text" : " ", "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0}; + + this.makeListBar(imgIcon, i, artistText, trackText); + + // Set callback function for the new list item + $("#" + this.type + "CanvasNum" + i).click(function () { + + try + { + imagePlayer.load($(this).parent().parent().index()); + $("#imageMediaList").hide(); + } + catch(err) + { + console.log("MediaPlayer: load image error: " + err.message); + } + }); + } +} diff --git a/js/listFunctions.js b/js/listFunctions.js index 2994825..f5960ed 100644 --- a/js/listFunctions.js +++ b/js/listFunctions.js @@ -7,43 +7,41 @@ * */ -//Audio list can be re-ordered while filling. -//This requires cancelling all previous timeouts to properly fill -var clearAudioTimeouts = new Array(); -var lightColor = false; - function mediaError() { console.log("MediaPlayer: file failed to load"); } -var drawCanvasImage = function(imageSrc) { - return function() { +var drawCanvasImage = function(imageSrc) +{ + return function() + { drawAlbumArt(imageSrc); } } function drawAlbumArt(imageSrc) { - if (currentPlayerType === "AUDIO") + var canvasH = mediaListItemH * 0.95 ; + var audioContent = audioPlayer.getContent(); + + for (var i=0; i < audioContent.length; i++) { - var canvasH = mediaListItemH * 0.95 ; - for (var i in audioContent) + if (audioContent[i].coverArt.src !== musicIcon.src && audioContent[i].coverArt.src === imageSrc) { - if (audioContent[i].coverArt.src !== musicIcon.src && audioContent[i].coverArt.src === imageSrc && audioContent[i].ctx) + try { - try - { - if (i == audioIndex) - { - updateMediaName(audioContent[audioIndex].artists[0], audioContent[audioIndex].title, audioContent[audioIndex].coverArt); - } - audioContent[i].ctx.drawImage(audioContent[i].coverArt, 0, 0, canvasH, canvasH); - } - catch(err) + if (i === audioPlayer.currentIndex()) { - console.log("MediaPlayer: drawImage failed - " + err); + audioPlayer.updateMediaName(audioContent[audioPlayer.currentIndex()].artists[0], audioContent[audioPlayer.currentIndex()].title, audioContent[audioPlayer.currentIndex()].coverArt); } + + if(audioContent[i].ctx) + audioContent[i].ctx.drawImage(audioContent[i].coverArt, 0, 0, canvasH, canvasH); + } + catch(err) + { + console.log("MediaPlayer: drawImage failed - " + err); } } } @@ -53,6 +51,8 @@ function loadImages() { console.log("MediaPlayer in loadImages"); + var audioContent = audioPlayer.getContent(); + for (var src in audioContent) { try @@ -73,223 +73,3 @@ function loadImages() } } } - -function makeListItem(j, k, contentList, playerType, listItems) -{ - var iconURI; - var currentCanvas; - var canvasW = mediaListItemW; - var canvasH = mediaListItemH * 0.95 ; - var lowerType = playerType.toLowerCase(); - - for (var i = j; (i < (j+k) && i < contentList.length); i++) - { - - if ((i+1)%2 === 0) - { - if (nightMode) - { - - listItems.append("
  • " + - " " + - "
  • " - ); - } - else - { - listItems.append("
  • " + - " " + - "
  • " - ); - } - } - else - { - if (nightMode) - { - listItems.append("
  • " + - " " + - "
  • " - ); - } - else - { - listItems.append("
  • " + - " " + - "
  • " - ); - } - - } - - lightColor = !lightColor; - - var currentCanvas = document.getElementById(lowerType + "CanvasNum" + i); - var currentCTX = currentCanvas.getContext("2d"); - - // Set callback function for the new list item - $("#" + lowerType + "CanvasNum" + i).click(function () { - - $("#playButton").toggleClass('playing', false); - - switch (playerType) - { - case "AUDIO": - try - { - audioIndex = $(this).parent().parent().index(); - loadAndPlay = true; - updateMediaName(audioContent[audioIndex].artists[0], audioContent[audioIndex].title, audioContent[audioIndex].coverArt); - $("#audioSrc").attr("src", audioContent[audioIndex].contentURI); - localStorage.prevAudioTrack = audioContent[audioIndex].contentURI; - audioPlayer.load(); - } - catch(err) - { - console.log("MediaPlayer: load audio error " + err.message); - } - break; - - case "VIDEO": - try - { - videoIndex = $(this).parent().parent().index(); - $("#videoSrc").attr("src", videoContent[videoIndex].contentURI); - localStorage.prevVideo = videoContent[videoIndex].contentURI; - videoPlayer.load(); - currentMediaList.fadeOut(300); - } - catch(err) - { - console.log("MediaPlayer: load video error " + err.message); - } - break; - - case "IMAGE": - try - { - imageIndex = $(this).parent().parent().index(); - $("#imagePlayer").css("background", "url(" + imageContent[imageIndex].contentURI + ") no-repeat center"); - $("#imagePlayer").css("background-size", "contain"); - currentMediaList.fadeOut(300); - } - catch(err) - { - console.log("MediaPlayer: load image error: " + err.message); - } - break; - - default: - break; - } - }); - - switch (playerType) - { - case "AUDIO": - - audioContent[i].ctx = currentCTX; - - try - { - //Check if album art is done loading, if not draw default until it is - if (audioContent[i].coverArt.complete) - currentCTX.drawImage(audioContent[i].coverArt, 0, 0, canvasH, canvasH ); - else - currentCTX.drawImage(musicIcon, 0, 0, canvasH, canvasH ); - } - catch(err) - { - console.log("MediaPlayer: drawImage failed - " + err); - } - - var trackText = new TextObject(currentCTX,{"text" : contentList[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0}); - var artistText = new TextObject(currentCTX,{"text" : contentList[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0}); - clearAudioTimeouts.splice(0, 1); - break; - - case "VIDEO": - currentCTX.drawImage(vidIcon, 0, 0, canvasH, canvasH ); - var artistText = new TextObject(currentCTX,{"text" : contentList[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0}); - var trackText = new TextObject(currentCTX,{"text" : contentList[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0}); - break; - - case "IMAGE": - currentCTX.drawImage(imgIcon, 0, 0, canvasH, canvasH ); - var artistText = new TextObject(currentCTX,{"text" : contentList[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0}); - var trackText = new TextObject(currentCTX,{"text" : " ", "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0}); - break; - - default: - break; - } - - var mediaTextTemp1 = screenOrientation === "portrait" ? mediaTextTemplate2 : mediaTextTemplate2Landscape; - var mediaTextTemp2 = screenOrientation === "portrait" ? mediaTextTemplate3 : mediaTextTemplate3Landscape; - var trackTextTemp = screenOrientation === "portrait" ? trackTextTemplate : trackTextTemplateLandscape; - - trackText.applyTemplate(mediaTextTemp1); - trackText.drawObj(); - trackText.applyTemplate(mediaTextTemp2); - trackText.drawObj(); - - artistText.applyTemplate(trackTextTemp); - artistText.drawObj(); - } -} - -function emptyTimeouts() -{ - var clearItem; - - while (clearItem = clearAudioTimeouts.pop()) - { - clearTimeout(clearItem); - } -} - -function fillMediaList(contentList) -{ - console.log("MediaPlayer in fillMediaList"); - - //Don't try and fill an empty content list - if (contentList === undefined || contentList === null || contentList.length <=0) - return false; - - if (currentPlayerType === "AUDIO") - emptyTimeouts(); - - currentMediaListItems.empty(); - var timeOut = 1; - - switch (currentPlayerType) - { - case "AUDIO": - audioMediaListLoaded = true; - break; - case "VIDEO": - videoMediaListLoaded = true; - break; - case "IMAGE": - imageMediaListLoaded = true; - break; - default: - break; - } - - var jumpSize = 1; - var tmpClearTimeout; - - for (var i=0; i < contentList.length; i++) - { - tmpClearTimeout = setTimeout(makeListItem.bind(this, i, jumpSize, contentList, currentPlayerType, currentMediaListItems), timeOut); - clearAudioTimeouts.push(tmpClearTimeout); - - timeOut += 50; - i+=jumpSize - 1; - } -} diff --git a/js/main.js b/js/main.js index cb947db..5797327 100644 --- a/js/main.js +++ b/js/main.js @@ -16,44 +16,27 @@ var screenOrientation; var iconWidth; var padding; var contentType = "AUDIO"; -var audioContent = new Array(); -var videoContent = new Array(); -var imageContent = new Array(); -var currentContent; var currentPlayer; -var currentPlayerType = "AUDIO"; var currentMediaList = $("#audioMediaList"); -var currentMediaListItems = $("#audioMediaListItems"); -var currentPlayerControls; -var audioPlayerControls; -var videoPlayerControls; var audioMediaListLoaded = false; var videoMediaListLoaded = false; var imageMediaListLoaded = false; var audioPlayer; var videoPlayer; -var audioIndex = 0; -var videoIndex = 0; -var imageIndex = 0; +var imagePlayer; var vidIcon = new Image(); var imgIcon = new Image(); var musicIcon = new Image(); var imagesLoaded = false; var mediaListItemW; var mediaListItemH; -var imageControls; -var loadAndPlay = false; -var loadPrevAudio = false; -var loadPrevVideo = false; var playOnConnect = false; -var currentFileLoaded = false; var mediaNameCanvas; var mediaNameCTX; var speechObj; var nightMode = false; var waitingToResumeVideo = false; //Media has been paused by exterior forces. If set to true, resume previous media when given the signal. var stopServerSearch; -var clearAudioTimeInterval, clearVideoTimeInterval; var mainMenuTitleTemplateLandscape = {"font" : "oblique bolder 30pt arial", "lineWidth" : 9.5, "fillStyle" : "black", "strokeStyle" : "white", "textAlign" : "left", "largeShadow" : 8, "shadowOffsetX" : 0, "shadowOffsetY" : 0, "shadowBlur" : 45, "shadowColor" : "rgba(255, 187, 0, 0.4)"}; @@ -158,232 +141,91 @@ function setupSpeech() } -function updateMediaName(newArtist, newTitle, newCover) +function onAudioContentLoaded(newContent) { - if (currentMenu === "audio") + if (!newContent || newContent.length === 0) { - var playBarHeight = mediaNameCanvas.height; - var boxWidth = playBarHeight * 0.75; - mediaNameCTX.clearRect(0,0,mediaNameCanvas.width, mediaNameCanvas.height); - - if (currentPlayerType === "AUDIO") - { - var shadeJump = 10; - var alphaJump = 0.01; - var currColor = 255; - var currAlpha = 1.0; - - mediaNameCTX.fillStyle="rgba(30,30,30,0.5)"; - mediaNameCTX.strokeStyle="rgba(130,130,130,1)"; - mediaNameCTX.lineWidth = 5; - mediaNameCTX.fillRect(0,0,mediaNameCanvas.width, playBarHeight); - mediaNameCTX.strokeRect(-20,0,mediaNameCanvas.width + 40, playBarHeight); - - if (newCover === undefined || newCover.naturalWidth === undefined || newCover.naturalWidth <= 0) - { - newCover = musicIcon; - } - - mediaNameCTX.drawImage(newCover, 20, (playBarHeight - boxWidth) / 2, boxWidth, boxWidth); - - if (screenOrientation === "portrait") - { - var textStartX = boxWidth + 50; - - var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 70 , "zLoc" : 0, - "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 65, "wordWrap" : true}); - trackText.applyTemplate(mainMenuTitleTemplate); - - var artistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 70, "zLoc" : 0, - "width" : mediaNameCanvas.width - textStartX, "height" : 50, "lineHeight" : 50, "wordWrap" : true}); - artistText.applyTemplate(mainTrackTemplate); - } - else - { - var textStartX = boxWidth + 50; - var trackText = new TextObject(mediaNameCTX,{"text" : newTitle, "xLoc" : textStartX, "yLoc" : 50 , "zLoc" : 0, - "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true}); - trackText.applyTemplate(mainMenuTitleTemplateLandscape); - var artistText = new TextObject(mediaNameCTX,{"text" : newArtist, "xLoc" : textStartX, "yLoc" : 50, "zLoc" : 0, - "width" : mediaNameCanvas.width - textStartX, "height" : 30, "lineHeight" : 30, "wordWrap" : true}); - artistText.applyTemplate(mainTrackTemplateLandscape); - } - - trackText.drawObj(); - trackText.drawLargeShadow(); - - artistText.yLoc += trackText.height; - artistText.drawObj(); - } + console.log("MediaPlayer: some content failed to load, trying again for " + audioPlayer.type); + audioPlayer.clearContent(); + setTimeout(function(){getMedia(onAudioContentLoaded, "AUDIO");}, 3000); + return; + } + else + { + audioPlayer.updateContent(newContent, true); + audioPlayer.onContentLoaded(); } } -function onContentItemArraySuccess(content) +function onVideoContentLoaded(newContent) { - console.log("MediaPlayer in onContentItemArraySuccess"); - var emptyContent = true; - - if (!content || content === undefined || content.length <= 0) - console.log("Invalid content for " + contentType); + if (!newContent || newContent.length === 0) + { + console.log("MediaPlayer: some content failed to load, trying again for " + videoPlayer.type); + videoPlayer.clearContent(); + setTimeout(function(){getMedia(onVideoContentLoaded, "VIDEO");}, 3000); + return; + } else { - emptyContent = false; + videoPlayer.updateContent(newContent, true); + videoPlayer.onContentLoaded(); } +} - switch (contentType) +function onImageContentLoaded(newContent) +{ + if (!newContent || newContent.length === 0) { - case "AUDIO": - - if (!emptyContent) - { - try - { - audioContent = audioContent.concat(content); - - if (localStorage.prevAudioTrack) - { - for (var i = 0; i < audioContent.length; i++) - { - - if (audioContent[i].contentURI === localStorage.prevAudioTrack) - { - - audioIndex = i; - loadPrevAudio = true; - $("#audioSrc").attr("src", audioContent[audioIndex].contentURI); - audioPlayer.load(); - break; - } - } - } - else - { - $("#audioSrc").attr("src", audioContent[0].contentURI); - localStorage.prevAudioTrack = audioContent[0].contentURI; - audioPlayer.load(); - } - - var imgSources = []; - for (var i = 0; i < audioContent.length; i++) - { - var iconURI = (audioContent[i].thumbnailURIs !== undefined && audioContent[i].thumbnailURIs !== null) ? audioContent[i].thumbnailURIs[0] : "images/musicIcon.png"; - audioContent[i].coverArtURI = iconURI; - } - - loadImages(); - - audioMediaListLoaded = true; - currentMediaListItems = $("#audioMediaListItems"); - fillMediaList(audioContent); - } - - catch (err) - { - console.log("Error when parsing audioContent"); - } - } - - contentType = "VIDEO"; - break; - - case "VIDEO": - if (!emptyContent) - { - videoContent = videoContent.concat(content); - - if (localStorage.prevVideo) - { - for (var i = 0; i < videoContent.length; i++) - { - if (videoContent[i].contentURI === localStorage.prevVideo) - { - videoIndex = i; - loadPrevVideo = true; - $("#videoSrc").attr("src", videoContent[videoIndex].contentURI); - videoPlayer.load(); - - } - } - } - else - { - $("#videoSrc").attr("src", videoContent[0].contentURI); - localStorage.prevVideo = videoContent[0].contentURI; - videoPlayer.load(); - } - - } - contentType = "IMAGE"; - break; - - case "IMAGE": - if (!emptyContent) - { - imageContent = imageContent.concat(content); - $("#imagePlayer").css("background", "url(" + imageContent[0].contentURI + ") no-repeat center"); - $("#imagePlayer").css("background-size", "contain"); - } - contentType = undefined; - break; - - default: - console.log("Undefined content search type"); - nextContentType = undefined; - break; + console.log("MediaPlayer: some content failed to load, trying again for " + imagePlayer.type); + imagePlayer.clearContent(); + setTimeout(function(){getMedia(onImageContentLoaded, "IMAGE");}, 3000); + return; + } + else + { + imagePlayer.updateContent(newContent, true); + imagePlayer.onContentLoaded(); } - - if (contentType !== undefined) - getMedia(contentType); } -function getMedia(mediaType) +function getMedia(callback, filterType) { console.log("MediaPlayer in getMedia"); var manager = tizen.content; - - var filter = new tizen.AttributeFilter("type", "EXACTLY", mediaType); - manager.find(onContentItemArraySuccess, onError, null, filter); + var filter = new tizen.AttributeFilter("type", "EXACTLY", filterType); + manager.find(callback, onError, null, filter); } function showMediaMenu() { console.log("MediaPlayer in showMediaMenu"); - $(".navButton").fadeIn(800); + $(".navButton").show(); - switch(currentPlayerType) + switch(currentPlayer.type) { - case "AUDIO": - //show audio player - try - { - if (audioContent.length > 0) - updateMediaName(audioContent[audioIndex].artists[0], audioContent[audioIndex].title, audioContent[audioIndex].coverArt); - } - catch(err) - { - console.log("updateMediaName failed for showMediaMenu (audio) : " + err.message); - } - - $("#mediaName").fadeIn(800); - $(".sortButton").fadeIn(800); - currentPlayer.fadeIn(800); + case "audio": + $("#mediaName").show(); + $(".sortButton").show(); + currentPlayer.show(); if (screenOrientation === "landscape" ) $("#audioMediaList").addClass("landscape"); else $("#audioMediaList").removeClass("landscape"); - $("#audioMediaList").fadeIn(800); + $("#audioMediaList").show(); break; - case "VIDEO": + case "video": //show video - setTimeout(function(){currentPlayer.show()}, 800); //The video element can't be faded, so wait a moment before showing + currentPlayer.show(); + //setTimeout(function(){currentPlayer.show()}, 800); //The video element can't be faded, so wait a moment before showing break; - case "IMAGE": + case "image": //show image - currentPlayer.fadeIn(800); + currentPlayer.show(); break; default: @@ -397,10 +239,10 @@ function showMediaList() console.log("MediaPlayer in showMediaList"); if (currentMediaList.is(":visible")) - currentMediaList.fadeOut(300); + currentMediaList.hide(); else { - currentMediaList.fadeIn(300); + currentMediaList.show(); } } @@ -413,6 +255,7 @@ function changeMenu(menuButtonId) var buttonBottom = clickedButton.css("bottom"); var buttonRight = clickedButton.css("right"); +/* //Animate the clicked button slightly clickedButton.animate({ bottom: screenOrientation === "portrait" ? "+=0" : "+=50", @@ -431,23 +274,29 @@ function changeMenu(menuButtonId) clickedButton.css({"bottom": buttonBottom}); } ); - - $(".mainButton").fadeOut(300); +*/ + $(".mainButton").hide(); switch(menuButtonId) { case ("mainMusicButton"): speechObj.vocalizeString("Music player"); currentMenu = "audio"; - currentPlayer = $("#audioPlayer"); - currentPlayerControls = document.getElementById("audioPlayer"); - currentPlayerType = "AUDIO"; + currentPlayer = audioPlayer; currentMediaList = $("#audioMediaList"); - currentMediaListItems = $("#audioMediaListItems"); - currentContent = audioContent; + localStorage.prevMenu = "mainMusicButton"; + + if (audioPlayer.currentAudioContent) + { + localStorage.prevAudioTrack = audioPlayer.currentAudioContent.contentURI + localStorage.prevAudioTime = audioPlayer.playerControls.currentTime; + } + + localStorage.prevVideo = undefined; + localStorage.prevVideoTime = undefined; if (!audioMediaListLoaded) - fillMediaList(currentContent); + audioPlayer.fillMediaList(); showMediaMenu(); break; @@ -455,15 +304,14 @@ function changeMenu(menuButtonId) case ("mainVideoButton"): speechObj.vocalizeString("Video player"); currentMenu = "video"; - currentPlayer = $("#videoPlayer"); - currentPlayerControls = document.getElementById("videoPlayer"); - currentPlayerType = "VIDEO"; + currentPlayer = videoPlayer; currentMediaList = $("#videoMediaList"); - currentMediaListItems = $("#videoMediaListItems"); - currentContent = videoContent; + localStorage.prevMenu = "mainVideoButton"; + localStorage.prevAudioTime = undefined; + localStorage.prevAudioTrack = undefined; if (!videoMediaListLoaded) - fillMediaList(currentContent); + videoPlayer.fillMediaList(); showMediaMenu(); break; @@ -471,15 +319,12 @@ function changeMenu(menuButtonId) case ("mainImageButton"): speechObj.vocalizeString("Picture viewer"); currentMenu = "image"; - currentPlayer = $("#imagePlayer"); - currentPlayerControls = imageControls; - currentPlayerType = "IMAGE"; + currentPlayer = imagePlayer; currentMediaList = $("#imageMediaList"); - currentMediaListItems = $("#imageMediaListItems"); - currentContent = imageContent; + localStorage.prevMenu = "mainImageButton"; if (!imageMediaListLoaded) - fillMediaList(currentContent); + imagePlayer.fillMediaList(); showMediaMenu(); break; @@ -493,105 +338,38 @@ function showMainMenu() { console.log("MediaPlayer in showMainMenu"); currentMenu = "main"; - - if (!currentPlayerControls.paused && currentPlayerType === "AUDIO") - clearInterval(clearAudioTimeInterval); - else if (!currentPlayerControls.paused && currentPlayerType === "VIDEO") - clearInterval(clearVideoTimeInterval); - - currentPlayerControls.pause(); + localStorage.prevMenu = "MAIN"; + localStorage.prevAudioTime = undefined; + localStorage.prevAudioTrack = undefined; + localStorage.prevVideo = undefined; + localStorage.prevVideoTime = undefined; + currentPlayer.pause(); //If the media list is showing, hide it. Remove the mediaListAudioList class if it exists so that it will resize properly if (currentMediaList.is(":visible")) - currentMediaList.fadeOut(300); - - $(".navButton").fadeOut(300); - $(".sortButton").fadeOut(300); - $("#mediaName").fadeOut(300); - - if (currentPlayerType !== "VIDEO") - currentPlayer.fadeOut(300); - else - currentPlayer.hide(); - + currentMediaList.hide(); + $(".navButton").hide(); + $(".sortButton").hide(); + $("#mediaName").hide(); + $(".player").hide(); $(".mainButton").css({"opacity": "100"}); - $(".mainButton").fadeIn(800); + $(".mainButton").show(); } function sortByAlpha(contentToSort) { - console.log("MediaPlayer in sortByAlpha"); - - if (currentPlayerType === "AUDIO") - emptyTimeouts(); - - //If contentToSort is undefined it's because the request came from the sortBy buttons - if (contentToSort === undefined) - contentToSort = audioContent; - - contentToSort.sort(function (a,b) { - var first = a.title.toLowerCase(); - var second = b.title.toLowerCase(); - - if (first < second) - return -1; - if (first > second) - return 1; - - return 0; - }); - - fillMediaList(contentToSort); + currentPlayer.sortByAlpha(); } function sortByArtist(contentToSort) { - console.log("MediaPlayer in sortByArtist"); - - if (currentPlayerType === "AUDIO") - emptyTimeouts(); - - if (contentToSort === undefined) - contentToSort = audioContent; - - contentToSort.sort(function (a,b) { - var first = a.artists[0].toLowerCase(); - var second = b.artists[0].toLowerCase(); - - if (first < second) - return -1; - if (first > second) - return 1; - - return 0; - }); - - fillMediaList(contentToSort); + currentPlayer.sortByArtist(); } function sortByAlbum(contentToSort) { - if (currentPlayerType === "AUDIO") - emptyTimeouts(); - - console.log("MediaPlayer in sortByAlbum"); - if (contentToSort === undefined) - contentToSort = audioContent; - - contentToSort.sort(function (a,b) { - var first = a.album.toLowerCase(); - var second = b.album.toLowerCase(); - - if (first < second) - return -1; - if (first > second) - return 1; - - return 0; - }); - - fillMediaList(contentToSort); + currentPlayer.sortByAlbum(); } /**************************************** NAVIGATION FUNCTIONS *******************************************/ @@ -599,207 +377,43 @@ function sortByAlbum(contentToSort) // This function is called once a file being loaded is ready to play function playLoadedMedia() { - console.log("MediaPlayer in playLoadedMedia"); - currentFileLoaded = true; - - if (loadAndPlay) - { - currentPlayerControls.play(); - clearAudioTimeInterval = setInterval( - function(){ - if (localStorage.prevAudioTime === audioPlayerControls.currentTime) - { - stallCounter++; - - if (stallCounter > 10) - { - //Remote media has stalled, attempt to reconnect - playOnConnect = true; - tizen.mediaserver.scanNetwork(reconnectServer); - } - } - - localStorage.prevAudioTime = audioPlayerControls.currentTime; - },500); - - if (audioContent[audioIndex].remoteFile) - stallCounter = 0; - - loadAndPlay = false; - } - else if (loadPrevAudio) - { - audioPlayerControls.currentTime = localStorage.prevAudioTime; - loadPrevAudio = false; - } + audioPlayer.playLoadedMedia(); } function videoLoaded() { - if (loadPrevVideo) - { - videoPlayerControls.currentTime = localStorage.prevVideoTime; - loadPrevVideo = false; - } + videoPlayer.videoLoaded(); } function playButtonClick() { console.log("MediaPlayer in playButtonClick"); - if (currentPlayerType !== "AUDIO" || currentFileLoaded) - { - if (currentPlayerControls.paused) - { - - if (loadAndPlay) - currentPlayerControls.currentTime = localStorage.prevAudioTime; - - loadAndPlay = false; - currentPlayerControls.play(); - - //Start tracking the current time of the media. This is used to play from previous position on restart. - if (currentPlayerType === "AUDIO") - clearAudioTimeInterval = setInterval(function(){localStorage.prevAudioTime = currentPlayerControls.currentTime},500); - else if (currentPlayerType === "VIDEO") - clearVideoTimeInterval = setInterval(function(){localStorage.prevVideoTime = currentPlayerControls.currentTime},500); - - } - else - { - currentPlayerControls.pause(); - - if (currentPlayerType === "AUDIO") - clearInterval(clearAudioTimeInterval); - else if (currentPlayerType === "VIDEO") - clearInterval(clearVideoTimeInterval); - } - } + if (!currentPlayer.playing()) + currentPlayer.play(); else - console.log(audioContent[audioIndex].artists[0] + " : " + audioContent[audioIndex].title + " can't play yet, it hasn't loaded"); + currentPlayer.pause(); } function pauseButtonClick() { console.log("MediaPlayer in pauseButtonClick"); - if (!currentPlayerControls.paused) + if (currentPlayer.playing()) { - currentPlayerControls.pause(); + currentPlayer.pause(); } } function backButtonClick() { console.log("MediaPlayer in backButtonClick"); - switch (currentPlayerType) - { - case "AUDIO": - if (audioContent) - { - if (audioIndex > 0 ) - audioIndex--; - else - audioIndex = audioContent.length - 1; - - loadAndPlay = true; - audioPlayer.pause(); - - $("#audioSrc").attr("src", audioContent[audioIndex].contentURI); - updateMediaName(audioContent[audioIndex].artists[0], audioContent[audioIndex].title, audioContent[audioIndex].coverArt); - - localStorage.prevAudioTrack = audioContent[audioIndex].contentURI; - audioPlayer.load(); - } - break; - - case "VIDEO": - if (videoContent) - { - if (videoIndex > 0 ) - videoIndex--; - else - videoIndex = videoContent.length - 1; - - videoPlayer.pause(); - $("#videoSrc").attr("src", videoContent[videoIndex].contentURI); - videoPlayer.load(); - } - break; - - case "IMAGE": - if (imageContent) - { - if (imageIndex > 0 ) - imageIndex--; - else - imageIndex = imageContent.length - 1; - - $("#imagePlayer").css("background", "url(" + imageContent[imageIndex].contentURI + ") no-repeat center"); - $("#imagePlayer").css("background-size", "contain"); - } - break; - - default: - console.log("Content failure"); - break; - } + currentPlayer.previous(); } function nextButtonClick() { console.log("MediaPlayer in nextButtonClick"); - switch (currentPlayerType) - { - case "AUDIO": - if (audioContent) - { - if (audioContent.length > (audioIndex + 1)) - audioIndex++; - else - audioIndex = 0; - - loadAndPlay = true; - audioPlayer.pause(); - - $("#audioSrc").attr("src", audioContent[audioIndex].contentURI); - - localStorage.prevAudioTrack = audioContent[audioIndex].contentURI; - updateMediaName(audioContent[audioIndex].artists[0], audioContent[audioIndex].title, audioContent[audioIndex].coverArt); - audioPlayer.load(); - } - break; - - case "VIDEO": - if (videoContent) - { - if (videoContent.length > (videoIndex + 1)) - videoIndex++; - else - videoIndex = 0; - - videoPlayer.pause(); - $("#videoSrc").attr("src", videoContent[videoIndex].contentURI); - videoPlayer.load(); - } - break; - - case "IMAGE": - if (imageContent) - { - if (imageContent.length > (imageIndex + 1)) - imageIndex++; - else - imageIndex = 0; - - $("#imagePlayer").css("background", "url(" + imageContent[imageIndex].contentURI + ") no-repeat center"); - $("#imagePlayer").css("background-size", "contain"); - } - break; - - default: - console.log("Content failure"); - break; - } + currentPlayer.next(); } /**************************************** END NAVIGATION FUNCTIONS *******************************************/ @@ -808,7 +422,7 @@ function resizeMainMenu() { console.log("MediaPlayer in resizeMainMenu"); - currentMediaList.fadeOut(0); + currentMediaList.hide(); screenWidth = window.innerWidth; screenHeight = window.innerHeight; screenOrientation = screenWidth < screenHeight ? "portrait" : "landscape"; @@ -833,8 +447,6 @@ function resizePlayerPage() { console.log("MediaPlayer in resizePlayerPage"); - audioPlayer = document.getElementById("audioPlayer"); - videoPlayer = document.getElementById("videoPlayer"); screenWidth = window.innerWidth; screenHeight = window.innerHeight; @@ -901,6 +513,13 @@ function toggleNightMode(nightModeValue) function init() { console.log("MediaPlayer in init"); + + musicIcon.src = "images/musicIcon.png"; + vidIcon.src = "images/videoIcon.png"; + imgIcon.src = "images/imageIcon.png"; + mediaNameCanvas = document.getElementById("mediaName"); + mediaNameCTX = mediaNameCanvas.getContext("2d"); + var vehicle = tizen.vehicle; @@ -936,35 +555,44 @@ function init() vehicle.subscribe("DrivingMode",function(value) { console.log("MediaPlayer: DrivingMode changed to " + value.drivingMode); - if (value.drivingMode > 0 && currentPlayerType === "VIDEO" && !currentPlayerControls.paused) + if (value.drivingMode > 0 && currentPlayer.type === "video" && currentPlayer.playing()) { console.log("MediaPlayer: pausing video due to vehicle motion"); - currentPlayerControls.pause(); + currentPlayer.pause(); waitingToResumeVideo = true; } - else if (value.drivingMode === 0 && currentPlayerType === "VIDEO" && waitingToResumeVideo) + else if (value.drivingMode === 0 && currentPlayer.type === "video" && waitingToResumeVideo) { console.log("MediaPlayer: vehicle has stopped, resuming video"); - currentPlayerControls.play(); + currentPlayer.play(); waitingToResumeVideo = false; } }); } - musicIcon.src = "images/musicIcon.png"; - vidIcon.src = "images/videoIcon.png"; - imgIcon.src = "images/imageIcon.png"; - imageControls = new ImageControls(); - - audioPlayerControls = document.getElementById("audioPlayer"); - videoPlayerControls = document.getElementById("videoPlayer"); + //Setup voice control + if (tizen.speech) + setupSpeech(); + else + console.log("MediaPlayer: Speech Recognition not running, voice control will be unavailable"); - mediaNameCanvas = document.getElementById("mediaName"); - mediaNameCTX = mediaNameCanvas.getContext("2d"); + audioPlayer = new MediaPlayer("audio"); + videoPlayer = new MediaPlayer("video"); + imagePlayer = new MediaPlayer("image"); + currentPlayer = audioPlayer; //Resize all items and search for local media resizeAll(); + if (localStorage.prevMenu && localStorage.prevMenu !== "MAIN") + changeMenu(localStorage.prevMenu) + else + showMainMenu(); + + getMedia(onAudioContentLoaded, "AUDIO"); + getMedia(onVideoContentLoaded, "VIDEO"); + getMedia(onImageContentLoaded, "IMAGE"); + //Check if DLNA plugin is installed. If so, scan for media. if (tizen.mediaserver) { @@ -976,15 +604,6 @@ function init() else console.log("MediaPlayer: No DLNA server running, using local media only..."); - //Setup voice control - if (tizen.speech) - setupSpeech(); - else - console.log("MediaPlayer: Speech Recognition not running, voice control will be unavailable"); - - //Get local media - setTimeout(function(){getMedia(contentType);}, 500); - //Prevent highlighting window.ondragstart = function() { return false; } @@ -1027,7 +646,7 @@ function init() $("#playButton").toggleClass('playing', false); }, false); document.getElementById('imagePlayer').addEventListener("click", function() { - if (imageControls.paused) + if (!imagePlayer.playing) { // next picture nextButtonClick(); @@ -1035,7 +654,7 @@ function init() else { // pause the slideshow and fade in the controls - imageControls.pause(); + imagePlayer.pause(); $("#navigationButtons").show(); } }, false); diff --git a/js/player.js b/js/player.js new file mode 100644 index 0000000..d6867b7 --- /dev/null +++ b/js/player.js @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2013, Intel Corporation. + * + * This program is licensed under the terms and conditions of the + * Apache License, version 2.0. The full text of the Apache License is at + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ + +MediaPlayer = function(type) +{ + this.type = type; + this.content = new Array(); + this.mediaList = $("#" + type + "MediaList"); + this.mediaListItems = $("#" + type + "MediaListItems"); + this.playerControls = undefined; + this.mediaListLoaded = false; + this.listIndex = 0; + this.imagesLoaded = false; + this.loadAndPlay = false; + this.loadPrev = false; + this.currentFileLoaded = false; + this.fillingList = false; + this.clearDrawTimeouts = new Array(); + + switch(type) + { + case "audio": + console.log("MediaPlayer creating AudioPlayer"); + audioPlayer = new AudioPlayer; + $.extend(this, audioPlayer); + this.playerControls = document.getElementById("audioPlayer"); + break; + case "video": + console.log("MediaPlayer creating VideoPlayer"); + videoPlayer = new VideoPlayer; + $.extend(this, videoPlayer); + this.playerControls = document.getElementById("videoPlayer"); + break; + case "image": + console.log("MediaPlayer creating ImagePlayer"); + imagePlayer = new ImagePlayer; + $.extend(this, imagePlayer); + this.playerControls = new ImageControls(); + break; + default: + console.log("MediaPlayer: Trying to make an invalid player type " + type); + break; + } +} + +MediaPlayer.prototype.updateContent = function(newContent, append) +{ + console.log("MediaPlayer: updating content for " + this.type); + if (newContent && newContent !== undefined && newContent.length > 0) + { + if (append) + { + this.content = this.content.concat(newContent); + } + else + { + this.content.length = 0; + this.content = newContent; + } + } + else + console.log("MediaPlayer: invalid content update for " + this.type); +} + +MediaPlayer.prototype.getContent = function() +{ + return this.content; +} + +MediaPlayer.prototype.contentLength = function() +{ + return this.content.length; +} + +MediaPlayer.prototype.show = function() +{ + $("#" + this.type + "Player").show(); +} + +MediaPlayer.prototype.clearContent = function() +{ + console.log("MediaPlayer: clearing content for " + this.type); + this.emptyTimeouts(); + this.content.length = 0; +} + +MediaPlayer.prototype.currentIndex = function() +{ + return this.listIndex; +} + +MediaPlayer.prototype.emptyTimeouts = function() +{ + var clearItem; + + while (clearItem = this.clearDrawTimeouts.pop()) + { + clearTimeout(clearItem); + } +} + +MediaPlayer.prototype.makeListBar = function(icon, i, artistTextObj, trackTextObj) +{ + var lightColor = ""; + var canvasW = mediaListItemW; + var canvasH = mediaListItemH * 0.95 ; + + if ((i+1)%2 !== 0) + { + lightColor = "lightColor "; + } + + if (nightMode) + { + this.mediaListItems.append("
  • " + + " " + + "
  • " + ); + } + else + { + this.mediaListItems.append("
  • " + + " " + + "
  • " + ); + } + + try + { + var currentCanvas = document.getElementById(this.type + "CanvasNum" + i); + var currentCTX = currentCanvas.getContext("2d"); + + this.content[i].ctx = currentCTX; + + currentCTX.drawImage(icon, 0, 0, canvasH, canvasH ); + var artistText = new TextObject(currentCTX,artistTextObj); + var trackText = new TextObject(currentCTX,trackTextObj); + var mediaTextTemp1 = screenOrientation === "portrait" ? mediaTextTemplate2 : mediaTextTemplate2Landscape; + var mediaTextTemp2 = screenOrientation === "portrait" ? mediaTextTemplate3 : mediaTextTemplate3Landscape; + var trackTextTemp = screenOrientation === "portrait" ? trackTextTemplate : trackTextTemplateLandscape; + + trackText.applyTemplate(mediaTextTemp1); + trackText.drawObj(); + trackText.applyTemplate(mediaTextTemp2); + trackText.drawObj(); + artistText.applyTemplate(trackTextTemp); + artistText.drawObj(); + } + catch(err) + { + console.log("MediaPlayer: drawImage failed for " + this.type + " - reason -> " + err); + } +} + +MediaPlayer.prototype.fillMediaList = function() +{ + console.log("MediaPlayer in fillMediaList for content = " + this.type); + this.fillingList = true; + + //Don't try and fill an empty content list + if (this.content === undefined || this.content === null || this.content.length <=0) + return false; + + this.emptyTimeouts(); + + this.mediaListItems.empty(); + var timeOut = 1; + + switch (this.type) + { + case "audio": + audioMediaListLoaded = true; + break; + case "video": + videoMediaListLoaded = true; + break; + case "image": + imageMediaListLoaded = true; + break; + default: + break; + } + + var jumpSize = 1; + var tmpClearTimeout; + + for (var i=0; i < this.content.length; i++) + { + tmpClearTimeout = setTimeout(this.makeListItem.bind(this, i, jumpSize), timeOut); + this.clearDrawTimeouts.push(tmpClearTimeout); + + timeOut += 50; + i+=jumpSize - 1; + } +} diff --git a/js/videoPlayer.js b/js/videoPlayer.js new file mode 100644 index 0000000..ca14eda --- /dev/null +++ b/js/videoPlayer.js @@ -0,0 +1,174 @@ + +/* + * Copyright (c) 2013, Intel Corporation. + * + * This program is licensed under the terms and conditions of the + * Apache License, version 2.0. The full text of the Apache License is at + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ + +VideoPlayer = function() +{ + this.clearVideoTimeInterval = undefined; + this.loadPrevVideo = false; +} + +VideoPlayer.prototype.play = function() +{ + console.log("MediaPlayer in VideoPlayer::play"); + if (this.playerControls.paused) + { + this.playerControls.play(); + + //Start tracking the current time of the media. This is used to play from previous position on restart. + if (!this.content[this.listIndex].remoteFile) + { + var timeoutFunction = function() + { + localStorage.prevVideoTime = this.playerControls.currentTime; + } + + //Start tracking the current time of the media. This is used to play from previous position on restart. + this.clearVideoTimeInterval = setInterval(timeoutFunction.bind(this),500); + } + } + else + { + this.pause(); + } +} + +VideoPlayer.prototype.pause = function() +{ + if (!this.playerControls.paused) + { + this.playerControls.pause(); + clearInterval(this.clearVideoTimeInterval); + } +} + +VideoPlayer.prototype.playing = function() +{ + return !(this.playerControls.paused); +} + +VideoPlayer.prototype.next = function() +{ + if (this.content) + { + if (this.content.length > (this.listIndex + 1)) + this.listIndex++; + else + this.listIndex = 0; + this.load(this.listIndex, false); + } +} + +VideoPlayer.prototype.previous = function() +{ + if (this.content) + { + if (this.listIndex > 0 ) + this.listIndex--; + else + this.listIndex = this.content.length - 1; + + this.load(this.listIndex, false); + } +} + +VideoPlayer.prototype.load = function(index, play) +{ + this.listIndex = index; + this.loadAndPlay = play; + this.playerControls.pause(); + $("#videoSrc").attr("src", this.content[this.listIndex].contentURI); + + if (!this.content[this.listIndex].remoteFile) + { + localStorage.prevVideo = this.content[this.listIndex].contentURI; + } + else + { + localStorage.prevVideo = undefined; + localStorage.prevVideoTime = undefined; + } + + this.playerControls.load(); +} + +VideoPlayer.prototype.videoLoaded = function() +{ + if (this.loadPrevVideo) + { + this.playerControls.currentTime = localStorage.prevVideoTime; + this.loadPrevVideo = false; + this.play(); + } + + if (this.loadAndPlay) + this.play(); + + this.currentFileLoaded = true; +} + +VideoPlayer.prototype.onContentLoaded = function() +{ + try + { + if (localStorage.prevVideo && localStorage.prevVideo !== "undefined") + { + for (var i = 0; i < this.content.length; i++) + { + if (this.content[i].contentURI === localStorage.prevVideo) + { + console.log("MediaPlayer: Previous video found, loading " + this.content[this.listIndex].contentURI); + this.listIndex = i; + this.loadPrevVideo = true; + $("#videoSrc").attr("src", this.content[this.listIndex].contentURI); + this.fillMediaList(); + this.playerControls.load(); + } + } + } + else + { + console.log("MediaPlayer: No previous video found, loading first"); + $("#videoSrc").attr("src", this.content[0].contentURI); + localStorage.prevVideo = this.content[0].contentURI; + this.playerControls.load(); + } + } + + catch (err) + { + console.log("MediaPlayer: Error when parsing videoContent"); + } +} + +VideoPlayer.prototype.makeListItem = function(j, k) +{ + var canvasH = mediaListItemH * 0.95 ; + + for (var i = j; (i < (j+k) && i < this.content.length); i++) + { + var artistText = {"text" : this.content[i].artists[0], "xLoc" : canvasH + 20, "yLoc" : canvasH / 2.5 , "zLoc" : 0}; + var trackText = {"text" : this.content[i].title, "xLoc" : canvasH + 20, "yLoc" : canvasH / 1.1 , "zLoc" : 0}; + + this.makeListBar(vidIcon, i, artistText, trackText); + + // Set callback function for the new list item + $("#" + this.type + "CanvasNum" + i).click(function () { + try + { + videoPlayer.load($(this).parent().parent().index(), true); + $("#videoMediaList").hide(); + } + catch(err) + { + console.log("MediaPlayer: load video error " + err.message); + } + }); + } +} diff --git a/packaging/MediaPlayer.changes b/packaging/MediaPlayer.changes index f8ff933..4415bb7 100644 --- a/packaging/MediaPlayer.changes +++ b/packaging/MediaPlayer.changes @@ -1,5 +1,14 @@ +* Tue Oct 08 2013 brianjjones accepted/tizen/20131004.164521@81d77fa +- Re-organizing the code so that the players are object based. Adding code to remember + what page you were on as well as the previous media + +* Fri Oct 04 2013 brianjjones accepted/tizen/20131004.164521@b1a663e +- Adding a change so that if local media fails to load, it tries again. Also now starts on + previous menu. + * Thu Oct 03 2013 brianjjones submit/tizen/20130925.235244@b480ae8 -- MediaPlayer will now remember where the user was on restart. Also able to reconnect to remote media if connection is lost (TIVI-1254) +- MediaPlayer will now remember where the user was on restart. Also able to reconnect + to remote media if connection is lost (TIVI-1254) - Load the first video when moving to the video player mode - Fix background when in nightMode - Make play button state driven directly off media events @@ -37,27 +46,33 @@ - Adding tizen.speech (voice control) support. * Mon Jul 22 2013 brianjjones submit/tizen/20130719.021058@4b5b477 -- Fix for play button bug, music now moves to the next song when finished, error shows up if filetype can't be loaded +- Fix for play button bug, music now moves to the next song when finished, error shows up + if filetype can't be loaded - More image shrinking * Wed Jul 17 2013 brianjjones submit/tizen/20130702.231722@8097a1e - Shrinking image sizes and removing hard coded reference to ogg * Tue Jul 02 2013 brianjjones submit/tizen/20130701.233523@c4d3618 -- Putting missing text back in. Adding several try/catch statements to deal with possible null arrays +- Putting missing text back in. Adding several try/catch statements to deal with possible + null arrays * Mon Jul 01 2013 brianjjones submit/tizen/20130629.001025@76c119d - Adding a null check for artwork. Various other sizing tweaks * Fri Jun 28 2013 brianjjones submit/tizen/20130628.000427@0eedd50 -- Changing installation to only wrt-install if it is after the first boot. Otherwise, copy the wgt file to the correct place and let wrt-installer handle it +- Changing installation to only wrt-install if it is after the first boot. Otherwise, + copy the wgt file to the correct place and let wrt-installer handle it * Thu Jun 27 2013 brianjjones submit/tizen/20130626.013745@95361ce -- Adding slide show ability to image player. Various changes to make app look better in landscape. Cleaning up code. +- Adding slide show ability to image player. Various changes to make app look better + in landscape. Cleaning up code. * Wed Jun 26 2013 brianjjones submit/tizen/20130626.013745@2809676 -- Check that the album cover art image is valid before using it. Removing some images due to renaming. -- Changing some image files. Adding check to ensure album cover image is valid. Removing stray text. +- Check that the album cover art image is valid before using it. Removing some images + due to renaming. +- Changing some image files. Adding check to ensure album cover image is valid. + Removing stray text. Brian Jones Initial Checkin