diff options
Diffstat (limited to 'debian/webinterface-default/js/NowPlayingManager.js')
-rwxr-xr-x | debian/webinterface-default/js/NowPlayingManager.js | 661 |
1 files changed, 661 insertions, 0 deletions
diff --git a/debian/webinterface-default/js/NowPlayingManager.js b/debian/webinterface-default/js/NowPlayingManager.js new file mode 100755 index 0000000..fb34f74 --- /dev/null +++ b/debian/webinterface-default/js/NowPlayingManager.js @@ -0,0 +1,661 @@ +/* + * Copyright (C) 2005-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * <http://www.gnu.org/licenses/>. + * + */ + +var NowPlayingManager = function () { + this.init(); + return true; +} + +NowPlayingManager.prototype = { + updateCounter: 0, + activePlayer: "", + activePlayerId: -1, + currentItem: -1, + playing: false, + paused: false, + playlistid: -1, + + init: function () { + $('#pbPause').hide(); /* Assume we are not playing something */ + this.bindPlaybackControls(); + this.updateState(); + $('#nextTrack').bind('click', jQuery.proxy(this.showPlaylist, this)); + $('#nowPlayingPlaylist').bind('click', function () { + return false; + }); + $(window).bind('click', jQuery.proxy(this.hidePlaylist, this)); + }, + updateState: function () { + xbmc.rpc.request({ + 'context': this, + 'method': 'Player.GetActivePlayers', + 'timeout': 3000, + 'success': function (data) { + if (data && data.result && data.result.length > 0) { + if (data.result[0].playerid != this.activePlayerId) { + this.activePlayerId = data.result[0].playerid; + this.activePlayer = data.result[0].type; + if (this.activePlayer == "audio") { + this.stopVideoPlaylistUpdate(); + this.displayAudioNowPlaying(); + } else if (this.activePlayer == "video") { + this.stopAudioPlaylistUpdate(); + this.displayVideoNowPlaying(); + } else { + this.stopVideoPlaylistUpdate(); + this.stopAudioPlaylistUpdate(); + this.activePlayer = ""; + this.activePlayerId = -1; + } + + this.stopRefreshTime(); + this.updatePlayer(); + } + } else if (!data || !data.result || data.result.length <= 0) { + this.stopVideoPlaylistUpdate(); + this.stopAudioPlaylistUpdate(); + this.activePlayer = ""; + this.activePlayerId = -1; + } + + if (this.activePlayerId >= 0) { + this.showFooter(); + } else { + this.stopRefreshTime(); + this.hideFooter(); + } + + setTimeout(jQuery.proxy(this.updateState, this), 1000); + }, + 'error': function (data, error) { + xbmc.core.displayCommunicationError(); + setTimeout(jQuery.proxy(this.updateState, this), 2000); + } + }); + }, + updatePlayer: function () { + xbmc.rpc.request({ + 'context': this, + 'method': 'Player.GetProperties', + 'params': { + 'playerid': this.activePlayerId, + 'properties': [ + 'playlistid', + 'speed', + 'position', + 'totaltime', + 'time' + ] + }, + 'success': function (data) { + if (data && data.result) { + this.playlistid = data.result.playlistid; + this.playing = data.result.speed != 0; + this.paused = data.result.speed == 0; + this.currentItem = data.result.position; + this.trackBaseTime = xbmc.core.timeToDuration(data.result.time); + this.trackDurationTime = xbmc.core.timeToDuration(data.result.totaltime); + if (!this.autoRefreshAudioData && !this.autoRefreshVideoData && this.playing) { + if (this.activePlayer == 'audio') { + this.autoRefreshAudioData = true; + this.refreshAudioData(); + } else if (this.activePlayer == 'video') { + this.autoRefreshVideoData = true; + this.refreshVideoData(); + } + } + } + if ((this.autoRefreshAudioData || this.autoRefreshVideoData) && !this + .activeItemTimer) { + this.activeItemTimer = 1; + setTimeout(jQuery.proxy(this.updateActiveItemDurationLoop, this), 1000); + } + } + }); + }, + bindPlaybackControls: function () { + $('#pbNext').bind('click', jQuery.proxy(this.nextTrack, this)); + $('#pbPrev').bind('click', jQuery.proxy(this.prevTrack, this)); + $('#pbStop').bind('click', jQuery.proxy(this.stopTrack, this)); + $('#pbPlay').bind('click', jQuery.proxy(this.playPauseTrack, this)); + $('#pbPause').bind('click', jQuery.proxy(this.playPauseTrack, this)); + that = this + $(document).keypress(function (event) { + switch (event.which) { + case 32: //spacebar + event.preventDefault() + jQuery.proxy(that.playPauseTrack, that)(); + break; + case 120: //x key + event.preventDefault() + jQuery.proxy(that.stopTrack, that)(); + break; + case 44: //period key + event.preventDefault() + jQuery.proxy(that.nextTrack, that)(); + break; + case 46: //comma key + event.preventDefault() + jQuery.proxy(that.prevTrack, that)(); + break; + } + }); + }, + showPlaylist: function () { + $('#nextText').html('Playlist: '); + $('#nowPlayingPlaylist').show(); + return false; + }, + hidePlaylist: function () { + $('#nextText').html('Next: '); + $('#nowPlayingPlaylist').hide(); + return false; + }, + hideFooter: function () { + $('#footerPopover').hide(); + $('#overlay').css('bottom', '0px'); + }, + showFooter: function () { + $('#footerPopover').show(); + $('#overlay').css('bottom', '150px'); + }, + nextTrack: function () { + if (this.activePlayer) { + xbmc.rpc.request({ + 'method': 'Player.GoTo', + 'params': { + 'playerid': this.activePlayerId, + 'to': 'next' + }, + 'success': function () {} + }); + } + }, + prevTrack: function () { + if (this.activePlayer) { + xbmc.rpc.request({ + 'method': 'Player.GoTo', + 'params': { + 'playerid': this.activePlayerId, + 'to': 'previous' + }, + 'success': function () {} + }); + } + }, + stopTrack: function () { + if (this.activePlayer) { + xbmc.rpc.request({ + 'context': this, + 'method': 'Player.Stop', + 'params': { + 'playerid': this.activePlayerId + }, + 'success': function (data) { + if (data && data.result == 'OK') { + this.playing = false; + this.paused = false; + this.trackBaseTime = 0; + this.trackDurationTime = 0; + this.showPlayButton(); + } + } + }); + } + }, + playPauseTrack: function () { + if (this.activePlayer) { + var method = ((this.playing || this.paused) ? 'Player.PlayPause' : 'Playlist.Play'); + xbmc.rpc.request({ + 'context': this, + 'method': method, + 'params': { + 'playerid': this.activePlayerId + }, + 'success': function (data) { + if (data && data.result) { + this.playing = data.result.speed != 0; + this.paused = data.result.speed == 0; + if (this.playing) { + this.showPauseButton(); + } else { + this.showPlayButton(); + } + } + } + }); + } + }, + showPauseButton: function () { + $('#pbPause').show(); + $('#pbPlay').hide(); + }, + showPlayButton: function () { + $('#pbPause').hide(); + $('#pbPlay').show(); + }, + displayAudioNowPlaying: function () { + if (!this.autoRefreshAudioPlaylist) { + this.autoRefreshAudioPlaylist = true; + this.updateAudioPlaylist(); + } + }, + displayVideoNowPlaying: function () { + if (!this.autoRefreshVideoPlaylist) { + this.autoRefreshVideoPlaylist = true; + this.updateVideoPlaylist(); + } + }, + playPlaylistItem: function (sender) { + var sequenceId = $(sender.currentTarget).attr('seq'); + if (!this.activePlaylistItem || (this.activePlaylistItem !== undefined && sequenceId != this + .activePlaylistItem.seq)) { + xbmc.rpc.request({ + 'method': 'Player.GoTo', + 'params': { + 'playerid': this.activePlayerId, + 'to': sequenceId + }, + 'success': function () {} + }); + } + this.hidePlaylist(); + }, + playlistChanged: function (newPlaylist) { + if (this.activePlaylist && !newPlaylist || !this.activePlaylist && newPlaylist) { + return true; + } + if (!this.activePlaylist && !newPlaylist) { + return false; + } + if (this.activePlaylist.length != newPlaylist.length) { + return true; + } + for (var i = 0; i < newPlaylist.length; i++) { + if (!this.comparePlaylistItems(this.activePlaylist[i], newPlaylist[i])) { + return true; + } + } + return false; + }, + updateAudioPlaylist: function () { + xbmc.rpc.request({ + 'context': this, + 'method': 'Playlist.GetItems', + 'params': { + 'playlistid': this.playlistid, + 'properties': [ + 'title', + 'album', + 'artist', + 'duration', + 'thumbnail' + ] + }, + 'success': function (data) { + if (data && data.result && data.result.items && data.result.items.length > 0 && data + .result.limits.total > 0) { + if (!this.activePlaylistItem || this.playlistChanged(data.result.items) || (this + .activePlaylistItem && (this.activePlaylistItem.seq != this.currentItem) + )) { + var ul = $('<ul>'); + var activeItem; + $.each($(data.result.items), jQuery.proxy(function (i, item) { + var li = $('<li>'); + var code = '<span class="duration">' + xbmc.core + .durationToString(item.duration) + + '</span><div class="trackInfo" title="' + item.title + + ' - ' + item.artist + '"><span class="trackTitle">' + + item.title + '</span> - <span class="trackArtist">' + + item.artist + '</span></div>'; + if (i == this.currentItem) { + activeItem = item; + activeItem.seq = i; + li.addClass('activeItem'); + } + if (i == (this.currentItem + 1)) { + $('#nextTrack').html(code).show(); + } + li.bind('click', jQuery.proxy(this.playPlaylistItem, this)); + ul.append(li.attr('seq', i).html(code)); + }, this)); + if (data.result.limits.total > 1) { + if (activeItem && data.result.limits.total - 1 == activeItem.seq) { + $('#nextTrack').html( + '<div class="trackInfo">Last track in playlist</div>') + .show(); + } + $('#nextText').show(); + $('#nowPlayingPlaylist').html('').append(ul); + } else { + $('#nextText').hide(); + $('#nowPlayingPlaylist').hide(); + $('#nextTrack').hide(); + } + if (!this.comparePlaylistItems(activeItem, this.activePlaylistItem)) { + this.activePlaylistItem = activeItem; + if (!this.updateActiveItemDurationRunOnce) { + this.updateActiveItemDurationRunOnce = true; + this.updatePlayer(); + } + } else if (!activeItem) { + this.stopRefreshTime(); + } + this.activePlaylist = data.result.items; + $('#videoDescription').hide(); + $('#audioDescription').show(); + $('#nowPlayingPanel').show(); + } + } else { + this.activePlaylist = null; + $('#audioDescription').hide(); + $('#nowPlayingPanel').hide(); + } + if (this.autoRefreshAudioPlaylist) { + setTimeout(jQuery.proxy(this.updateAudioPlaylist, this), 1000); + } + }, + 'error': function (data) { + xbmc.core.displayCommunicationError(); + if (this.autoRefreshAudioPlaylist) { + setTimeout(jQuery.proxy(this.updateAudioPlaylist, this), + 2000); /* Slow down request period */ + } + } + }); + }, + stopAudioPlaylistUpdate: function () { + this.autoRefreshAudioPlaylist = false; + this.updateActiveItemDurationRunOnce = false; + }, + stopVideoPlaylistUpdate: function () { + this.autoRefreshVideoPlaylist = false; + this.updateActiveItemDurationRunOnce = false; + }, + updateActiveItemDurationLoop: function () { + this.activeItemTimer = 0; + this.updatePlayer(); + }, + refreshAudioDataLoop: function () { + this.audioRefreshTimer = 0; + this.refreshAudioData(); + }, + refreshAudioData: function () { + if (this.autoRefreshAudioData && !this.audioRefreshTimer) { + this.audioRefreshTimer = 1; + setTimeout(jQuery.proxy(this.refreshAudioDataLoop, this), 1000); + } + if (this.playing && !this.paused) { + this.trackBaseTime++; + } + if (this.paused) { + this.showPlayButton(); + } else if (this.playing) { + this.showPauseButton(); + } + if (this.activePlaylistItem) { + if (this.activePlaylistItem != this.lastPlaylistItem) { + this.lastPlaylistItem = this.activePlaylistItem; + var imgPath = xbmc.core.DEFAULT_ALBUM_COVER; + if (this.activePlaylistItem.thumbnail) { + imgPath = 'image/' + encodeURI(this.activePlaylistItem.thumbnail); + } + $('#audioCoverArt').html('<img src="' + imgPath + '" alt="' + this.activePlaylistItem.album + + ' cover art">'); + $('#audioTrackTitle').html('<span title="' + this.activePlaylistItem.title + '">' + this + .activePlaylistItem.title + '</span>'); + if (this.activePlaylistItem.album) { + $('#audioAlbumTitle').html('<span title="' + this.activePlaylistItem.album + '">' + this + .activePlaylistItem.album + '</span>') + .show(); + } else { + $('#audioAlbumTitle').hide(); + } + $('#audioArtistTitle').html(this.activePlaylistItem.artist); + $('#progressBar').attr('style', ''); + } + $('#audioDuration').html(xbmc.core.durationToString(this.trackBaseTime) + ' / ' + xbmc.core + .durationToString(this.trackDurationTime)); + var buttonWidth = $('#progressBar .progressIndicator').width(); + var progressBarWidth = (this.trackBaseTime / this.trackDurationTime) * 100; + var progressSliderPosition = Math.ceil(($('#progressBar').width() / 100) * progressBarWidth) - + buttonWidth; + if (progressSliderPosition < 0) { + progressSliderPosition = 0; + } + if (progressBarWidth <= 100) { + $('#progressBar .elapsedTime').width(progressBarWidth + '%'); + $('#progressBar .progressIndicator').css('left', progressSliderPosition); + } + } + }, + refreshVideoDataLoop: function () { + this.videoRefreshTimer = 0; + this.refreshVideoData(); + }, + refreshVideoData: function () { + if (this.autoRefreshVideoData && !this.videoRefreshTimer) { + this.videoRefreshTimer = 1; + setTimeout(jQuery.proxy(this.refreshVideoDataLoop, this), 1500); + } + if (this.playing && !this.paused) { + this.trackBaseTime++; + } + if (this.paused) { + this.showPlayButton(); + } else if (this.playing) { + this.showPauseButton(); + } + if (this.activePlaylistItem) { + if (this.activePlaylistItem != this.lastPlaylistItem) { + this.lastPlaylistItem = this.activePlaylistItem; + var imgPath = xbmc.core.DEFAULT_VIDEO_COVER; + if (this.activePlaylistItem.thumbnail) { + imgPath = 'image/' + encodeURI(this.activePlaylistItem.thumbnail); + } + $('#videoCoverArt').html('<img src="' + imgPath + '" alt="' + this.activePlaylistItem.title + + ' cover art">'); + $('#videoShowTitle').html(this.activePlaylistItem.showtitle || ' '); + var extra = ''; + if (this.activePlaylistItem.season >= 0 && this.activePlaylistItem.episode >= 0) { + extra = this.activePlaylistItem.season + 'x' + this.activePlaylistItem.episode + ' '; + } + $('#videoTitle').html(extra + this.activePlaylistItem.title); + } + $('#videoDuration').html(xbmc.core.durationToString(this.trackBaseTime) + ' / ' + xbmc.core + .durationToString(this.trackDurationTime)); + var buttonWidth = $('#progressBar .progressIndicator').width(); + var progressBarWidth = (this.trackBaseTime / this.trackDurationTime) * 100; + var progressSliderPosition = Math.ceil(($('#progressBar').width() / 100) * progressBarWidth) - + buttonWidth; + if (progressSliderPosition < 0) { + progressSliderPosition = 0; + } + if (progressBarWidth <= 100) { + $('#progressBar .elapsedTime').width(progressBarWidth + '%'); + $('#progressBar .progressIndicator').css('left', progressSliderPosition); + } + } + }, + stopRefreshTime: function () { + this.autoRefreshAudioData = false; + this.autoRefreshVideoData = false; + }, + comparePlaylistItems: function (item1, item2) { + if (!item1 || !item2) { + if (!item1 && !item2) { + return true; + } + return false; + } + if (item1.title != item2.title) { + return false; + } + if (item1.album != item2.album) { + return false; + } + if (item1.artist != item2.artist) { + return false; + } + if (item1.duration != item2.duration) { + return false; + } + if (item1.label != item2.label) { + return false; + } + if (item1.season != item2.season) { + return false; + } + if (item1.episode != item2.episode) { + return false; + } + return true; + }, + updateVideoPlaylist: function () { + xbmc.rpc.request({ + 'context': this, + 'method': 'Playlist.GetItems', + 'params': { + 'playlistid': this.playlistid, + 'properties': [ + 'title', + 'season', + 'episode', + 'plot', + 'runtime', + 'showtitle', + 'thumbnail' + ] + }, + 'success': function (data) { + if (data && data.result && data.result.items && data.result.items.length > 0 && data + .result.limits.total > 0) { + if (this.playlistChanged(data.result.items)) { + var ul = $('<ul>'); + var activeItem; + $.each($(data.result.items), jQuery.proxy(function (i, item) { + var li = $('<li>'); + var extra = ''; + if (item.season >= 0 && item.episode >= 0) { + extra = item.season + 'x' + item.episode + ' '; + } + var code = '<span class="duration">' + xbmc.core + .durationToString(item.runtime) + + '</span><div class="trackInfo" title="' + extra + item + .title + '"><span class="trackTitle">' + extra + item + .title + '</span></div>'; + if (i == this.currentItem) { + activeItem = item; + activeItem.seq = i; + li.addClass('activeItem'); + } + if (i == (this.currentItem + 1)) { + $('#nextTrack').html(code).show(); + } + li.bind('click', jQuery.proxy(this.playPlaylistItem, this)); + ul.append(li.attr('seq', i).html(code)); + }, this)); + if (data.result.limits.total > 1) { + $('#nextText').show(); + if (activeItem && data.result.limits.total == activeItem.seq) { + $('#nextTrack').html( + '<div class="trackInfo">Last track in playlist</div>') + .show(); + } + $('#nowPlayingPlaylist').html('').append(ul); + } else { + $('#nextText').hide(); + $('#nowPlayingPlaylist').hide(); + $('#nextTrack').hide(); + } + if (!this.comparePlaylistItems(activeItem, this.activePlaylistItem)) { + this.activePlaylistItem = activeItem; + if (!this.updateActiveItemDurationRunOnce) { + this.updateActiveItemDurationRunOnce = true; + this.updatePlayer(); + } + } else if (!activeItem) { + this.stopRefreshTime(); + } + this.activePlaylist = data.result.items; + $('#videoDescription').show(); + $('#audioDescription').hide(); + $('#nowPlayingPanel').show(); + } + } else { + xbmc.rpc.request({ + 'context': this, + 'method': 'Player.GetItem', + 'params': { + 'playerid': this.activePlayerId, + 'properties': [ + 'title', + 'season', + 'episode', + 'plot', + 'runtime', + 'showtitle', + 'thumbnail' + ] + }, + 'success': function (data) { + if (data && data.result && data.result.item) { + this.activePlaylistItem = data.result.item; + if (!this.updateActiveItemDurationRunOnce) { + this.updateActiveItemDurationRunOnce = true; + this.updatePlayer(); + } + + $('#nextText').hide(); + $('#nowPlayingPlaylist').hide(); + $('#nextTrack').hide(); + + $('#videoDescription').show(); + $('#audioDescription').hide(); + $('#nowPlayingPanel').show(); + } else { + this.activePlaylist = null; + $('#videoDescription').hide(); + $('#nowPlayingPanel').hide(); + } + }, + 'error': function (data) { + xbmc.core.displayCommunicationError(); + if (this.autoRefreshVideoPlaylist) { + setTimeout(jQuery.proxy(this.updateVideoPlaylist, this), + 2000); /* Slow down request period */ + } + } + }); + } + if (this.autoRefreshVideoPlaylist) { + setTimeout(jQuery.proxy(this.updateVideoPlaylist, this), 1000); + } + }, + 'error': function (data) { + xbmc.core.displayCommunicationError(); + if (this.autoRefreshVideoPlaylist) { + setTimeout(jQuery.proxy(this.updateVideoPlaylist, this), + 2000); /* Slow down request period */ + } + } + }); + } +}
\ No newline at end of file |