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.url,
|
||||||
this.initRange.start,
|
this.initRange.start,
|
||||||
this.indexRange.end,
|
this.indexRange.end,
|
||||||
|
'Initialization+index segments',
|
||||||
).then(
|
).then(
|
||||||
(buffer) => {
|
(buffer) => {
|
||||||
let init_end = this.initRange.end - this.initRange.start + 1;
|
let init_end = this.initRange.end - this.initRange.start + 1;
|
||||||
@ -219,6 +220,7 @@ Stream.prototype.setup = async function(){
|
|||||||
this.url,
|
this.url,
|
||||||
this.initRange.start,
|
this.initRange.start,
|
||||||
this.initRange.end,
|
this.initRange.end,
|
||||||
|
'Initialization segment',
|
||||||
).then(this.setupInitSegment.bind(this));
|
).then(this.setupInitSegment.bind(this));
|
||||||
|
|
||||||
// sidx (segment index) table
|
// sidx (segment index) table
|
||||||
@ -226,6 +228,7 @@ Stream.prototype.setup = async function(){
|
|||||||
this.url,
|
this.url,
|
||||||
this.indexRange.start,
|
this.indexRange.start,
|
||||||
this.indexRange.end,
|
this.indexRange.end,
|
||||||
|
'Index segment',
|
||||||
).then(this.setupSegmentIndex.bind(this));
|
).then(this.setupSegmentIndex.bind(this));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -485,6 +488,7 @@ Stream.prototype.fetchSegment = function(segmentIdx) {
|
|||||||
this.url,
|
this.url,
|
||||||
entry.start,
|
entry.start,
|
||||||
entry.end,
|
entry.end,
|
||||||
|
String(this.streamType) + ' segment ' + String(segmentIdx),
|
||||||
).then(this.appendSegment.bind(this, segmentIdx));
|
).then(this.appendSegment.bind(this, segmentIdx));
|
||||||
}
|
}
|
||||||
Stream.prototype.fetchSegmentIfNeeded = function(segmentIdx) {
|
Stream.prototype.fetchSegmentIfNeeded = function(segmentIdx) {
|
||||||
@ -523,27 +527,49 @@ Stream.prototype.reportError = function(...args) {
|
|||||||
|
|
||||||
// https://gomakethings.com/promise-based-xhr/
|
// https://gomakethings.com/promise-based-xhr/
|
||||||
// https://stackoverflow.com/a/30008115
|
// 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) => {
|
return new Promise((resolve, reject) => {
|
||||||
|
let retryCount = 0;
|
||||||
let xhr = new XMLHttpRequest();
|
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.open('get', url);
|
||||||
|
xhr.timeout = 15000;
|
||||||
xhr.responseType = 'arraybuffer';
|
xhr.responseType = 'arraybuffer';
|
||||||
xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end);
|
xhr.setRequestHeader('Range', 'bytes=' + start + '-' + end);
|
||||||
xhr.onload = function () {
|
xhr.onload = function (e) {
|
||||||
if (xhr.status >= 200 && xhr.status < 300) {
|
if (xhr.status >= 200 && xhr.status < 300) {
|
||||||
resolve(xhr.response);
|
resolve(xhr.response);
|
||||||
} else {
|
} else {
|
||||||
reject({
|
onFailure(e,
|
||||||
status: xhr.status,
|
'Status '
|
||||||
statusText: xhr.statusText
|
+ String(xhr.status) + ' ' + String(xhr.statusText)
|
||||||
});
|
);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhr.onerror = function () {
|
xhr.onerror = function (event) {
|
||||||
reject({
|
onFailure(e, 'Network error');
|
||||||
status: xhr.status,
|
};
|
||||||
statusText: xhr.statusText
|
xhr.ontimeout = function (event){
|
||||||
});
|
onFailure(null, 'Timeout (15s)', maxRetries=1);
|
||||||
};
|
};
|
||||||
xhr.send();
|
xhr.send();
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user