update missing season creator

This commit is contained in:
Luke Pulverenti 2016-05-20 15:45:04 -04:00
parent a981c0eb8b
commit 5fa9e9637b
22 changed files with 190 additions and 83 deletions

View file

@ -1329,8 +1329,9 @@ var LevelController = function (_EventHandler) {
var details = data.details,
hls = this.hls,
levelId,
level;
levelId = void 0,
level = void 0,
levelError = false;
// try to recover not fatal errors
switch (details) {
case _errors.ErrorDetails.FRAG_LOAD_ERROR:
@ -1343,6 +1344,7 @@ var LevelController = function (_EventHandler) {
case _errors.ErrorDetails.LEVEL_LOAD_ERROR:
case _errors.ErrorDetails.LEVEL_LOAD_TIMEOUT:
levelId = data.level;
levelError = true;
break;
default:
break;
@ -1366,6 +1368,10 @@ var LevelController = function (_EventHandler) {
hls.abrController.nextAutoLevel = 0;
} else if (level && level.details && level.details.live) {
_logger.logger.warn('level controller,' + details + ' on live stream, discard');
if (levelError) {
// reset this._level so that another call to set level() will retrigger a frag load
this._level = undefined;
}
// FRAG_LOAD_ERROR and FRAG_LOAD_TIMEOUT are handled by mediaController
} else if (details !== _errors.ErrorDetails.FRAG_LOAD_ERROR && details !== _errors.ErrorDetails.FRAG_LOAD_TIMEOUT) {
_logger.logger.error('cannot recover ' + details + ' error');
@ -1664,14 +1670,15 @@ var StreamController = function (_EventHandler) {
break;
case State.STARTING:
// determine load level
this.startLevel = hls.startLevel;
if (this.startLevel === -1) {
var startLevel = hls.startLevel;
if (startLevel === -1) {
// -1 : guess start Level by doing a bitrate test by loading first fragment of lowest quality level
this.startLevel = 0;
startLevel = 0;
this.fragBitrateTest = true;
}
// set new level to playlist loader : this will trigger start level load
this.level = hls.nextLoadLevel = this.startLevel;
// hls.nextLoadLevel remains until it is set to a new value or until a new frag is successfully loaded
this.level = hls.nextLoadLevel = startLevel;
this.state = State.WAITING_LEVEL;
this.loadedmetadata = false;
break;
@ -1692,13 +1699,7 @@ var StreamController = function (_EventHandler) {
} else {
pos = this.nextLoadPosition;
}
// determine next load level
if (this.startFragRequested === false) {
level = this.startLevel;
} else {
// we are not at playback start, get next load level from level Controller
level = hls.nextLoadLevel;
}
level = hls.nextLoadLevel;
var bufferInfo = _bufferHelper2.default.bufferInfo(this.media, pos, config.maxBufferHole),
bufferLen = bufferInfo.len,
bufferEnd = bufferInfo.end,
@ -1827,8 +1828,14 @@ var StreamController = function (_EventHandler) {
} else {
// have we reached end of VOD playlist ?
if (!levelDetails.live) {
// Finalize the media stream
_this2.hls.trigger(_events2.default.BUFFER_EOS);
_this2.state = State.ENDED;
// We might be loading the last fragment but actually the media
// is currently processing a seek command and waiting for new data to resume at another point.
// Going to ended state while media is seeking can spawn an infinite buffering broken state.
if (!_this2.media.seeking) {
_this2.state = State.ENDED;
}
}
frag = null;
}
@ -2278,10 +2285,13 @@ var StreamController = function (_EventHandler) {
value: function onFragLoaded(data) {
var fragCurrent = this.fragCurrent;
if (this.state === State.FRAG_LOADING && fragCurrent && data.frag.level === fragCurrent.level && data.frag.sn === fragCurrent.sn) {
_logger.logger.log('Loaded ' + fragCurrent.sn + ' of level ' + fragCurrent.level);
if (this.fragBitrateTest === true) {
// switch back to IDLE state ... we just loaded a fragment to determine adequate start bitrate and initialize autoswitch algo
this.state = State.IDLE;
this.fragBitrateTest = false;
this.startFragRequested = false;
data.stats.tparsed = data.stats.tbuffered = performance.now();
this.hls.trigger(_events2.default.FRAG_BUFFERED, { stats: data.stats, frag: fragCurrent });
} else {
@ -2606,8 +2616,16 @@ var StreamController = function (_EventHandler) {
}
}
} else {
if (targetSeekPosition && media.currentTime !== targetSeekPosition) {
_logger.logger.log('adjust currentTime from ' + media.currentTime + ' to ' + targetSeekPosition);
var _currentTime = media.currentTime;
if (targetSeekPosition && _currentTime !== targetSeekPosition) {
if (bufferInfo.len === 0) {
var nextStart = bufferInfo.nextStart;
if (nextStart !== undefined && nextStart - targetSeekPosition < this.config.maxSeekHole) {
targetSeekPosition = nextStart;
_logger.logger.log('target seek position not buffered, seek to next buffered ' + targetSeekPosition);
}
}
_logger.logger.log('adjust currentTime from ' + _currentTime + ' to ' + targetSeekPosition);
media.currentTime = targetSeekPosition;
}
}
@ -4520,7 +4538,8 @@ var TSDemuxer = function () {
pid,
atf,
offset,
codecsOnly = this.remuxer.passthrough;
codecsOnly = this.remuxer.passthrough,
unknownPIDs = false;
this.audioCodec = audioCodec;
this.videoCodec = videoCodec;
@ -4634,6 +4653,15 @@ var TSDemuxer = function () {
avcId = this._avcTrack.id;
aacId = this._aacTrack.id;
id3Id = this._id3Track.id;
if (unknownPIDs) {
_logger.logger.log('reparse from beginning');
unknownPIDs = false;
// we set it to -188, the += 188 in the for loop will reset start to 0
start = -188;
}
} else {
_logger.logger.log('unknown PID found before PAT/PMT');
unknownPIDs = true;
}
}
} else {
@ -4948,8 +4976,10 @@ var TSDemuxer = function () {
//build sample from PES
// Annex B to MP4 conversion to be done
if (units2.length) {
// only push AVC sample if keyframe already found. browsers expect a keyframe at first to start decoding
if (key === true || track.sps) {
// only push AVC sample if keyframe already found in this fragment OR
// keyframe found in last fragment (track.sps) AND
// samples already appended (we already found a keyframe in this fragment) OR fragment is contiguous
if (key === true || track.sps && (samples.length || this.contiguous)) {
avcSample = { units: { units: units2, length: length }, pts: pes.pts, dts: pes.dts, key: key };
samples.push(avcSample);
track.len += length;
@ -8420,7 +8450,6 @@ var logger = exports.logger = exportedLogger;
'use strict';
var URLHelper = {
// build an absolute URL from a relative one using the provided baseURL
// if relativeURL is an absolute URL it will be returned as is.
buildAbsoluteURL: function buildAbsoluteURL(baseURL, relativeURL) {
@ -8454,18 +8483,27 @@ var URLHelper = {
baseURL = baseURLQuerySplit[1];
}
var baseURLDomainSplit = /^((([a-z]+):)?\/\/[a-z0-9\.\-_~]+(:[0-9]+)?\/)(.*)$/i.exec(baseURL);
var baseURLProtocol = baseURLDomainSplit[3];
var baseURLDomain = baseURLDomainSplit[1];
var baseURLPath = baseURLDomainSplit[5];
var baseURLDomainSplit = /^(([a-z]+:)?\/\/[a-z0-9\.\-_~]+(:[0-9]+)?)?(\/.*)$/i.exec(baseURL);
if (!baseURLDomainSplit) {
throw new Error('Error trying to parse base URL.');
}
// e.g. 'http:', 'https:', ''
var baseURLProtocol = baseURLDomainSplit[2] || '';
// e.g. 'http://example.com', '//example.com', ''
var baseURLProtocolDomain = baseURLDomainSplit[1] || '';
// e.g. '/a/b/c/playlist.m3u8'
var baseURLPath = baseURLDomainSplit[4];
var builtURL = null;
if (/^\/\//.test(relativeURL)) {
builtURL = baseURLProtocol + '://' + URLHelper.buildAbsolutePath('', relativeURL.substring(2));
// relative url starts wth '//' so copy protocol (which may be '' if baseUrl didn't provide one)
builtURL = baseURLProtocol + '//' + URLHelper.buildAbsolutePath('', relativeURL.substring(2));
} else if (/^\//.test(relativeURL)) {
builtURL = baseURLDomain + URLHelper.buildAbsolutePath('', relativeURL.substring(1));
// relative url starts with '/' so start from root of domain
builtURL = baseURLProtocolDomain + '/' + URLHelper.buildAbsolutePath('', relativeURL.substring(1));
} else {
builtURL = URLHelper.buildAbsolutePath(baseURLDomain + baseURLPath, relativeURL);
builtURL = URLHelper.buildAbsolutePath(baseURLProtocolDomain + baseURLPath, relativeURL);
}
// put the query and hash parts back

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long