jellyfish-web/dashboard-ui/bower_components/emby-webcomponents/htmlvideoplayer/htmlmediahelper.js
2018-10-23 01:05:09 +03:00

218 lines
No EOL
9.4 KiB
JavaScript

define(["appSettings", "browser", "events"], function(appSettings, browser, events) {
"use strict";
function getSavedVolume() {
return appSettings.get("volume") || 1
}
function saveVolume(value) {
value && appSettings.set("volume", value)
}
function getCrossOriginValue(mediaSource) {
return mediaSource.IsRemote ? null : "anonymous"
}
function canPlayNativeHls() {
var media = document.createElement("video");
return !(!media.canPlayType("application/x-mpegURL").replace(/no/, "") && !media.canPlayType("application/vnd.apple.mpegURL").replace(/no/, ""))
}
function enableHlsShakaPlayer(item, mediaSource, mediaType) {
if (window.MediaSource && MediaSource.isTypeSupported) {
if (canPlayNativeHls()) {
if (browser.edge && "Video" === mediaType) return !0;
mediaSource.RunTimeTicks
}
return !0
}
return !1
}
function enableHlsJsPlayer(runTimeTicks, mediaType) {
if (null == window.MediaSource) return !1;
if (browser.iOS) return !1;
if (browser.tizen || browser.web0s) return !1;
if (canPlayNativeHls()) {
if (browser.android && "Audio" === mediaType) return !0;
if (browser.edge, runTimeTicks) return !1
}
return !0
}
function handleHlsJsMediaError(instance, reject) {
var hlsPlayer = instance._hlsPlayer;
if (hlsPlayer) {
var now = Date.now();
window.performance && window.performance.now && (now = performance.now()), !recoverDecodingErrorDate || now - recoverDecodingErrorDate > 3e3 ? (recoverDecodingErrorDate = now, console.log("try to recover media Error ..."), hlsPlayer.recoverMediaError()) : !recoverSwapAudioCodecDate || now - recoverSwapAudioCodecDate > 3e3 ? (recoverSwapAudioCodecDate = now, console.log("try to swap Audio Codec and recover media Error ..."), hlsPlayer.swapAudioCodec(), hlsPlayer.recoverMediaError()) : (console.error("cannot recover, last media error recovery failed ..."), reject ? reject() : onErrorInternal(instance, "mediadecodeerror"))
}
}
function onErrorInternal(instance, type) {
instance.destroyCustomTrack && instance.destroyCustomTrack(instance._mediaElement), events.trigger(instance, "error", [{
type: type
}])
}
function isValidDuration(duration) {
return !(!duration || isNaN(duration) || duration === Number.POSITIVE_INFINITY || duration === Number.NEGATIVE_INFINITY)
}
function setCurrentTimeIfNeeded(element, seconds, allowance) {
Math.abs((element.currentTime || 0) - seconds) >= allowance && (element.currentTime = seconds)
}
function seekOnPlaybackStart(instance, element, ticks) {
var seconds = (ticks || 0) / 1e7;
if (seconds) {
(instance.currentSrc() || "").toLowerCase();
setCurrentTimeIfNeeded(element, seconds, 5), setTimeout(function() {
setCurrentTimeIfNeeded(element, seconds, 10)
}, 2500)
}
}
function applySrc(elem, src, options) {
return window.Windows && options.mediaSource && options.mediaSource.IsLocal ? Windows.Storage.StorageFile.getFileFromPathAsync(options.url).then(function(file) {
var playlist = new Windows.Media.Playback.MediaPlaybackList,
source1 = Windows.Media.Core.MediaSource.createFromStorageFile(file),
startTime = (options.playerStartPositionTicks || 0) / 1e4;
return playlist.items.append(new Windows.Media.Playback.MediaPlaybackItem(source1, startTime)), elem.src = URL.createObjectURL(playlist, {
oneTimeOnly: !0
}), Promise.resolve()
}) : (elem.src = src, Promise.resolve())
}
function onSuccessfulPlay(elem, onErrorFn) {
elem.addEventListener("error", onErrorFn)
}
function playWithPromise(elem, onErrorFn) {
try {
var promise = elem.play();
return promise && promise.then ? promise.catch(function(e) {
var errorName = (e.name || "").toLowerCase();
return "notallowederror" === errorName || "aborterror" === errorName ? (onSuccessfulPlay(elem, onErrorFn), Promise.resolve()) : Promise.reject()
}) : (onSuccessfulPlay(elem, onErrorFn), Promise.resolve())
} catch (err) {
return console.log("error calling video.play: " + err), Promise.reject()
}
}
function destroyCastPlayer(instance) {
var player = instance._castPlayer;
if (player) {
try {
player.unload()
} catch (err) {
console.log(err)
}
instance._castPlayer = null
}
}
function destroyShakaPlayer(instance) {
var player = instance._shakaPlayer;
if (player) {
try {
player.destroy()
} catch (err) {
console.log(err)
}
instance._shakaPlayer = null
}
}
function destroyHlsPlayer(instance) {
var player = instance._hlsPlayer;
if (player) {
try {
player.destroy()
} catch (err) {
console.log(err)
}
instance._hlsPlayer = null
}
}
function destroyFlvPlayer(instance) {
var player = instance._flvPlayer;
if (player) {
try {
player.unload(), player.detachMediaElement(), player.destroy()
} catch (err) {
console.log(err)
}
instance._flvPlayer = null
}
}
function bindEventsToHlsPlayer(instance, hls, elem, onErrorFn, resolve, reject) {
hls.on(Hls.Events.MANIFEST_PARSED, function() {
playWithPromise(elem, onErrorFn).then(resolve, function() {
reject && (reject(), reject = null)
})
}), hls.on(Hls.Events.ERROR, function(event, data) {
switch (console.log("HLS Error: Type: " + data.type + " Details: " + (data.details || "") + " Fatal: " + (data.fatal || !1)), data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
if (data.response && data.response.code && data.response.code >= 400) return console.log("hls.js response error code: " + data.response.code), hls.destroy(), void(reject ? (reject("servererror"), reject = null) : onErrorInternal(instance, "servererror"))
}
if (data.fatal) switch (data.type) {
case Hls.ErrorTypes.NETWORK_ERROR:
data.response && 0 === data.response.code ? (console.log("hls.js response error code: " + data.response.code), hls.destroy(), reject ? (reject("network"), reject = null) : onErrorInternal(instance, "network")) : (console.log("fatal network error encountered, try to recover"), hls.startLoad());
break;
case Hls.ErrorTypes.MEDIA_ERROR:
console.log("fatal media error encountered, try to recover");
var currentReject = reject;
reject = null, handleHlsJsMediaError(instance, currentReject);
break;
default:
console.log("Cannot recover from hls error - destroy and trigger error"), hls.destroy(), reject ? (reject(), reject = null) : onErrorInternal(instance, "mediadecodeerror")
}
})
}
function onEndedInternal(instance, elem, onErrorFn) {
elem.removeEventListener("error", onErrorFn), elem.src = "", elem.innerHTML = "", elem.removeAttribute("src"), destroyHlsPlayer(instance), destroyFlvPlayer(instance), destroyShakaPlayer(instance), destroyCastPlayer(instance);
var stopInfo = {
src: instance._currentSrc
};
events.trigger(instance, "stopped", [stopInfo]), instance._currentTime = null, instance._currentSrc = null, instance._currentPlayOptions = null
}
function getBufferedRanges(instance, elem) {
var offset, ranges = [],
seekable = elem.buffered || [],
currentPlayOptions = instance._currentPlayOptions;
currentPlayOptions && (offset = currentPlayOptions.transcodingOffsetTicks), offset = offset || 0;
for (var i = 0, length = seekable.length; i < length; i++) {
var start = seekable.start(i),
end = seekable.end(i);
isValidDuration(start) || (start = 0), isValidDuration(end) ? ranges.push({
start: 1e7 * start + offset,
end: 1e7 * end + offset
}) : end = 0
}
return ranges
}
var recoverDecodingErrorDate, recoverSwapAudioCodecDate;
return {
getSavedVolume: getSavedVolume,
saveVolume: saveVolume,
enableHlsJsPlayer: enableHlsJsPlayer,
enableHlsShakaPlayer: enableHlsShakaPlayer,
handleHlsJsMediaError: handleHlsJsMediaError,
isValidDuration: isValidDuration,
onErrorInternal: onErrorInternal,
seekOnPlaybackStart: seekOnPlaybackStart,
applySrc: applySrc,
playWithPromise: playWithPromise,
destroyHlsPlayer: destroyHlsPlayer,
destroyFlvPlayer: destroyFlvPlayer,
destroyCastPlayer: destroyCastPlayer,
bindEventsToHlsPlayer: bindEventsToHlsPlayer,
onEndedInternal: onEndedInternal,
getCrossOriginValue: getCrossOriginValue,
getBufferedRanges: getBufferedRanges
}
});