From 1dd2833ed701ec639bdf6e0c6756f1134c76a892 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Sun, 7 Jun 2015 23:16:42 -0400 Subject: [PATCH] fix encoding escape quotes --- dashboard-ui/mypreferenceswebclient.html | 8 + dashboard-ui/scripts/appsettings.js | 8 + dashboard-ui/scripts/chromecast.js | 3 +- dashboard-ui/scripts/htmlmediarenderer.js | 266 +++++++++++++++++ dashboard-ui/scripts/librarylist.js | 20 +- dashboard-ui/scripts/mediaplayer-video.js | 42 +-- dashboard-ui/scripts/mediaplayer.js | 278 +----------------- .../scripts/mypreferenceswebclient.js | 6 +- dashboard-ui/scripts/userlibraryaccess.js | 30 +- dashboard-ui/scripts/userparentalcontrol.js | 8 +- dashboard-ui/scripts/userpassword.js | 7 +- dashboard-ui/scripts/wizardstartpage.js | 24 +- dashboard-ui/thirdparty/cordova/chromecast.js | 3 +- dashboard-ui/userlibraryaccess.html | 5 +- dashboard-ui/userparentalcontrol.html | 7 +- dashboard-ui/userpassword.html | 7 +- dashboard-ui/wizardstart.html | 6 +- 17 files changed, 387 insertions(+), 341 deletions(-) create mode 100644 dashboard-ui/scripts/htmlmediarenderer.js diff --git a/dashboard-ui/mypreferenceswebclient.html b/dashboard-ui/mypreferenceswebclient.html index 9acf27c9f4..31959edb8d 100644 --- a/dashboard-ui/mypreferenceswebclient.html +++ b/dashboard-ui/mypreferenceswebclient.html @@ -151,6 +151,14 @@ +
+
+
+ + +
+
+
diff --git a/dashboard-ui/scripts/appsettings.js b/dashboard-ui/scripts/appsettings.js index d71aff97ea..37f5321929 100644 --- a/dashboard-ui/scripts/appsettings.js +++ b/dashboard-ui/scripts/appsettings.js @@ -24,6 +24,14 @@ return parseInt(store.getItem('chromecastBitrate') || '') || 3000000; }, + enableChromecastAc3: function (val) { + + if (val != null) { + update('enablechromecastac3', val.toString()); + } + + return store.getItem('enablechromecastac3') == 'true'; + }, enableExternalPlayers: function (val) { if (val != null) { diff --git a/dashboard-ui/scripts/chromecast.js b/dashboard-ui/scripts/chromecast.js index 586cf89f95..4c027cc096 100644 --- a/dashboard-ui/scripts/chromecast.js +++ b/dashboard-ui/scripts/chromecast.js @@ -344,7 +344,8 @@ accessToken: ApiClient.accessToken(), serverAddress: ApiClient.serverAddress(), maxBitrate: bitrateSetting, - receiverName: receiverName + receiverName: receiverName, + supportsAc3: AppSettings.enableChromecastAc3() }); getEndpointInfo().done(function (endpoint) { diff --git a/dashboard-ui/scripts/htmlmediarenderer.js b/dashboard-ui/scripts/htmlmediarenderer.js new file mode 100644 index 0000000000..83f5ad1fa9 --- /dev/null +++ b/dashboard-ui/scripts/htmlmediarenderer.js @@ -0,0 +1,266 @@ +(function () { + + function htmlMediaRenderer(type) { + + var mediaElement; + var self = this; + + function onEnded() { + $(self).trigger('ended'); + } + + function onTimeUpdate() { + $(self).trigger('timeupdate'); + } + + function onVolumeChange() { + $(self).trigger('volumechange'); + } + + function onOneAudioPlaying() { + $('.mediaPlayerAudioContainer').hide(); + } + + function onPlaying() { + $(self).trigger('playing'); + } + + function onPlay() { + $(self).trigger('play'); + } + + function onPause() { + $(self).trigger('pause'); + } + + function onClick() { + $(self).trigger('click'); + } + + function onDblClick() { + $(self).trigger('dblclick'); + } + + function onError() { + + var errorCode = this.error ? this.error.code : ''; + console.log('Media element error code: ' + errorCode); + + $(self).trigger('error'); + } + + function onLoadedMetadata() { + + // The IE video player won't autoplay without this + if ($.browser.msie) { + this.play(); + } + } + + function onOneVideoPlaying() { + + var requiresNativeControls = !MediaPlayer.enableCustomVideoControls(); + + if (requiresNativeControls) { + $(this).attr('controls', 'controls'); + } + + var currentSrc = (this.currentSrc || '').toLowerCase(); + + var parts = currentSrc.split('#'); + + if (parts.length > 1) { + + parts = parts[parts.length - 1].split('='); + + if (parts.length == 2) { + + var startPositionInSeekParam = parseFloat(parts[1]); + + // Appending #t=xxx to the query string doesn't seem to work with HLS + if (startPositionInSeekParam && currentSrc.indexOf('.m3u8') != -1) { + var element = this; + setTimeout(function () { + element.currentTime = startPositionInSeekParam; + }, 3000); + } + } + } + } + + function createAudioElement() { + + var elem = $('.mediaPlayerAudio'); + + if (!elem.length) { + var html = ''; + + var requiresControls = !MediaPlayer.canAutoPlayAudio(); + + if (requiresControls) { + html += '
';; + } else { + html += ''; + + $(document.body).append(html); + + elem = $('.mediaPlayerAudio'); + } + + return $(elem) + .on('timeupdate', onTimeUpdate) + .on('ended', onEnded) + .on('volumechange', onVolumeChange) + .one('playing', onOneAudioPlaying) + .on('play', onPlay) + .on('pause', onPause) + .on('playing', onPlaying) + .on('error', onError)[0]; + } + + function createVideoElement() { + + var elem = $('.itemVideo'); + + return $(elem) + .one('.loadedmetadata') + .one('playing', onOneVideoPlaying) + .on('timeupdate', onTimeUpdate) + .on('ended', onEnded) + .on('volumechange', onVolumeChange) + .on('play', onPlay) + .on('pause', onPause) + .on('playing', onPlaying) + .on('error', onError)[0]; + } + + self.currentTime = function (val) { + + if (mediaElement) { + if (val != null) { + mediaElement.currentTime = val; + return; + } + + return mediaElement.currentTime; + } + }; + + self.duration = function (val) { + + if (mediaElement) { + return mediaElement.duration; + } + + return null; + }; + + self.pause = function () { + if (mediaElement) { + mediaElement.pause(); + } + }; + + self.unpause = function () { + if (mediaElement) { + mediaElement.play(); + } + }; + + self.volume = function (val) { + if (mediaElement) { + if (val != null) { + mediaElement.volume = val; + return; + } + + return mediaElement.volume; + } + }; + + self.setCurrentSrc = function (val) { + + var elem = mediaElement; + + if (!elem) { + return; + } + + if (!val) { + elem.src = null; + elem.src = ""; + + // When the browser regains focus it may start auto-playing the last video + if ($.browser.safari) { + elem.src = 'files/dummy.mp4'; + elem.play(); + } + + return; + } + + elem.src = val; + + if (elem.tagName.toLowerCase() == 'audio') { + elem.play(); + } + else { + + $(elem).one("loadedmetadata.mediaplayerevent", onLoadedMetadata); + } + }; + + self.currentSrc = function () { + if (mediaElement) { + return mediaElement.currentSrc; + } + }; + + self.paused = function () { + + if (mediaElement) { + return mediaElement.paused; + } + + return false; + }; + + self.destroy = function () { + + self.setCurrentSrc(null); + + var elem = mediaElement; + + if (elem) { + + $(elem).off(); + + if (elem.tagName.toLowerCase() != 'audio') { + $(elem).remove(); + } + } + }; + + self.setPoster = function (url) { + var elem = mediaElement; + + if (elem) { + elem.poster = url; + } + }; + + if (type == 'audio') { + mediaElement = createAudioElement(); + } + else { + mediaElement = createVideoElement(); + } + } + + window.HtmlMediaRenderer = htmlMediaRenderer; + +})(); \ No newline at end of file diff --git a/dashboard-ui/scripts/librarylist.js b/dashboard-ui/scripts/librarylist.js index bc4a8491e2..0df70ae326 100644 --- a/dashboard-ui/scripts/librarylist.js +++ b/dashboard-ui/scripts/librarylist.js @@ -518,6 +518,15 @@ GroupItems: false }; + var target = $(e.target); + if (target.is('a') || target.is('button')) { + return; + } + + if (target.parents('a').length || target.parents('button').length) { + return; + } + ApiClient.getJSON(ApiClient.getUrl('Users/' + userId + '/Items/Latest', options)).done(function (items) { if (items.length == 1) { @@ -774,7 +783,8 @@ function onCardClick(e) { - if ($(e.target).is('.itemSelectionPanel') || $('.itemSelectionPanel', this).length) { + var target = $(e.target); + if (target.is('.itemSelectionPanel') || $('.itemSelectionPanel', this).length) { return false; } @@ -800,6 +810,14 @@ return; } + if (target.is('a') || target.is('button')) { + return; + } + + if (target.parents('a').length || target.parents('button').length) { + return; + } + if (AppSettings.enableItemPreviews()) { showItemsOverlay({ ids: [itemId], diff --git a/dashboard-ui/scripts/mediaplayer-video.js b/dashboard-ui/scripts/mediaplayer-video.js index 930c684039..fdf516e88c 100644 --- a/dashboard-ui/scripts/mediaplayer-video.js +++ b/dashboard-ui/scripts/mediaplayer-video.js @@ -2,7 +2,6 @@ function createVideoPlayer(self) { - var timeout; var initialVolume; var idleState = true; @@ -1051,29 +1050,31 @@ self.playVideo = function (item, mediaSource, startPosition) { - var streamInfo = self.createStreamInfo('Video', item, mediaSource, startPosition); + requirejs(['scripts/htmlmediarenderer'], function () { - // Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts - // This will start the transcoding process before actually feeding the video url into the player - if ($.browser.safari && !mediaSource.RunTimeTicks) { + var streamInfo = self.createStreamInfo('Video', item, mediaSource, startPosition); - Dashboard.showLoadingMsg(); + // Huge hack alert. Safari doesn't seem to like if the segments aren't available right away when playback starts + // This will start the transcoding process before actually feeding the video url into the player + if ($.browser.safari && !mediaSource.RunTimeTicks) { - ApiClient.ajax({ - type: 'GET', - url: streamInfo.url.replace('master.m3u8', 'live.m3u8') - }).always(function () { + Dashboard.showLoadingMsg(); - Dashboard.hideLoadingMsg(); + ApiClient.ajax({ + type: 'GET', + url: streamInfo.url.replace('master.m3u8', 'live.m3u8') + }).always(function () { - }).done(function () { + Dashboard.hideLoadingMsg(); + + }).done(function () { + self.playVideoInternal(item, mediaSource, startPosition, streamInfo); + }); + + } else { self.playVideoInternal(item, mediaSource, startPosition, streamInfo); - }); - - } else { - self.playVideoInternal(item, mediaSource, startPosition, streamInfo); - } - + } + }); }; function supportsContentOverVideoPlayer() { @@ -1107,7 +1108,10 @@ var requiresNativeControls = !self.enableCustomVideoControls(); // Can't autoplay in these browsers so we need to use the full controls - if (requiresNativeControls) { + if (requiresNativeControls && AppInfo.isNativeApp && $.browser.android) { + html += '