Conflicts:
	MediaBrowser.WebDashboard/dashboard-ui/scripts/mediaplayer-video.js
This commit is contained in:
Luke Pulverenti 2015-06-07 17:23:05 -04:00
commit 4a0f78149a
16 changed files with 433 additions and 228 deletions

View File

@ -44,7 +44,7 @@
} }
.cardBox { .cardBox {
margin: 3px; margin: 2px;
} }
.largeCardMargin .cardBox { .largeCardMargin .cardBox {
@ -55,7 +55,7 @@
margin: 4px; margin: 4px;
} }
@media all and (max-width: 600px) { @media all and (max-width: 800px) {
.cardBox { .cardBox {
margin: 1px; margin: 1px;

View File

@ -282,7 +282,7 @@
} }
} }
@media all and (max-width: 1200px) { @media all and (max-width: 800px) {
/* They can use the left menu */ /* They can use the left menu */
.dashboardEntryHeaderButton { .dashboardEntryHeaderButton {

View File

@ -4,7 +4,7 @@
<title>${TitleLiveTV}</title> <title>${TitleLiveTV}</title>
</head> </head>
<body> <body>
<div id="liveTvSettingsPage" data-role="page" class="page type-interior liveTvSettingsPage liveTvPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Live%20TV"> <div id="liveTvSettingsPage" data-role="page" class="page type-interior liveTvSettingsPage liveTvPage" data-helpurl="https://github.com/MediaBrowser/Wiki/wiki/Live%20TV" data-require="scripts/livetvsettings">
<div data-role="content"> <div data-role="content">
<div class="content-primary"> <div class="content-primary">
@ -70,10 +70,6 @@
</div> </div>
</div> </div>
</div> </div>
<script type="text/javascript">
$('.liveTvSettingsForm').off('submit', LiveTvSettingsPage.onSubmit).on('submit', LiveTvSettingsPage.onSubmit);
</script>
</div> </div>
</body> </body>
</html> </html>

View File

@ -808,7 +808,11 @@
function getAlbumArtists(form) { function getAlbumArtists(form) {
return $('#txtAlbumArtist', form).val().split(';').map(function (a) { return $('#txtAlbumArtist', form).val().trim().split(';').filter(function(s){
return s.length > 0;
}).map(function (a) {
return { return {
Name: a Name: a
@ -818,7 +822,11 @@
function getArtists(form) { function getArtists(form) {
return $('#txtArtist', form).val().split(';').map(function (a) { return $('#txtArtist', form).val().trim().split(';').filter(function(s){
return s.length > 0;
}).map(function (a) {
return { return {
Name: a Name: a

View File

@ -19,7 +19,29 @@
Dashboard.hideLoadingMsg(); Dashboard.hideLoadingMsg();
} }
$(document).on('pageshow', "#liveTvSettingsPage", function () { function onSubmit() {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getNamedConfiguration("livetv").done(function (config) {
config.GuideDays = $('#selectGuideDays', form).val() || null;
config.EnableMovieProviders = $('#chkMovies', form).checked();
ApiClient.updateNamedConfiguration("livetv", config).done(Dashboard.processServerConfigurationUpdateResult);
});
// Disable default form submission
return false;
}
$(document).on('pageinitdepends', "#liveTvSettingsPage", function () {
$('.liveTvSettingsForm').off('submit', onSubmit).on('submit', onSubmit);
}).on('pageshowready', "#liveTvSettingsPage", function () {
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
@ -37,25 +59,4 @@
}); });
window.LiveTvSettingsPage = {
onSubmit: function () {
Dashboard.showLoadingMsg();
var form = this;
ApiClient.getNamedConfiguration("livetv").done(function (config) {
config.GuideDays = $('#selectGuideDays', form).val() || null;
config.EnableMovieProviders = $('#chkMovies', form).checked();
ApiClient.updateNamedConfiguration("livetv", config).done(Dashboard.processServerConfigurationUpdateResult);
});
// Disable default form submission
return false;
}
};
})(jQuery, document, window); })(jQuery, document, window);

View File

@ -271,7 +271,7 @@
var mediaControls = $("#videoPlayer"); var mediaControls = $("#videoPlayer");
var state = self.getPlayerStateInternal(self.currentMediaElement, item, self.currentMediaSource); var state = self.getPlayerStateInternal(self.currentMediaRenderer, item, self.currentMediaSource);
var url = ""; var url = "";
var imageWidth = 400; var imageWidth = 400;
@ -751,7 +751,7 @@
return currentStream.Type == "Audio"; return currentStream.Type == "Audio";
}); });
var currentIndex = getParameterByName('AudioStreamIndex', self.getCurrentSrc(self.currentMediaElement)); var currentIndex = getParameterByName('AudioStreamIndex', self.getCurrentSrc(self.currentMediaRenderer));
var html = ''; var html = '';
html += '<div class="videoPlayerPopupContent">'; html += '<div class="videoPlayerPopupContent">';
@ -917,7 +917,7 @@
function getQualityFlyoutHtml() { function getQualityFlyoutHtml() {
var currentSrc = self.getCurrentSrc(self.currentMediaElement).toLowerCase(); var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase();
var isStatic = currentSrc.indexOf('static=true') != -1; var isStatic = currentSrc.indexOf('static=true') != -1;
var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) { var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) {
@ -1042,13 +1042,11 @@
}; };
// Replace audio version // Replace audio version
self.cleanup = function (playerElement) { self.cleanup = function (mediaRenderer) {
if (playerElement.tagName.toLowerCase() == 'video') { currentTimeElement.html('--:--');
currentTimeElement.html('--:--');
unbindEventsForPlayback(); unbindEventsForPlayback();
}
}; };
self.playVideo = function (item, mediaSource, startPosition) { self.playVideo = function (item, mediaSource, startPosition) {
@ -1109,10 +1107,7 @@
var requiresNativeControls = !self.enableCustomVideoControls(); var requiresNativeControls = !self.enableCustomVideoControls();
// Can't autoplay in these browsers so we need to use the full controls // Can't autoplay in these browsers so we need to use the full controls
if (requiresNativeControls && AppInfo.isNativeApp && $.browser.android) { if (requiresNativeControls) {
html += '<video data-viblast-key="N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=" class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" ' + posterCode + ' webkit-playsinline>';
}
else if (requiresNativeControls) {
html += '<video data-viblast-key="N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=" class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" controls="controls"' + posterCode + ' webkit-playsinline>'; html += '<video data-viblast-key="N8FjNTQ3NDdhZqZhNGI5NWU5ZTI=" class="itemVideo" id="itemVideo" preload="metadata" autoplay="autoplay" crossorigin="anonymous" controls="controls"' + posterCode + ' webkit-playsinline>';
} }
else { else {
@ -1192,45 +1187,18 @@
videoControls.removeClass('hide'); videoControls.removeClass('hide');
} }
var video = $("video", videoElement); var mediaRenderer = new HtmlMediaRenderer('video');
initialVolume = self.getSavedVolume(); initialVolume = self.getSavedVolume();
video.each(function () { mediaRenderer.volume(initialVolume);
this.volume = initialVolume;
});
volumeSlider.val(initialVolume).slider('refresh'); volumeSlider.val(initialVolume).slider('refresh');
updateVolumeButtons(initialVolume); updateVolumeButtons(initialVolume);
video.one("loadedmetadata.mediaplayerevent", function (e) { $(mediaRenderer).on("volumechange.mediaplayerevent", function (e) {
// The IE video player won't autoplay without this updateVolumeButtons(this.volume());
if ($.browser.msie) {
this.play();
}
}).one("playing.mediaplayerevent", function (e) {
// TODO: This is not working in chrome. Is it too early?
// Appending #t=xxx to the query string doesn't seem to work with HLS
if (startPositionInSeekParam && this.currentSrc && this.currentSrc.toLowerCase().indexOf('.m3u8') != -1) {
var element = this;
setTimeout(function () {
element.currentTime = startPositionInSeekParam;
}, 3000);
}
if (requiresNativeControls) {
$(this).attr('controls', 'controls');
}
}).on("volumechange.mediaplayerevent", function (e) {
var vol = this.volume;
updateVolumeButtons(vol);
}).one("playing.mediaplayerevent", function () { }).one("playing.mediaplayerevent", function () {
@ -1269,9 +1237,6 @@
self.stop(); self.stop();
var errorCode = this.error ? this.error.code : '';
console.log('Html5 Video error code: ' + errorCode);
var errorMsg = Globalize.translate('MessageErrorPlayingVideo'); var errorMsg = Globalize.translate('MessageErrorPlayingVideo');
if (item.Type == "TvChannel") { if (item.Type == "TvChannel") {
@ -1296,7 +1261,7 @@
}).on("click.mediaplayerevent", function (e) { }).on("click.mediaplayerevent", function (e) {
if (!$.browser.mobile) { if (!$.browser.mobile) {
if (this.paused) { if (this.paused()) {
self.unpause(); self.unpause();
} else { } else {
self.pause(); self.pause();
@ -1318,7 +1283,7 @@
$('body').addClass('bodyWithPopupOpen'); $('body').addClass('bodyWithPopupOpen');
self.currentMediaElement = video[0]; self.currentMediaRenderer = mediaRenderer;
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks; self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
self.updateNowPlayingInfo(item); self.updateNowPlayingInfo(item);

View File

@ -4,12 +4,11 @@
var self = this; var self = this;
var testableVideoElement = document.createElement('video');
var currentProgressInterval; var currentProgressInterval;
var canClientSeek; var canClientSeek;
var currentPlaylistIndex = 0; var currentPlaylistIndex = 0;
self.currentMediaElement = null; self.currentMediaRenderer = null;
self.currentItem = null; self.currentItem = null;
self.currentMediaSource = null; self.currentMediaSource = null;
@ -395,20 +394,20 @@
return profile; return profile;
}; };
self.updateCanClientSeek = function (elem) { self.updateCanClientSeek = function (mediaRenderer) {
var duration = elem.duration; var duration = mediaRenderer.duration();
canClientSeek = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY; canClientSeek = duration && !isNaN(duration) && duration != Number.POSITIVE_INFINITY && duration != Number.NEGATIVE_INFINITY;
}; };
self.getCurrentSrc = function (mediaElement) { self.getCurrentSrc = function (mediaRenderer) {
return mediaElement.currentSrc; return mediaRenderer.currentSrc();
}; };
self.getCurrentTicks = function (mediaElement) { self.getCurrentTicks = function (mediaRenderer) {
var playerTime = Math.floor(10000000 * (mediaElement || self.currentMediaElement).currentTime); var playerTime = Math.floor(10000000 * (mediaRenderer || self.currentMediaRenderer).currentTime());
playerTime += self.startTimeTicksOffset; playerTime += self.startTimeTicksOffset;
@ -429,7 +428,7 @@
currentProgressInterval = setInterval(function () { currentProgressInterval = setInterval(function () {
if (self.currentMediaElement) { if (self.currentMediaRenderer) {
if ((new Date().getTime() - self.lastProgressReport) > intervalTime) { if ((new Date().getTime() - self.lastProgressReport) > intervalTime) {
@ -449,7 +448,7 @@
self.canPlayNativeHls = function () { self.canPlayNativeHls = function () {
var media = testableVideoElement; var media = document.createElement('video');
// safari // safari
if (media.canPlayType('application/x-mpegURL').replace(/no/, '') || if (media.canPlayType('application/x-mpegURL').replace(/no/, '') ||
@ -472,17 +471,17 @@
self.changeStream = function (ticks, params) { self.changeStream = function (ticks, params) {
var element = self.currentMediaElement; var mediaRenderer = self.currentMediaRenderer;
if (canClientSeek && params == null) { if (canClientSeek && params == null) {
element.currentTime = ticks / (1000 * 10000); mediaRenderer.currentTime(ticks / (1000 * 10000));
return; return;
} }
params = params || {}; params = params || {};
var currentSrc = element.currentSrc; var currentSrc = mediaRenderer.currentSrc();
var playSessionId = getParameterByName('PlaySessionId', currentSrc); var playSessionId = getParameterByName('PlaySessionId', currentSrc);
var liveStreamId = getParameterByName('LiveStreamId', currentSrc); var liveStreamId = getParameterByName('LiveStreamId', currentSrc);
@ -490,7 +489,7 @@
if (params.AudioStreamIndex == null && params.SubtitleStreamIndex == null && params.Bitrate == null) { if (params.AudioStreamIndex == null && params.SubtitleStreamIndex == null && params.Bitrate == null) {
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks || 0); currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks || 0);
changeStreamToUrl(element, playSessionId, currentSrc, ticks); changeStreamToUrl(mediaRenderer, playSessionId, currentSrc, ticks);
return; return;
} }
@ -514,23 +513,16 @@
self.currentSubtitleStreamIndex = subtitleStreamIndex; self.currentSubtitleStreamIndex = subtitleStreamIndex;
currentSrc = ApiClient.getUrl(self.currentMediaSource.TranscodingUrl); currentSrc = ApiClient.getUrl(self.currentMediaSource.TranscodingUrl);
changeStreamToUrl(element, playSessionId, currentSrc, ticks); changeStreamToUrl(mediaRenderer, playSessionId, currentSrc, ticks);
} }
}); });
}; };
function changeStreamToUrl(element, playSessionId, url, newPositionTicks) { function changeStreamToUrl(mediaRenderer, playSessionId, url, newPositionTicks) {
clearProgressInterval(); clearProgressInterval();
$(element).off('ended.playbackstopped').off('ended.playnext').one("loadedmetadata.mediaplayerevent", function (e) { $(mediaRenderer).off('ended.playbackstopped').off('ended.playnext').one("play", function () {
// The IE video player won't autoplay without this
if ($.browser.msie && self.currentItem.MediaType == "Video") {
this.play();
}
}).one("play", function () {
self.updateCanClientSeek(this); self.updateCanClientSeek(this);
@ -545,15 +537,14 @@
ApiClient.stopActiveEncodings(playSessionId).done(function () { ApiClient.stopActiveEncodings(playSessionId).done(function () {
self.startTimeTicksOffset = newPositionTicks; self.startTimeTicksOffset = newPositionTicks;
element.src = url; mediaRenderer.setCurrentSrc(url);
}); });
self.updateTextStreamUrls(newPositionTicks || 0); self.updateTextStreamUrls(newPositionTicks || 0);
} else { } else {
self.startTimeTicksOffset = newPositionTicks; self.startTimeTicksOffset = newPositionTicks;
element.src = url; mediaRenderer.setCurrentSrc(url);
element.play();
} }
} }
@ -587,7 +578,7 @@
currentTimeElement.html(timeText); currentTimeElement.html(timeText);
} }
var state = self.getPlayerStateInternal(self.currentMediaElement, self.currentItem, self.currentMediaSource); var state = self.getPlayerStateInternal(self.currentMediaRenderer, self.currentItem, self.currentMediaSource);
$(self).trigger('positionchange', [state]); $(self).trigger('positionchange', [state]);
}; };
@ -902,7 +893,7 @@
} else if (item.MediaType === "Audio") { } else if (item.MediaType === "Audio") {
self.currentMediaElement = playAudio(item, self.currentMediaSource, startPosition); self.currentMediaRenderer = playAudio(item, self.currentMediaSource, startPosition);
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks; self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
} }
@ -1071,7 +1062,7 @@
self.queue = function (options) { self.queue = function (options) {
if (!self.currentMediaElement) { if (!self.playlist.length) {
self.play(options); self.play(options);
return; return;
} }
@ -1105,7 +1096,7 @@
self.queueNext = function (options) { self.queueNext = function (options) {
if (!self.currentMediaElement) { if (!self.playlist.length) {
self.play(options); self.play(options);
return; return;
} }
@ -1136,11 +1127,11 @@
self.pause = function () { self.pause = function () {
self.currentMediaElement.pause(); self.currentMediaRenderer.pause();
}; };
self.unpause = function () { self.unpause = function () {
self.currentMediaElement.play(); self.currentMediaRenderer.unpause();
}; };
self.seek = function (position) { self.seek = function (position) {
@ -1159,12 +1150,12 @@
}; };
self.volume = function () { self.volume = function () {
return self.currentMediaElement.volume * 100; return self.currentMediaRenderer.volume() * 100;
}; };
self.toggleMute = function () { self.toggleMute = function () {
if (self.currentMediaElement) { if (self.currentMediaRenderer) {
console.log('MediaPlayer toggling mute'); console.log('MediaPlayer toggling mute');
@ -1178,14 +1169,14 @@
self.volumeDown = function () { self.volumeDown = function () {
if (self.currentMediaElement) { if (self.currentMediaRenderer) {
self.setVolume(Math.max(self.volume() - 2, 0)); self.setVolume(Math.max(self.volume() - 2, 0));
} }
}; };
self.volumeUp = function () { self.volumeUp = function () {
if (self.currentMediaElement) { if (self.currentMediaRenderer) {
self.setVolume(Math.min(self.volume() + 2, 100)); self.setVolume(Math.min(self.volume() + 2, 100));
} }
}; };
@ -1193,14 +1184,14 @@
// Sets volume using a 0-100 scale // Sets volume using a 0-100 scale
self.setVolume = function (val) { self.setVolume = function (val) {
if (self.currentMediaElement) { if (self.currentMediaRenderer) {
console.log('MediaPlayer setting volume to ' + val); console.log('MediaPlayer setting volume to ' + val);
self.currentMediaElement.volume = val / 100; self.currentMediaRenderer.volume(val / 100);
self.onVolumeChanged(self.currentMediaElement); self.onVolumeChanged(self.currentMediaRenderer);
self.saveVolume(); //self.saveVolume();
} }
}; };
@ -1333,36 +1324,25 @@
self.stop = function () { self.stop = function () {
var elem = self.currentMediaElement; var mediaRenderer = self.currentMediaRenderer;
if (elem) { if (mediaRenderer) {
elem.pause(); mediaRenderer.pause();
$(elem).off("ended.playnext").one("ended", function () { $(mediaRenderer).off("ended.playnext").one("ended", function () {
$(this).off(); $(this).off();
if (this.tagName.toLowerCase() != 'audio') { this.destroy();
$(this).remove(); self.currentMediaRenderer = null;
}
elem.src = null;
elem.src = "";
self.currentMediaElement = null;
self.currentItem = null; self.currentItem = null;
self.currentMediaSource = null; self.currentMediaSource = null;
// When the browser regains focus it may start auto-playing the last video
if ($.browser.safari) {
elem.src = 'files/dummy.mp4';
elem.play();
}
}).trigger("ended"); }).trigger("ended");
} else { } else {
self.currentMediaElement = null; self.currentMediaRenderer = null;
self.currentItem = null; self.currentItem = null;
self.currentMediaSource = null; self.currentMediaSource = null;
} }
@ -1374,34 +1354,34 @@
}; };
self.isPlaying = function () { self.isPlaying = function () {
return self.currentMediaElement != null; return self.playlist.length > 0;
}; };
self.getPlayerState = function () { self.getPlayerState = function () {
var deferred = $.Deferred(); var deferred = $.Deferred();
var result = self.getPlayerStateInternal(self.currentMediaElement, self.currentItem, self.currentMediaSource); var result = self.getPlayerStateInternal(self.currentMediaRenderer, self.currentItem, self.currentMediaSource);
deferred.resolveWith(null, [result]); deferred.resolveWith(null, [result]);
return deferred.promise(); return deferred.promise();
}; };
self.getPlayerStateInternal = function (playerElement, item, mediaSource) { self.getPlayerStateInternal = function (mediaRenderer, item, mediaSource) {
var state = { var state = {
PlayState: {} PlayState: {}
}; };
if (playerElement) { if (mediaRenderer) {
state.PlayState.VolumeLevel = playerElement.volume * 100; state.PlayState.VolumeLevel = mediaRenderer.volume() * 100;
state.PlayState.IsMuted = playerElement.volume == 0; state.PlayState.IsMuted = mediaRenderer.volume() == 0;
state.PlayState.IsPaused = playerElement.paused; state.PlayState.IsPaused = mediaRenderer.paused();
state.PlayState.PositionTicks = self.getCurrentTicks(playerElement); state.PlayState.PositionTicks = self.getCurrentTicks(mediaRenderer);
var currentSrc = playerElement.currentSrc; var currentSrc = mediaRenderer.currentSrc();
if (currentSrc) { if (currentSrc) {
@ -1521,22 +1501,22 @@
// Nothing to setup here // Nothing to setup here
}; };
self.onPlaybackStart = function (playerElement, item, mediaSource) { self.onPlaybackStart = function (mediaRenderer, item, mediaSource) {
self.updateCanClientSeek(playerElement); self.updateCanClientSeek(mediaRenderer);
var state = self.getPlayerStateInternal(playerElement, item, mediaSource); var state = self.getPlayerStateInternal(mediaRenderer, item, mediaSource);
$(self).trigger('playbackstart', [state]); $(self).trigger('playbackstart', [state]);
self.startProgressInterval(); self.startProgressInterval();
}; };
self.onVolumeChanged = function (playerElement) { self.onVolumeChanged = function (mediaRenderer) {
self.saveVolume(playerElement.volume); self.saveVolume(mediaRenderer.volume());
var state = self.getPlayerStateInternal(playerElement, self.currentItem, self.currentMediaSource); var state = self.getPlayerStateInternal(mediaRenderer, self.currentItem, self.currentMediaSource);
$(self).trigger('volumechange', [state]); $(self).trigger('volumechange', [state]);
}; };
@ -1551,11 +1531,11 @@
$('body').removeClass('bodyWithPopupOpen'); $('body').removeClass('bodyWithPopupOpen');
var playerElement = this; var mediaRenderer = this;
$(playerElement).off('.mediaplayerevent').off('ended.playbackstopped'); $(mediaRenderer).off('.mediaplayerevent').off('ended.playbackstopped');
self.cleanup(playerElement); self.cleanup(mediaRenderer);
clearProgressInterval(); clearProgressInterval();
@ -1570,14 +1550,14 @@
self.resetEnhancements(); self.resetEnhancements();
} }
var state = self.getPlayerStateInternal(playerElement, item, mediaSource); var state = self.getPlayerStateInternal(mediaRenderer, item, mediaSource);
$(self).trigger('playbackstop', [state]); $(self).trigger('playbackstop', [state]);
}; };
self.onPlaystateChange = function (playerElement) { self.onPlaystateChange = function (mediaRenderer) {
var state = self.getPlayerStateInternal(playerElement, self.currentItem, self.currentMediaSource); var state = self.getPlayerStateInternal(mediaRenderer, self.currentItem, self.currentMediaSource);
$(self).trigger('playstatechange', [state]); $(self).trigger('playstatechange', [state]);
}; };
@ -1585,16 +1565,15 @@
$(window).on("beforeunload", function () { $(window).on("beforeunload", function () {
// Try to report playback stopped before the browser closes // Try to report playback stopped before the browser closes
if (self.currentItem && self.currentMediaElement && currentProgressInterval) { if (self.currentItem && self.currentMediaRenderer && currentProgressInterval) {
self.onPlaybackStopped.call(self.currentMediaElement); self.onPlaybackStopped.call(self.currentMediaRenderer);
} }
}); });
function sendProgressUpdate() { function sendProgressUpdate() {
var element = self.currentMediaElement; var state = self.getPlayerStateInternal(self.currentMediaRenderer, self.currentItem, self.currentMediaSource);
var state = self.getPlayerStateInternal(element, self.currentItem, self.currentMediaSource);
var info = { var info = {
QueueableMediaTypes: state.NowPlayingItem.MediaType, QueueableMediaTypes: state.NowPlayingItem.MediaType,
@ -1615,9 +1594,13 @@
} }
} }
self._canPlayWebm = null;
self.canPlayWebm = function () { self.canPlayWebm = function () {
return testableVideoElement.canPlayType('video/webm').replace(/no/, ''); if (self._canPlayWebm == null) {
self._canPlayWebm = document.createElement('video').canPlayType('video/webm').replace(/no/, '');
}
return self._canPlayWebm;
}; };
self.canAutoPlayAudio = function () { self.canAutoPlayAudio = function () {
@ -1633,30 +1616,9 @@
return true; return true;
}; };
function getAudioElement() { function getAudioRenderer() {
var elem = $('.mediaPlayerAudio'); return new HtmlMediaRenderer('audio');
if (elem.length) {
return elem;
}
var html = '';
var requiresControls = !self.canAutoPlayAudio();
if (requiresControls) {
html += '<div class="mediaPlayerAudioContainer"><div class="mediaPlayerAudioContainerInner">';;
} else {
html += '<div class="mediaPlayerAudioContainer" style="display:none;"><div class="mediaPlayerAudioContainerInner">';;
}
html += '<audio class="mediaPlayerAudio" crossorigin="anonymous" controls>';
html += '</audio></div></div>';
$(document.body).append(html);
return $('.mediaPlayerAudio');
} }
function onTimeUpdate() { function onTimeUpdate() {
@ -1673,14 +1635,13 @@
var initialVolume = self.getSavedVolume(); var initialVolume = self.getSavedVolume();
return getAudioElement().each(function () { var mediaRenderer = getAudioRenderer();
this.src = audioUrl; mediaRenderer.setCurrentSrc(audioUrl);
this.volume = initialVolume; mediaRenderer.volume(initialVolume);
this.poster = self.getPosterUrl(item); mediaRenderer.setPoster(self.getPosterUrl(item));
this.play();
}).on("volumechange.mediaplayerevent", function () { $(mediaRenderer).on("volumechange.mediaplayerevent", function () {
console.log('audio element event: volumechange'); console.log('audio element event: volumechange');
@ -1690,8 +1651,6 @@
console.log('audio element event: playing'); console.log('audio element event: playing');
$('.mediaPlayerAudioContainer').hide();
// For some reason this is firing at the start, so don't bind until playback has begun // For some reason this is firing at the start, so don't bind until playback has begun
$(this).on("ended.playbackstopped", self.onPlaybackStopped).one('ended.playnext', self.playNextAfterEnded); $(this).on("ended.playbackstopped", self.onPlaybackStopped).one('ended.playnext', self.playNextAfterEnded);
@ -1715,7 +1674,9 @@
// In the event timeupdate isn't firing, at least we can update when this happens // In the event timeupdate isn't firing, at least we can update when this happens
self.setCurrentTime(self.getCurrentTicks()); self.setCurrentTime(self.getCurrentTicks());
}).on("timeupdate.mediaplayerevent", onTimeUpdate)[0]; }).on("timeupdate.mediaplayerevent", onTimeUpdate);
return mediaRenderer;
}; };
var getItemFields = "MediaSources,Chapters"; var getItemFields = "MediaSources,Chapters";
@ -1736,4 +1697,265 @@
}); });
})(document, setTimeout, clearTimeout, screen, window.appStorage, $, setInterval, window); })(document, setTimeout, clearTimeout, screen, window.appStorage, $, setInterval, window);
(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 currentSrc = (this.currentSrc || '').toLowerCase();
var parts = currentSrc.split('#');
if (parts.length > 1) {
var 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 += '<div class="mediaPlayerAudioContainer"><div class="mediaPlayerAudioContainerInner">';;
} else {
html += '<div class="mediaPlayerAudioContainer" style="display:none;"><div class="mediaPlayerAudioContainerInner">';;
}
html += '<audio class="mediaPlayerAudio" crossorigin="anonymous" controls>';
html += '</audio></div></div>';
$(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;
})();

View File

@ -257,7 +257,7 @@
reloadItems(page); reloadItems(page);
}); });
}).on('pagebeforeshowready', "#boxsetsPage", function () { }).on('pageshowready', "#boxsetsPage", function () {
var page = this; var page = this;
@ -273,6 +273,9 @@
$('.collectionTabs', page).show(); $('.collectionTabs', page).show();
$('.movieTabs', page).hide(); $('.movieTabs', page).hide();
query.ParentId = LibraryMenu.getTopParentId(); query.ParentId = LibraryMenu.getTopParentId();
// Doing this for now due to reports of the page being empty for AutoBoxSet users
query.ParentId = null;
} }
var limit = LibraryBrowser.getDefaultPageSize(); var limit = LibraryBrowser.getDefaultPageSize();
@ -296,8 +299,6 @@
} }
}); });
}).on('pageshowready', "#boxsetsPage", function () {
updateFilterControls(this); updateFilterControls(this);
}); });

View File

@ -1,6 +1,7 @@
(function () { (function () {
function connectToServer(page, server) { var serverList = [];
function connectToServer(page, server) {
Dashboard.showLoadingMsg(); Dashboard.showLoadingMsg();
@ -109,6 +110,8 @@
function renderServers(page, servers) { function renderServers(page, servers) {
serverList = servers;
if (servers.length) { if (servers.length) {
$('.noServersMessage', page).hide(); $('.noServersMessage', page).hide();
} else { } else {
@ -178,7 +181,13 @@
ConnectionManager.deleteServer(id).done(function () { ConnectionManager.deleteServer(id).done(function () {
Dashboard.hideModalLoadingMsg(); Dashboard.hideModalLoadingMsg();
loadPage(page);
// Just re-render the servers without discovering them again
// If we re-discover then the one they deleted may just come back
var newServerList = serverList.filter(function(s){
return s.Id != id;
});
renderServers(page, newServerList);
}).fail(function () { }).fail(function () {
@ -195,6 +204,7 @@
ConnectionManager.rejectServer(id).done(function () { ConnectionManager.rejectServer(id).done(function () {
Dashboard.hideModalLoadingMsg(); Dashboard.hideModalLoadingMsg();
loadPage(page); loadPage(page);
}).fail(function () { }).fail(function () {

View File

@ -1,6 +1,8 @@
(function (window, $) { (function (window, $) {
function onSubmit(page) { function onSubmit() {
var page = $(this).parents('.page');
if ($('#chkAccept', page).checked()) { if ($('#chkAccept', page).checked()) {
Dashboard.navigate('wizardfinish.html'); Dashboard.navigate('wizardfinish.html');
@ -11,18 +13,13 @@
title: '' title: ''
}); });
} }
return false;
} }
window.WizardAgreementPage = { $(document).on('pageinitdepends', '#wizardAgreementPage', function(){
onSubmit: function () { $('.wizardAgreementForm').off('submit', onSubmit).on('submit', onSubmit);
});
var page = $(this).parents('.page');
onSubmit(page);
return false;
}
};
})(window, jQuery); })(window, jQuery);

View File

@ -1,8 +1,8 @@
var WizardFinishPage = { (function(){
onFinish: function () { function onFinish() {
ApiClient.ajax({ ApiClient.ajax({
url: ApiClient.getUrl('Startup/Complete'), url: ApiClient.getUrl('Startup/Complete'),
type: 'POST' type: 'POST'
@ -11,5 +11,11 @@
Dashboard.navigate('dashboard.html'); Dashboard.navigate('dashboard.html');
}); });
} }
};
$(document).on('pageinitdepends', '#wizardFinishPage', function(){
$('.btnWizardNext', this).on('click', onFinish);
});
})();

View File

@ -1,6 +1,6 @@
(function ($, document) { (function ($, document) {
$(document).on('pageinit', "#wizardServicePage", function () { $(document).on('pageinitdepends', "#wizardServicePage", function () {
var page = this; var page = this;

View File

@ -964,6 +964,9 @@
function normalizeAddress(address) { function normalizeAddress(address) {
// attempt to correct bad input
address = address.trim();
if (address.toLowerCase().indexOf('http') != 0) { if (address.toLowerCase().indexOf('http') != 0) {
address = "http://" + address; address = "http://" + address;
} }

View File

@ -4,7 +4,7 @@
<title>Emby</title> <title>Emby</title>
</head> </head>
<body> <body>
<div id="wizardAgreementPage" data-role="page" class="page standalonePage wizardPage"> <div id="wizardAgreementPage" data-role="page" class="page standalonePage wizardPage" data-require="scripts/wizardagreement">
<div data-role="content"> <div data-role="content">
@ -36,10 +36,6 @@
</div> </div>
</div> </div>
<script type="text/javascript">
$('.wizardAgreementForm').off('submit', WizardAgreementPage.onSubmit).on('submit', WizardAgreementPage.onSubmit);
</script>
</div> </div>
</body> </body>
</html> </html>

View File

@ -4,7 +4,7 @@
<title>Emby</title> <title>Emby</title>
</head> </head>
<body> <body>
<div id="wizardFinishPage" data-role="page" class="page standalonePage wizardPage"> <div id="wizardFinishPage" data-role="page" class="page standalonePage wizardPage" data-require="scripts/wizardfinishpage">
<div data-role="content"> <div data-role="content">
@ -39,7 +39,7 @@
<div class="wizardNavigation"> <div class="wizardNavigation">
<button type="button" data-iconpos="left" data-icon="arrow-l" data-inline="true" onclick="history.back();">${LabelPrevious}</button> <button type="button" data-iconpos="left" data-icon="arrow-l" data-inline="true" onclick="history.back();">${LabelPrevious}</button>
<button type="button" data-iconpos="right" data-icon="check" data-inline="true" onclick="WizardFinishPage.onFinish();" data-theme="b">${LabelFinish}</button> <button type="button" data-iconpos="right" data-icon="check" data-inline="true" class="btnWizardNext" data-theme="b">${LabelFinish}</button>
</div> </div>
</div> </div>

View File

@ -4,7 +4,7 @@
<title>Emby</title> <title>Emby</title>
</head> </head>
<body> <body>
<div id="wizardServicePage" data-role="page" class="page standalonePage wizardPage mediaLibraryPage"> <div id="wizardServicePage" data-role="page" class="page standalonePage wizardPage mediaLibraryPage" data-require="scripts/wizardservice">
<div data-role="content"> <div data-role="content">