av-merge: Retry failed requests
Should reduce playback stalling
This commit is contained in:
parent
284024433b
commit
629c811e84
@ -204,6 +204,7 @@ Stream.prototype.setup = async function(){
|
||||
this.url,
|
||||
this.initRange.start,
|
||||
this.indexRange.end,
|
||||
'Initialization+index segments',
|
||||
).then(
|
||||
(buffer) => {
|
||||
let init_end = this.initRange.end - this.initRange.start + 1;
|
||||
@ -219,6 +220,7 @@ Stream.prototype.setup = async function(){
|
||||
this.url,
|
||||
this.initRange.start,
|
||||
this.initRange.end,
|
||||
'Initialization segment',
|
||||
).then(this.setupInitSegment.bind(this));
|
||||
|
||||
// sidx (segment index) table
|
||||
@ -226,6 +228,7 @@ Stream.prototype.setup = async function(){
|
||||
this.url,
|
||||
this.indexRange.start,
|
||||
this.indexRange.end,
|
||||
'Index segment',
|
||||
).then(this.setupSegmentIndex.bind(this));
|
||||
}
|
||||
}
|
||||
@ -485,6 +488,7 @@ Stream.prototype.fetchSegment = function(segmentIdx) {
|
||||
this.url,
|
||||
entry.start,
|
||||
entry.end,
|
||||
String(this.streamType) + ' segment ' + String(segmentIdx),
|
||||
).then(this.appendSegment.bind(this, segmentIdx));
|
||||
}
|
||||
Stream.prototype.fetchSegmentIfNeeded = function(segmentIdx) {
|
||||
@ -523,27 +527,49 @@ Stream.prototype.reportError = function(...args) {
|
||||
|
||||
// https://gomakethings.com/promise-based-xhr/
|
||||
// https://stackoverflow.com/a/30008115
|
||||
function fetchRange(url, start, end) {
|
||||
// http://lofi.limo/blog/retry-xmlhttprequest-carefully
|
||||
function fetchRange(url, start, end, debugInfo) {
|
||||
return new Promise((resolve, reject) => {
|
||||
let retryCount = 0;
|
||||
let xhr = new XMLHttpRequest();
|
||||
function onFailure(err, message, maxRetries=5){
|
||||
message = debugInfo + ': ' + message + ' - Err: ' + String(err);
|
||||
retryCount++;
|
||||
if (retryCount > maxRetries || xhr.status == 403){
|
||||
reportError('fetchRange error while fetching ' + message);
|
||||
reject(message);
|
||||
return;
|
||||
} else {
|
||||
reportWarning('Failed to fetch ' + message
|
||||
+ '. Attempting retry '
|
||||
+ String(retryCount) +'/' + String(maxRetries));
|
||||
}
|
||||
|
||||
// Retry in 1 second, doubled for each next retry
|
||||
setTimeout(function(){
|
||||
xhr.open('get',url);
|
||||
xhr.send();
|
||||
}, 1000*Math.pow(2,(retryCount-1)));
|
||||
}
|
||||
xhr.open('get', url);
|
||||
xhr.timeout = 15000;
|
||||
xhr.responseType = 'arraybuffer';
|
||||
xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end);
|
||||
xhr.onload = function () {
|
||||
xhr.onload = function (e) {
|
||||
if (xhr.status >= 200 && xhr.status < 300) {
|
||||
resolve(xhr.response);
|
||||
} else {
|
||||
reject({
|
||||
status: xhr.status,
|
||||
statusText: xhr.statusText
|
||||
});
|
||||
onFailure(e,
|
||||
'Status '
|
||||
+ String(xhr.status) + ' ' + String(xhr.statusText)
|
||||
);
|
||||
}
|
||||
};
|
||||
xhr.onerror = function () {
|
||||
reject({
|
||||
status: xhr.status,
|
||||
statusText: xhr.statusText
|
||||
});
|
||||
xhr.onerror = function (event) {
|
||||
onFailure(e, 'Network error');
|
||||
};
|
||||
xhr.ontimeout = function (event){
|
||||
onFailure(null, 'Timeout (15s)', maxRetries=1);
|
||||
};
|
||||
xhr.send();
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user