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

update components

This commit is contained in:
Luke Pulverenti 2016-03-17 01:06:37 -04:00
parent d004fd3960
commit 2fa1b14785
15 changed files with 179 additions and 86 deletions

View file

@ -16,12 +16,12 @@
}, },
"devDependencies": {}, "devDependencies": {},
"ignore": [], "ignore": [],
"version": "1.1.71", "version": "1.1.72",
"_release": "1.1.71", "_release": "1.1.72",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "1.1.71", "tag": "1.1.72",
"commit": "d908b2813ab510b2059a80a2d0ec0d1bf0eca6d9" "commit": "0d9778f1438ca3e42ad7e07859d1e52696aa9c45"
}, },
"_source": "git://github.com/MediaBrowser/emby-webcomponents.git", "_source": "git://github.com/MediaBrowser/emby-webcomponents.git",
"_target": "~1.1.5", "_target": "~1.1.5",

View file

@ -20,7 +20,7 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
var connectionManager; var connectionManager;
function redirectToLogin() { function beginConnectionWizard() {
backdrop.clear(); backdrop.clear();
@ -265,35 +265,56 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
console.log('Emby.Page - processing path request ' + pathname); console.log('Emby.Page - processing path request ' + pathname);
if ((!apiClient || !apiClient.isLoggedIn()) && !route.anonymous) {
alert(JSON.stringify(route));
console.log('Emby.Page - route does not allow anonymous access, redirecting to login');
beginConnectionWizard();
return;
}
if (apiClient && apiClient.isLoggedIn()) { if (apiClient && apiClient.isLoggedIn()) {
console.log('Emby.Page - user is authenticated'); console.log('Emby.Page - user is authenticated');
if (ctx.isBack && (route.isDefaultRoute /*|| isStartup(ctx)*/)) { if (ctx.isBack && (route.isDefaultRoute /*|| isStartup(ctx)*/)) {
handleBackToDefault(); handleBackToDefault();
return;
} }
else if (route.isDefaultRoute) { else if (route.isDefaultRoute) {
console.log('Emby.Page - loading skin home page'); console.log('Emby.Page - loading skin home page');
skinManager.loadUserSkin(); skinManager.loadUserSkin();
} else { return;
console.log('Emby.Page - next()'); } else if (route.roles) {
callback(); validateRoles(apiClient, route.roles, callback).then(callback, beginConnectionWizard);
return;
} }
return;
} }
console.log('Emby.Page - user is not authenticated'); console.log('Emby.Page - proceeding to ' + pathname);
callback();
}
if (!route.anonymous) { function validateRoles(apiClient, roles) {
console.log('Emby.Page - route does not allow anonymous access, redirecting to login'); return Promise.all(roles.split(',').map(function (role) {
redirectToLogin(); return validateRole(apiClient, role);
}));
}
function validateRole(apiClient, role) {
if (role == 'admin') {
return apiClient.getCurrentUser().then(function (user) {
if (user.Policy.IsAdministrator) {
return Promise.resolve();
}
return Promise.reject();
});
} }
else {
console.log('Emby.Page - proceeding to ' + pathname); // Unknown role
callback(); return Promise.resolve();
}
} }
var isHandlingBackToDefault; var isHandlingBackToDefault;
@ -526,7 +547,7 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
embyRouter.baseUrl = baseUrl; embyRouter.baseUrl = baseUrl;
embyRouter.canGoBack = canGoBack; embyRouter.canGoBack = canGoBack;
embyRouter.current = current; embyRouter.current = current;
embyRouter.redirectToLogin = redirectToLogin; embyRouter.beginConnectionWizard = beginConnectionWizard;
embyRouter.goHome = goHome; embyRouter.goHome = goHome;
embyRouter.showItem = showItem; embyRouter.showItem = showItem;
embyRouter.setTitle = setTitle; embyRouter.setTitle = setTitle;

View file

@ -1,6 +1,6 @@
{ {
"name": "hls.js", "name": "hls.js",
"version": "0.5.13", "version": "0.5.14",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion", "description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js", "homepage": "https://github.com/dailymotion/hls.js",
@ -16,11 +16,11 @@
"test", "test",
"tests" "tests"
], ],
"_release": "0.5.13", "_release": "0.5.14",
"_resolution": { "_resolution": {
"type": "version", "type": "version",
"tag": "v0.5.13", "tag": "v0.5.14",
"commit": "ef9fae497dd6d6e80a6d471c55eef2310e883853" "commit": "ce96495c701482308d2cb57d50259bcd8e2bc506"
}, },
"_source": "git://github.com/dailymotion/hls.js.git", "_source": "git://github.com/dailymotion/hls.js.git",
"_target": "~0.5.7", "_target": "~0.5.7",

View file

@ -554,6 +554,8 @@ however if ```config.autoStartLoad``` is set to ```false```, the following metho
#### ```hls.startLoad()``` #### ```hls.startLoad()```
start/restart playlist/fragment loading. this is only effective if MANIFEST_PARSED event has been triggered and video element has been attached to hls object. start/restart playlist/fragment loading. this is only effective if MANIFEST_PARSED event has been triggered and video element has been attached to hls object.
#### ```hls.stopLoad()```
stop playlist/fragment loading. could be resumed later on by calling ```hls.startLoad()```
## Runtime Events ## Runtime Events

View file

@ -1,6 +1,6 @@
{ {
"name": "hls.js", "name": "hls.js",
"version": "0.5.13", "version": "0.5.14",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion", "description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js", "homepage": "https://github.com/dailymotion/hls.js",

View file

@ -111,8 +111,9 @@ header {
<button type="button" class="btn btn-sm btn-info" onclick="$('#video')[0].currentTime=$('#seek_pos').val()">seek to </button> <button type="button" class="btn btn-sm btn-info" onclick="$('#video')[0].currentTime=$('#seek_pos').val()">seek to </button>
<input type="text" id='seek_pos' size="8" onkeydown="if(window.event.keyCode=='13'){$('#video')[0].currentTime=$('#seek_pos').val();}"><br><br> <input type="text" id='seek_pos' size="8" onkeydown="if(window.event.keyCode=='13'){$('#video')[0].currentTime=$('#seek_pos').val();}"><br><br>
<button type="button" class="btn btn-xs btn-warning" onclick="hls.attachMedia($('#video')[0])">attach Video</button> <button type="button" class="btn btn-xs btn-warning" onclick="hls.attachMedia($('#video')[0])">attach Video</button>
<button type="button" class="btn btn-xs btn-warning" onclick="hls.detachVideo()">detach Video</button><br> <button type="button" class="btn btn-xs btn-warning" onclick="hls.detachMedia()">detach Video</button><br>
<button type="button" class="btn btn-xs btn-warning" onclick="hls.startLoad()">recover Network Error</button> <button type="button" class="btn btn-xs btn-warning" onclick="hls.startLoad()">start Load</button>
<button type="button" class="btn btn-xs btn-warning" onclick="hls.stopLoad()">stop Load</button>
<button type="button" class="btn btn-xs btn-warning" onclick="hls.recoverMediaError()">recover Media Error</button><br> <button type="button" class="btn btn-xs btn-warning" onclick="hls.recoverMediaError()">recover Media Error</button><br>
</div> </div>

View file

@ -582,6 +582,7 @@ var BufferController = function (_EventHandler) {
this.mediaSource = null; this.mediaSource = null;
this.media = null; this.media = null;
this.pendingTracks = null; this.pendingTracks = null;
this.sourceBuffer = null;
} }
this.onmso = this.onmse = this.onmsc = null; this.onmso = this.onmse = this.onmsc = null;
this.hls.trigger(_events2.default.MEDIA_DETACHED); this.hls.trigger(_events2.default.MEDIA_DETACHED);
@ -934,6 +935,20 @@ var LevelController = function (_EventHandler) {
} }
this._manualLevel = -1; this._manualLevel = -1;
} }
}, {
key: 'startLoad',
value: function startLoad() {
this.canload = true;
// speed up live playlist refresh if timer exists
if (this.timer) {
this.tick();
}
}
}, {
key: 'stopLoad',
value: function stopLoad() {
this.canload = false;
}
}, { }, {
key: 'onManifestLoaded', key: 'onManifestLoaded',
value: function onManifestLoaded(data) { value: function onManifestLoaded(data) {
@ -1119,7 +1134,7 @@ var LevelController = function (_EventHandler) {
key: 'tick', key: 'tick',
value: function tick() { value: function tick() {
var levelId = this._level; var levelId = this._level;
if (levelId !== undefined) { if (levelId !== undefined && this.canload) {
var level = this._levels[levelId], var level = this._levels[levelId],
urlId = level.urlId; urlId = level.urlId;
this.hls.trigger(_events2.default.LEVEL_LOADING, { url: level.url[urlId], level: levelId, id: urlId }); this.hls.trigger(_events2.default.LEVEL_LOADING, { url: level.url[urlId], level: levelId, id: urlId });
@ -1237,7 +1252,7 @@ function _inherits(subClass, superClass) { if (typeof superClass !== "function"
*/ */
var State = { var State = {
ERROR: 'ERROR', STOPPED: 'STOPPED',
STARTING: 'STARTING', STARTING: 'STARTING',
IDLE: 'IDLE', IDLE: 'IDLE',
PAUSED: 'PAUSED', PAUSED: 'PAUSED',
@ -1247,7 +1262,8 @@ var State = {
WAITING_LEVEL: 'WAITING_LEVEL', WAITING_LEVEL: 'WAITING_LEVEL',
PARSING: 'PARSING', PARSING: 'PARSING',
PARSED: 'PARSED', PARSED: 'PARSED',
ENDED: 'ENDED' ENDED: 'ENDED',
ERROR: 'ERROR'
}; };
var StreamController = function (_EventHandler) { var StreamController = function (_EventHandler) {
@ -1256,7 +1272,7 @@ var StreamController = function (_EventHandler) {
function StreamController(hls) { function StreamController(hls) {
_classCallCheck(this, StreamController); _classCallCheck(this, StreamController);
var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(StreamController).call(this, hls, _events2.default.MEDIA_ATTACHED, _events2.default.MEDIA_DETACHING, _events2.default.MANIFEST_PARSED, _events2.default.LEVEL_LOADED, _events2.default.KEY_LOADED, _events2.default.FRAG_LOADED, _events2.default.FRAG_PARSING_INIT_SEGMENT, _events2.default.FRAG_PARSING_DATA, _events2.default.FRAG_PARSED, _events2.default.ERROR, _events2.default.BUFFER_APPENDED, _events2.default.BUFFER_FLUSHED)); var _this = _possibleConstructorReturn(this, Object.getPrototypeOf(StreamController).call(this, hls, _events2.default.MEDIA_ATTACHED, _events2.default.MEDIA_DETACHING, _events2.default.MANIFEST_LOADING, _events2.default.MANIFEST_PARSED, _events2.default.LEVEL_LOADED, _events2.default.KEY_LOADED, _events2.default.FRAG_LOADED, _events2.default.FRAG_PARSING_INIT_SEGMENT, _events2.default.FRAG_PARSING_DATA, _events2.default.FRAG_PARSED, _events2.default.ERROR, _events2.default.BUFFER_APPENDED, _events2.default.BUFFER_FLUSHED));
_this.config = hls.config; _this.config = hls.config;
_this.audioCodecSwap = false; _this.audioCodecSwap = false;
@ -1268,19 +1284,27 @@ var StreamController = function (_EventHandler) {
_createClass(StreamController, [{ _createClass(StreamController, [{
key: 'destroy', key: 'destroy',
value: function destroy() { value: function destroy() {
this.stop(); this.stopLoad();
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
_eventHandler2.default.prototype.destroy.call(this); _eventHandler2.default.prototype.destroy.call(this);
this.state = State.IDLE; this.state = State.STOPPED;
} }
}, { }, {
key: 'startLoad', key: 'startLoad',
value: function startLoad() { value: function startLoad() {
var startPosition = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
if (this.levels) { if (this.levels) {
var media = this.media, var media = this.media,
lastCurrentTime = this.lastCurrentTime; lastCurrentTime = this.lastCurrentTime;
this.stop(); this.stopLoad();
this.demuxer = new _demuxer2.default(this.hls); this.demuxer = new _demuxer2.default(this.hls);
this.timer = setInterval(this.ontick, 100); if (!this.timer) {
this.timer = setInterval(this.ontick, 100);
}
this.level = -1; this.level = -1;
this.fragLoadError = 0; this.fragLoadError = 0;
if (media && lastCurrentTime) { if (media && lastCurrentTime) {
@ -1291,20 +1315,19 @@ var StreamController = function (_EventHandler) {
} }
this.state = State.IDLE; this.state = State.IDLE;
} else { } else {
this.lastCurrentTime = this.startPosition ? this.startPosition : 0; this.lastCurrentTime = this.startPosition ? this.startPosition : startPosition;
this.state = State.STARTING; this.state = State.STARTING;
} }
this.nextLoadPosition = this.startPosition = this.lastCurrentTime; this.nextLoadPosition = this.startPosition = this.lastCurrentTime;
this.tick(); this.tick();
} else { } else {
_logger.logger.warn('cannot start loading as manifest not parsed yet'); _logger.logger.warn('cannot start loading as manifest not parsed yet');
this.state = State.STOPPED;
} }
} }
}, { }, {
key: 'stop', key: 'stopLoad',
value: function stop() { value: function stopLoad() {
this.bufferRange = [];
this.stalled = false;
var frag = this.fragCurrent; var frag = this.fragCurrent;
if (frag) { if (frag) {
if (frag.loader) { if (frag.loader) {
@ -1313,16 +1336,11 @@ var StreamController = function (_EventHandler) {
this.fragCurrent = null; this.fragCurrent = null;
} }
this.fragPrevious = null; this.fragPrevious = null;
_logger.logger.log('trigger BUFFER_RESET');
this.hls.trigger(_events2.default.BUFFER_RESET);
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
if (this.demuxer) { if (this.demuxer) {
this.demuxer.destroy(); this.demuxer.destroy();
this.demuxer = null; this.demuxer = null;
} }
this.state = State.STOPPED;
} }
}, { }, {
key: 'tick', key: 'tick',
@ -1935,7 +1953,7 @@ var StreamController = function (_EventHandler) {
} }
this.media = null; this.media = null;
this.loadedmetadata = false; this.loadedmetadata = false;
this.stop(); this.stopLoad();
} }
}, { }, {
key: 'onMediaSeeking', key: 'onMediaSeeking',
@ -1983,6 +2001,15 @@ var StreamController = function (_EventHandler) {
// reset startPosition and lastCurrentTime to restart playback @ stream beginning // reset startPosition and lastCurrentTime to restart playback @ stream beginning
this.startPosition = this.lastCurrentTime = 0; this.startPosition = this.lastCurrentTime = 0;
} }
}, {
key: 'onManifestLoading',
value: function onManifestLoading() {
// reset buffer on manifest loading
_logger.logger.log('trigger BUFFER_RESET');
this.hls.trigger(_events2.default.BUFFER_RESET);
this.bufferRange = [];
this.stalled = false;
}
}, { }, {
key: 'onManifestParsed', key: 'onManifestParsed',
value: function onManifestParsed(data) { value: function onManifestParsed(data) {
@ -2361,6 +2388,7 @@ var StreamController = function (_EventHandler) {
if (this.stalled && playheadMoving) { if (this.stalled && playheadMoving) {
this.stalled = false; this.stalled = false;
_logger.logger.log('playback not stuck anymore @' + currentTime);
} }
// check buffer upfront // check buffer upfront
// if less than 200ms is buffered, and media is expected to play but playhead is not moving, // if less than 200ms is buffered, and media is expected to play but playhead is not moving,
@ -2371,8 +2399,8 @@ var StreamController = function (_EventHandler) {
jumpThreshold = 0; jumpThreshold = 0;
} else { } else {
// playhead not moving AND media expected to play // playhead not moving AND media expected to play
_logger.logger.log('playback seems stuck @' + currentTime);
if (!this.stalled) { if (!this.stalled) {
_logger.logger.log('playback seems stuck @' + currentTime);
this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_STALLED_ERROR, fatal: false }); this.hls.trigger(_events2.default.ERROR, { type: _errors.ErrorTypes.MEDIA_ERROR, details: _errors.ErrorDetails.BUFFER_STALLED_ERROR, fatal: false });
this.stalled = true; this.stalled = true;
} }
@ -3304,9 +3332,9 @@ var ADTS = function () {
// multiply frequency by 2 (see table below, equivalent to substract 3) // multiply frequency by 2 (see table below, equivalent to substract 3)
adtsExtensionSampleingIndex = adtsSampleingIndex - 3; adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
} else { } else {
// if (manifest codec is AAC) AND (frequency less than 24kHz OR nb channel is 1) OR (manifest codec not specified and mono audio) // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
// Chrome fails to play back with AAC LC mono when initialized with HE-AAC. This is not a problem with stereo. // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo.
if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSampleingIndex >= 6 || adtsChanelConfig === 1) || !audioCodec && adtsChanelConfig === 1) { if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && adtsSampleingIndex >= 6 && adtsChanelConfig === 1 || !audioCodec && adtsChanelConfig === 1) {
adtsObjectType = 2; adtsObjectType = 2;
config = new Array(2); config = new Array(2);
} }
@ -5544,8 +5572,18 @@ var Hls = function () {
}, { }, {
key: 'startLoad', key: 'startLoad',
value: function startLoad() { value: function startLoad() {
var startPosition = arguments.length <= 0 || arguments[0] === undefined ? 0 : arguments[0];
_logger.logger.log('startLoad'); _logger.logger.log('startLoad');
this.streamController.startLoad(); this.levelController.startLoad();
this.streamController.startLoad(startPosition);
}
}, {
key: 'stopLoad',
value: function stopLoad() {
_logger.logger.log('stopLoad');
this.levelController.stopLoad();
this.streamController.stopLoad();
} }
}, { }, {
key: 'swapAudioCodec', key: 'swapAudioCodec',

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -1,6 +1,6 @@
{ {
"name": "hls.js", "name": "hls.js",
"version": "0.5.13", "version": "0.5.14",
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "Media Source Extension - HLS library, by/for Dailymotion", "description": "Media Source Extension - HLS library, by/for Dailymotion",
"homepage": "https://github.com/dailymotion/hls.js", "homepage": "https://github.com/dailymotion/hls.js",

View file

@ -67,6 +67,7 @@ class BufferController extends EventHandler {
this.mediaSource = null; this.mediaSource = null;
this.media = null; this.media = null;
this.pendingTracks = null; this.pendingTracks = null;
this.sourceBuffer = null;
} }
this.onmso = this.onmse = this.onmsc = null; this.onmso = this.onmse = this.onmsc = null;
this.hls.trigger(Event.MEDIA_DETACHED); this.hls.trigger(Event.MEDIA_DETACHED);

View file

@ -25,6 +25,18 @@ class LevelController extends EventHandler {
this._manualLevel = -1; this._manualLevel = -1;
} }
startLoad() {
this.canload = true;
// speed up live playlist refresh if timer exists
if (this.timer) {
this.tick();
}
}
stopLoad() {
this.canload = false;
}
onManifestLoaded(data) { onManifestLoaded(data) {
var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false, hls = this.hls; var levels0 = [], levels = [], bitrateStart, i, bitrateSet = {}, videoCodecFound = false, audioCodecFound = false, hls = this.hls;
@ -235,7 +247,7 @@ class LevelController extends EventHandler {
tick() { tick() {
var levelId = this._level; var levelId = this._level;
if (levelId !== undefined) { if (levelId !== undefined && this.canload) {
var level = this._levels[levelId], urlId = level.urlId; var level = this._levels[levelId], urlId = level.urlId;
this.hls.trigger(Event.LEVEL_LOADING, {url: level.url[urlId], level: levelId, id: urlId}); this.hls.trigger(Event.LEVEL_LOADING, {url: level.url[urlId], level: levelId, id: urlId});
} }

View file

@ -11,7 +11,7 @@ import LevelHelper from '../helper/level-helper';
import {ErrorTypes, ErrorDetails} from '../errors'; import {ErrorTypes, ErrorDetails} from '../errors';
const State = { const State = {
ERROR : 'ERROR', STOPPED : 'STOPPED',
STARTING : 'STARTING', STARTING : 'STARTING',
IDLE : 'IDLE', IDLE : 'IDLE',
PAUSED : 'PAUSED', PAUSED : 'PAUSED',
@ -21,7 +21,8 @@ const State = {
WAITING_LEVEL : 'WAITING_LEVEL', WAITING_LEVEL : 'WAITING_LEVEL',
PARSING : 'PARSING', PARSING : 'PARSING',
PARSED : 'PARSED', PARSED : 'PARSED',
ENDED : 'ENDED' ENDED : 'ENDED',
ERROR : 'ERROR'
}; };
class StreamController extends EventHandler { class StreamController extends EventHandler {
@ -30,6 +31,7 @@ class StreamController extends EventHandler {
super(hls, super(hls,
Event.MEDIA_ATTACHED, Event.MEDIA_ATTACHED,
Event.MEDIA_DETACHING, Event.MEDIA_DETACHING,
Event.MANIFEST_LOADING,
Event.MANIFEST_PARSED, Event.MANIFEST_PARSED,
Event.LEVEL_LOADED, Event.LEVEL_LOADED,
Event.KEY_LOADED, Event.KEY_LOADED,
@ -48,17 +50,23 @@ class StreamController extends EventHandler {
} }
destroy() { destroy() {
this.stop(); this.stopLoad();
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
EventHandler.prototype.destroy.call(this); EventHandler.prototype.destroy.call(this);
this.state = State.IDLE; this.state = State.STOPPED;
} }
startLoad() { startLoad(startPosition=0) {
if (this.levels) { if (this.levels) {
var media = this.media, lastCurrentTime = this.lastCurrentTime; var media = this.media, lastCurrentTime = this.lastCurrentTime;
this.stop(); this.stopLoad();
this.demuxer = new Demuxer(this.hls); this.demuxer = new Demuxer(this.hls);
this.timer = setInterval(this.ontick, 100); if (!this.timer) {
this.timer = setInterval(this.ontick, 100);
}
this.level = -1; this.level = -1;
this.fragLoadError = 0; this.fragLoadError = 0;
if (media && lastCurrentTime) { if (media && lastCurrentTime) {
@ -69,19 +77,18 @@ class StreamController extends EventHandler {
} }
this.state = State.IDLE; this.state = State.IDLE;
} else { } else {
this.lastCurrentTime = this.startPosition ? this.startPosition : 0; this.lastCurrentTime = this.startPosition ? this.startPosition : startPosition;
this.state = State.STARTING; this.state = State.STARTING;
} }
this.nextLoadPosition = this.startPosition = this.lastCurrentTime; this.nextLoadPosition = this.startPosition = this.lastCurrentTime;
this.tick(); this.tick();
} else { } else {
logger.warn('cannot start loading as manifest not parsed yet'); logger.warn('cannot start loading as manifest not parsed yet');
this.state = State.STOPPED;
} }
} }
stop() { stopLoad() {
this.bufferRange = [];
this.stalled = false;
var frag = this.fragCurrent; var frag = this.fragCurrent;
if (frag) { if (frag) {
if (frag.loader) { if (frag.loader) {
@ -90,16 +97,11 @@ class StreamController extends EventHandler {
this.fragCurrent = null; this.fragCurrent = null;
} }
this.fragPrevious = null; this.fragPrevious = null;
logger.log('trigger BUFFER_RESET');
this.hls.trigger(Event.BUFFER_RESET);
if (this.timer) {
clearInterval(this.timer);
this.timer = null;
}
if (this.demuxer) { if (this.demuxer) {
this.demuxer.destroy(); this.demuxer.destroy();
this.demuxer = null; this.demuxer = null;
} }
this.state = State.STOPPED;
} }
tick() { tick() {
@ -703,7 +705,7 @@ class StreamController extends EventHandler {
} }
this.media = null; this.media = null;
this.loadedmetadata = false; this.loadedmetadata = false;
this.stop(); this.stopLoad();
} }
onMediaSeeking() { onMediaSeeking() {
@ -750,6 +752,14 @@ class StreamController extends EventHandler {
} }
onManifestLoading() {
// reset buffer on manifest loading
logger.log('trigger BUFFER_RESET');
this.hls.trigger(Event.BUFFER_RESET);
this.bufferRange = [];
this.stalled = false;
}
onManifestParsed(data) { onManifestParsed(data) {
var aac = false, heaac = false, codec; var aac = false, heaac = false, codec;
data.levels.forEach(level => { data.levels.forEach(level => {
@ -1111,6 +1121,7 @@ _checkBuffer() {
if (this.stalled && playheadMoving) { if (this.stalled && playheadMoving) {
this.stalled = false; this.stalled = false;
logger.log(`playback not stuck anymore @${currentTime}`);
} }
// check buffer upfront // check buffer upfront
// if less than 200ms is buffered, and media is expected to play but playhead is not moving, // if less than 200ms is buffered, and media is expected to play but playhead is not moving,
@ -1121,8 +1132,8 @@ _checkBuffer() {
jumpThreshold = 0; jumpThreshold = 0;
} else { } else {
// playhead not moving AND media expected to play // playhead not moving AND media expected to play
logger.log(`playback seems stuck @${currentTime}`);
if(!this.stalled) { if(!this.stalled) {
logger.log(`playback seems stuck @${currentTime}`);
this.hls.trigger(Event.ERROR, {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_STALLED_ERROR, fatal: false}); this.hls.trigger(Event.ERROR, {type: ErrorTypes.MEDIA_ERROR, details: ErrorDetails.BUFFER_STALLED_ERROR, fatal: false});
this.stalled = true; this.stalled = true;
} }

View file

@ -66,9 +66,9 @@ import {ErrorTypes, ErrorDetails} from '../errors';
// multiply frequency by 2 (see table below, equivalent to substract 3) // multiply frequency by 2 (see table below, equivalent to substract 3)
adtsExtensionSampleingIndex = adtsSampleingIndex - 3; adtsExtensionSampleingIndex = adtsSampleingIndex - 3;
} else { } else {
// if (manifest codec is AAC) AND (frequency less than 24kHz OR nb channel is 1) OR (manifest codec not specified and mono audio) // if (manifest codec is AAC) AND (frequency less than 24kHz AND nb channel is 1) OR (manifest codec not specified and mono audio)
// Chrome fails to play back with AAC LC mono when initialized with HE-AAC. This is not a problem with stereo. // Chrome fails to play back with low frequency AAC LC mono when initialized with HE-AAC. This is not a problem with stereo.
if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSampleingIndex >= 6 || adtsChanelConfig === 1) || if (audioCodec && audioCodec.indexOf('mp4a.40.2') !== -1 && (adtsSampleingIndex >= 6 && adtsChanelConfig === 1) ||
(!audioCodec && adtsChanelConfig === 1)) { (!audioCodec && adtsChanelConfig === 1)) {
adtsObjectType = 2; adtsObjectType = 2;
config = new Array(2); config = new Array(2);

View file

@ -165,9 +165,16 @@ class Hls {
this.trigger(Event.MANIFEST_LOADING, {url: url}); this.trigger(Event.MANIFEST_LOADING, {url: url});
} }
startLoad() { startLoad(startPosition=0) {
logger.log('startLoad'); logger.log('startLoad');
this.streamController.startLoad(); this.levelController.startLoad();
this.streamController.startLoad(startPosition);
}
stopLoad() {
logger.log('stopLoad');
this.levelController.stopLoad();
this.streamController.stopLoad();
} }
swapAudioCodec() { swapAudioCodec() {