1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

update web components

This commit is contained in:
Luke Pulverenti 2015-12-23 12:46:01 -05:00
parent 909402537a
commit fcdd2e4f4b
114 changed files with 1611 additions and 1238 deletions

View file

@ -32,7 +32,7 @@ class LevelController {
}
onManifestLoaded(event, data) {
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false;
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false, hls = this.hls;
// regroup redundant level together
data.levels.forEach(level => {
@ -65,31 +65,34 @@ class LevelController {
}
// only keep level with supported audio/video codecs
levels0 = levels0.filter(function(level) {
levels = levels.filter(function(level) {
var checkSupported = function(codec) { return MediaSource.isTypeSupported(`video/mp4;codecs=${codec}`);};
var audioCodec = level.audioCodec, videoCodec = level.videoCodec;
return ((audioCodec && checkSupported(audioCodec)) || !audioCodec) &&
((videoCodec && checkSupported(videoCodec)) || !videoCodec);
return (!audioCodec || checkSupported(audioCodec)) &&
(!videoCodec || checkSupported(videoCodec));
});
// start bitrate is the first bitrate of the manifest
bitrateStart = levels[0].bitrate;
// sort level on bitrate
levels.sort(function (a, b) {
return a.bitrate - b.bitrate;
});
this._levels = levels;
// find index of first level in sorted levels
for (i = 0; i < levels.length; i++) {
if (levels[i].bitrate === bitrateStart) {
this._firstLevel = i;
logger.log(`manifest loaded,${levels.length} level(s) found, first bitrate:${bitrateStart}`);
break;
if(levels.length) {
// start bitrate is the first bitrate of the manifest
bitrateStart = levels[0].bitrate;
// sort level on bitrate
levels.sort(function (a, b) {
return a.bitrate - b.bitrate;
});
this._levels = levels;
// find index of first level in sorted levels
for (i = 0; i < levels.length; i++) {
if (levels[i].bitrate === bitrateStart) {
this._firstLevel = i;
logger.log(`manifest loaded,${levels.length} level(s) found, first bitrate:${bitrateStart}`);
break;
}
}
hls.trigger(Event.MANIFEST_PARSED, {levels: this._levels, firstLevel: this._firstLevel, stats: data.stats});
} else {
hls.trigger(Event.ERROR, {type: ErrorTypes.NETWORK_ERROR, details: ErrorDetails.MANIFEST_PARSING_ERROR, fatal: true, url: hls.url, reason: 'no compatible level found in manifest'});
}
this.hls.trigger(Event.MANIFEST_PARSED, {levels: this._levels, firstLevel: this._firstLevel, stats: data.stats});
return;
}
@ -187,7 +190,8 @@ class LevelController {
}
/* try to switch to a redundant stream if any available.
* if no redundant stream available, emergency switch down (if in auto mode and current level not 0)
* otherwise, we cannot recover this network error ....
* otherwise, we cannot recover this network error ...
* don't raise FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT as fatal, as it is handled by mediaController
*/
if (levelId !== undefined) {
level = this._levels[levelId];
@ -203,7 +207,8 @@ class LevelController {
hls.abrController.nextAutoLevel = 0;
} else if(level && level.details && level.details.live) {
logger.warn(`level controller,${details} on live stream, discard`);
} else {
// FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT are handled by mediaController
} else if (details !== ErrorDetails.FRAG_LOAD_ERROR && details !== ErrorDetails.FRAG_LOAD_TIMEOUT) {
logger.error(`cannot recover ${details} error`);
this._level = undefined;
// stopping live reloading timer if any

View file

@ -391,26 +391,30 @@ class MSEMediaController {
this.appendError = 0;
} catch(err) {
// in case any error occured while appending, put back segment in mp4segments table
//logger.error(`error while trying to append buffer:${err.message},try appending later`);
logger.error(`error while trying to append buffer:${err.message},try appending later`);
this.mp4segments.unshift(segment);
if (this.appendError) {
this.appendError++;
} else {
this.appendError = 1;
}
var event = {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_APPEND_ERROR, frag: this.fragCurrent};
/* with UHD content, we could get loop of quota exceeded error until
browser is able to evict some data from sourcebuffer. retrying help recovering this
*/
if (this.appendError > this.config.appendErrorMaxRetry) {
logger.log(`fail ${this.config.appendErrorMaxRetry} times to append segment in sourceBuffer`);
event.fatal = true;
hls.trigger(Event.ERROR, event);
this.state = State.ERROR;
return;
} else {
event.fatal = false;
hls.trigger(Event.ERROR, event);
// just discard QuotaExceededError for now, and wait for the natural browser buffer eviction
//http://www.w3.org/TR/html5/infrastructure.html#quotaexceedederror
if(err.code !== 22) {
if (this.appendError) {
this.appendError++;
} else {
this.appendError = 1;
}
var event = {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_APPEND_ERROR, frag: this.fragCurrent};
/* with UHD content, we could get loop of quota exceeded error until
browser is able to evict some data from sourcebuffer. retrying help recovering this
*/
if (this.appendError > this.config.appendErrorMaxRetry) {
logger.log(`fail ${this.config.appendErrorMaxRetry} times to append segment in sourceBuffer`);
event.fatal = true;
hls.trigger(Event.ERROR, event);
this.state = State.ERROR;
return;
} else {
event.fatal = false;
hls.trigger(Event.ERROR, event);
}
}
}
this.state = State.APPENDING;
@ -1000,6 +1004,7 @@ class MSEMediaController {
this.demuxer.push(data.payload, audioCodec, currentLevel.videoCodec, start, fragCurrent.cc, level, sn, duration, fragCurrent.decryptdata);
}
}
this.fragLoadError = 0;
}
onInitSegment(event, data) {
@ -1095,6 +1100,24 @@ class MSEMediaController {
// abort fragment loading on errors
case ErrorDetails.FRAG_LOAD_ERROR:
case ErrorDetails.FRAG_LOAD_TIMEOUT:
var loadError = this.fragLoadError;
if(loadError) {
loadError++;
} else {
loadError=1;
}
if (loadError <= this.config.fragLoadingMaxRetry) {
this.fragLoadError = loadError;
// retry loading
this.state = State.IDLE;
} else {
logger.error(`mediaController: ${data.details} reaches max retry, redispatch as fatal ...`);
// redispatch same error but with fatal set to true
data.fatal = true;
this.hls.trigger(event, data);
this.state = State.ERROR;
}
break;
case ErrorDetails.FRAG_LOOP_LOADING_ERROR:
case ErrorDetails.LEVEL_LOAD_ERROR:
case ErrorDetails.LEVEL_LOAD_TIMEOUT: