mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-17 19:08:18 -07:00
modularize media player
This commit is contained in:
parent
db61c30557
commit
440bfc832a
@ -282,7 +282,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media all and (max-width: 1200px) {
|
||||
@media all and (max-width: 800px) {
|
||||
|
||||
/* They can use the left menu */
|
||||
.dashboardEntryHeaderButton {
|
||||
|
@ -271,7 +271,7 @@
|
||||
|
||||
var mediaControls = $("#videoPlayer");
|
||||
|
||||
var state = self.getPlayerStateInternal(self.currentMediaElement, item, self.currentMediaSource);
|
||||
var state = self.getPlayerStateInternal(self.currentMediaRenderer, item, self.currentMediaSource);
|
||||
|
||||
var url = "";
|
||||
var imageWidth = 400;
|
||||
@ -751,7 +751,7 @@
|
||||
return currentStream.Type == "Audio";
|
||||
});
|
||||
|
||||
var currentIndex = getParameterByName('AudioStreamIndex', self.getCurrentSrc(self.currentMediaElement));
|
||||
var currentIndex = getParameterByName('AudioStreamIndex', self.getCurrentSrc(self.currentMediaRenderer));
|
||||
|
||||
var html = '';
|
||||
html += '<div class="videoPlayerPopupContent">';
|
||||
@ -917,7 +917,7 @@
|
||||
|
||||
function getQualityFlyoutHtml() {
|
||||
|
||||
var currentSrc = self.getCurrentSrc(self.currentMediaElement).toLowerCase();
|
||||
var currentSrc = self.getCurrentSrc(self.currentMediaRenderer).toLowerCase();
|
||||
var isStatic = currentSrc.indexOf('static=true') != -1;
|
||||
|
||||
var videoStream = self.currentMediaSource.MediaStreams.filter(function (stream) {
|
||||
@ -1042,13 +1042,11 @@
|
||||
};
|
||||
|
||||
// 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) {
|
||||
@ -1189,41 +1187,18 @@
|
||||
videoControls.removeClass('hide');
|
||||
}
|
||||
|
||||
var video = $("video", videoElement);
|
||||
var mediaRenderer = new HtmlMediaRenderer('video');
|
||||
|
||||
initialVolume = self.getSavedVolume();
|
||||
|
||||
video.each(function () {
|
||||
this.volume = initialVolume;
|
||||
});
|
||||
mediaRenderer.volume(initialVolume);
|
||||
|
||||
volumeSlider.val(initialVolume).slider('refresh');
|
||||
updateVolumeButtons(initialVolume);
|
||||
|
||||
video.one("loadedmetadata.mediaplayerevent", function (e) {
|
||||
$(mediaRenderer).on("volumechange.mediaplayerevent", function (e) {
|
||||
|
||||
// The IE video player won't autoplay without this
|
||||
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);
|
||||
}
|
||||
|
||||
}).on("volumechange.mediaplayerevent", function (e) {
|
||||
|
||||
var vol = this.volume;
|
||||
|
||||
updateVolumeButtons(vol);
|
||||
updateVolumeButtons(this.volume());
|
||||
|
||||
}).one("playing.mediaplayerevent", function () {
|
||||
|
||||
@ -1262,9 +1237,6 @@
|
||||
|
||||
self.stop();
|
||||
|
||||
var errorCode = this.error ? this.error.code : '';
|
||||
console.log('Html5 Video error code: ' + errorCode);
|
||||
|
||||
var errorMsg = Globalize.translate('MessageErrorPlayingVideo');
|
||||
|
||||
if (item.Type == "TvChannel") {
|
||||
@ -1289,7 +1261,7 @@
|
||||
}).on("click.mediaplayerevent", function (e) {
|
||||
|
||||
if (!$.browser.mobile) {
|
||||
if (this.paused) {
|
||||
if (this.paused()) {
|
||||
self.unpause();
|
||||
} else {
|
||||
self.pause();
|
||||
@ -1311,7 +1283,7 @@
|
||||
|
||||
$('body').addClass('bodyWithPopupOpen');
|
||||
|
||||
self.currentMediaElement = video[0];
|
||||
self.currentMediaRenderer = mediaRenderer;
|
||||
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
|
||||
|
||||
self.updateNowPlayingInfo(item);
|
||||
|
@ -4,12 +4,11 @@
|
||||
|
||||
var self = this;
|
||||
|
||||
var testableVideoElement = document.createElement('video');
|
||||
var currentProgressInterval;
|
||||
var canClientSeek;
|
||||
var currentPlaylistIndex = 0;
|
||||
|
||||
self.currentMediaElement = null;
|
||||
self.currentMediaRenderer = null;
|
||||
self.currentItem = null;
|
||||
self.currentMediaSource = null;
|
||||
|
||||
@ -395,20 +394,20 @@
|
||||
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;
|
||||
};
|
||||
|
||||
self.getCurrentSrc = function (mediaElement) {
|
||||
return mediaElement.currentSrc;
|
||||
self.getCurrentSrc = function (mediaRenderer) {
|
||||
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;
|
||||
|
||||
@ -429,7 +428,7 @@
|
||||
|
||||
currentProgressInterval = setInterval(function () {
|
||||
|
||||
if (self.currentMediaElement) {
|
||||
if (self.currentMediaRenderer) {
|
||||
|
||||
if ((new Date().getTime() - self.lastProgressReport) > intervalTime) {
|
||||
|
||||
@ -449,7 +448,7 @@
|
||||
|
||||
self.canPlayNativeHls = function () {
|
||||
|
||||
var media = testableVideoElement;
|
||||
var media = document.createElement('video');
|
||||
|
||||
// safari
|
||||
if (media.canPlayType('application/x-mpegURL').replace(/no/, '') ||
|
||||
@ -472,17 +471,17 @@
|
||||
|
||||
self.changeStream = function (ticks, params) {
|
||||
|
||||
var element = self.currentMediaElement;
|
||||
var mediaRenderer = self.currentMediaRenderer;
|
||||
|
||||
if (canClientSeek && params == null) {
|
||||
|
||||
element.currentTime = ticks / (1000 * 10000);
|
||||
mediaRenderer.currentTime(ticks / (1000 * 10000));
|
||||
return;
|
||||
}
|
||||
|
||||
params = params || {};
|
||||
|
||||
var currentSrc = element.currentSrc;
|
||||
var currentSrc = mediaRenderer.currentSrc();
|
||||
|
||||
var playSessionId = getParameterByName('PlaySessionId', currentSrc);
|
||||
var liveStreamId = getParameterByName('LiveStreamId', currentSrc);
|
||||
@ -490,7 +489,7 @@
|
||||
if (params.AudioStreamIndex == null && params.SubtitleStreamIndex == null && params.Bitrate == null) {
|
||||
|
||||
currentSrc = replaceQueryString(currentSrc, 'starttimeticks', ticks || 0);
|
||||
changeStreamToUrl(element, playSessionId, currentSrc, ticks);
|
||||
changeStreamToUrl(mediaRenderer, playSessionId, currentSrc, ticks);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -514,23 +513,16 @@
|
||||
self.currentSubtitleStreamIndex = subtitleStreamIndex;
|
||||
|
||||
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();
|
||||
|
||||
$(element).off('ended.playbackstopped').off('ended.playnext').one("loadedmetadata.mediaplayerevent", function (e) {
|
||||
|
||||
// The IE video player won't autoplay without this
|
||||
if ($.browser.msie && self.currentItem.MediaType == "Video") {
|
||||
this.play();
|
||||
}
|
||||
|
||||
}).one("play", function () {
|
||||
$(mediaRenderer).off('ended.playbackstopped').off('ended.playnext').one("play", function () {
|
||||
|
||||
self.updateCanClientSeek(this);
|
||||
|
||||
@ -545,15 +537,14 @@
|
||||
ApiClient.stopActiveEncodings(playSessionId).done(function () {
|
||||
|
||||
self.startTimeTicksOffset = newPositionTicks;
|
||||
element.src = url;
|
||||
mediaRenderer.setCurrentSrc(url);
|
||||
|
||||
});
|
||||
|
||||
self.updateTextStreamUrls(newPositionTicks || 0);
|
||||
} else {
|
||||
self.startTimeTicksOffset = newPositionTicks;
|
||||
element.src = url;
|
||||
element.play();
|
||||
mediaRenderer.setCurrentSrc(url);
|
||||
}
|
||||
}
|
||||
|
||||
@ -587,7 +578,7 @@
|
||||
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]);
|
||||
};
|
||||
@ -902,7 +893,7 @@
|
||||
|
||||
} else if (item.MediaType === "Audio") {
|
||||
|
||||
self.currentMediaElement = playAudio(item, self.currentMediaSource, startPosition);
|
||||
self.currentMediaRenderer = playAudio(item, self.currentMediaSource, startPosition);
|
||||
self.currentDurationTicks = self.currentMediaSource.RunTimeTicks;
|
||||
}
|
||||
|
||||
@ -1071,7 +1062,7 @@
|
||||
|
||||
self.queue = function (options) {
|
||||
|
||||
if (!self.currentMediaElement) {
|
||||
if (!self.playlist.length) {
|
||||
self.play(options);
|
||||
return;
|
||||
}
|
||||
@ -1105,7 +1096,7 @@
|
||||
|
||||
self.queueNext = function (options) {
|
||||
|
||||
if (!self.currentMediaElement) {
|
||||
if (!self.playlist.length) {
|
||||
self.play(options);
|
||||
return;
|
||||
}
|
||||
@ -1136,11 +1127,11 @@
|
||||
|
||||
self.pause = function () {
|
||||
|
||||
self.currentMediaElement.pause();
|
||||
self.currentMediaRenderer.pause();
|
||||
};
|
||||
|
||||
self.unpause = function () {
|
||||
self.currentMediaElement.play();
|
||||
self.currentMediaRenderer.unpause();
|
||||
};
|
||||
|
||||
self.seek = function (position) {
|
||||
@ -1159,12 +1150,12 @@
|
||||
};
|
||||
|
||||
self.volume = function () {
|
||||
return self.currentMediaElement.volume * 100;
|
||||
return self.currentMediaRenderer.volume() * 100;
|
||||
};
|
||||
|
||||
self.toggleMute = function () {
|
||||
|
||||
if (self.currentMediaElement) {
|
||||
if (self.currentMediaRenderer) {
|
||||
|
||||
console.log('MediaPlayer toggling mute');
|
||||
|
||||
@ -1178,14 +1169,14 @@
|
||||
|
||||
self.volumeDown = function () {
|
||||
|
||||
if (self.currentMediaElement) {
|
||||
if (self.currentMediaRenderer) {
|
||||
self.setVolume(Math.max(self.volume() - 2, 0));
|
||||
}
|
||||
};
|
||||
|
||||
self.volumeUp = function () {
|
||||
|
||||
if (self.currentMediaElement) {
|
||||
if (self.currentMediaRenderer) {
|
||||
self.setVolume(Math.min(self.volume() + 2, 100));
|
||||
}
|
||||
};
|
||||
@ -1193,14 +1184,14 @@
|
||||
// Sets volume using a 0-100 scale
|
||||
self.setVolume = function (val) {
|
||||
|
||||
if (self.currentMediaElement) {
|
||||
if (self.currentMediaRenderer) {
|
||||
|
||||
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 () {
|
||||
|
||||
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();
|
||||
|
||||
if (this.tagName.toLowerCase() != 'audio') {
|
||||
$(this).remove();
|
||||
}
|
||||
|
||||
elem.src = null;
|
||||
elem.src = "";
|
||||
self.currentMediaElement = null;
|
||||
this.destroy();
|
||||
self.currentMediaRenderer = null;
|
||||
self.currentItem = 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");
|
||||
|
||||
} else {
|
||||
self.currentMediaElement = null;
|
||||
self.currentMediaRenderer = null;
|
||||
self.currentItem = null;
|
||||
self.currentMediaSource = null;
|
||||
}
|
||||
@ -1374,34 +1354,34 @@
|
||||
};
|
||||
|
||||
self.isPlaying = function () {
|
||||
return self.currentMediaElement != null;
|
||||
return self.playlist.length > 0;
|
||||
};
|
||||
|
||||
self.getPlayerState = function () {
|
||||
|
||||
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]);
|
||||
|
||||
return deferred.promise();
|
||||
};
|
||||
|
||||
self.getPlayerStateInternal = function (playerElement, item, mediaSource) {
|
||||
self.getPlayerStateInternal = function (mediaRenderer, item, mediaSource) {
|
||||
|
||||
var state = {
|
||||
PlayState: {}
|
||||
};
|
||||
|
||||
if (playerElement) {
|
||||
if (mediaRenderer) {
|
||||
|
||||
state.PlayState.VolumeLevel = playerElement.volume * 100;
|
||||
state.PlayState.IsMuted = playerElement.volume == 0;
|
||||
state.PlayState.IsPaused = playerElement.paused;
|
||||
state.PlayState.PositionTicks = self.getCurrentTicks(playerElement);
|
||||
state.PlayState.VolumeLevel = mediaRenderer.volume() * 100;
|
||||
state.PlayState.IsMuted = mediaRenderer.volume() == 0;
|
||||
state.PlayState.IsPaused = mediaRenderer.paused();
|
||||
state.PlayState.PositionTicks = self.getCurrentTicks(mediaRenderer);
|
||||
|
||||
var currentSrc = playerElement.currentSrc;
|
||||
var currentSrc = mediaRenderer.currentSrc();
|
||||
|
||||
if (currentSrc) {
|
||||
|
||||
@ -1521,22 +1501,22 @@
|
||||
// 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.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]);
|
||||
};
|
||||
@ -1551,11 +1531,11 @@
|
||||
|
||||
$('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();
|
||||
|
||||
@ -1570,14 +1550,14 @@
|
||||
self.resetEnhancements();
|
||||
}
|
||||
|
||||
var state = self.getPlayerStateInternal(playerElement, item, mediaSource);
|
||||
var state = self.getPlayerStateInternal(mediaRenderer, item, mediaSource);
|
||||
|
||||
$(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]);
|
||||
};
|
||||
@ -1585,16 +1565,15 @@
|
||||
$(window).on("beforeunload", function () {
|
||||
|
||||
// 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() {
|
||||
|
||||
var element = self.currentMediaElement;
|
||||
var state = self.getPlayerStateInternal(element, self.currentItem, self.currentMediaSource);
|
||||
var state = self.getPlayerStateInternal(self.currentMediaRenderer, self.currentItem, self.currentMediaSource);
|
||||
|
||||
var info = {
|
||||
QueueableMediaTypes: state.NowPlayingItem.MediaType,
|
||||
@ -1615,9 +1594,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
self._canPlayWebm = null;
|
||||
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 () {
|
||||
@ -1633,30 +1616,9 @@
|
||||
return true;
|
||||
};
|
||||
|
||||
function getAudioElement() {
|
||||
function getAudioRenderer() {
|
||||
|
||||
var elem = $('.mediaPlayerAudio');
|
||||
|
||||
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');
|
||||
return new HtmlMediaRenderer('audio');
|
||||
}
|
||||
|
||||
function onTimeUpdate() {
|
||||
@ -1673,14 +1635,13 @@
|
||||
|
||||
var initialVolume = self.getSavedVolume();
|
||||
|
||||
return getAudioElement().each(function () {
|
||||
var mediaRenderer = getAudioRenderer();
|
||||
|
||||
this.src = audioUrl;
|
||||
this.volume = initialVolume;
|
||||
this.poster = self.getPosterUrl(item);
|
||||
this.play();
|
||||
mediaRenderer.setCurrentSrc(audioUrl);
|
||||
mediaRenderer.volume(initialVolume);
|
||||
mediaRenderer.setPoster(self.getPosterUrl(item));
|
||||
|
||||
}).on("volumechange.mediaplayerevent", function () {
|
||||
$(mediaRenderer).on("volumechange.mediaplayerevent", function () {
|
||||
|
||||
console.log('audio element event: volumechange');
|
||||
|
||||
@ -1690,8 +1651,6 @@
|
||||
|
||||
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
|
||||
$(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
|
||||
self.setCurrentTime(self.getCurrentTicks());
|
||||
|
||||
}).on("timeupdate.mediaplayerevent", onTimeUpdate)[0];
|
||||
}).on("timeupdate.mediaplayerevent", onTimeUpdate);
|
||||
|
||||
return mediaRenderer;
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
})();
|
Loading…
Reference in New Issue
Block a user