Skip to content

Commit

Permalink
av-merge: Retry failed requests
Browse files Browse the repository at this point in the history
Should reduce playback stalling
  • Loading branch information
user234683 committed Jan 22, 2024
1 parent 3213649 commit fd6641c
Showing 1 changed file with 37 additions and 11 deletions.
48 changes: 37 additions & 11 deletions youtube/static/js/av-merge.js
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ Stream.prototype.setup = async function(){
this.url,
this.initRange.start,
this.indexRange.end,
'Initialization+index segments',
).then(
(buffer) => {
var init_end = this.initRange.end - this.initRange.start + 1;
Expand All @@ -219,13 +220,15 @@ Stream.prototype.setup = async function(){
this.url,
this.initRange.start,
this.initRange.end,
'Initialization segment',
).then(this.setupInitSegment.bind(this));

// sidx (segment index) table
fetchRange(
this.url,
this.indexRange.start,
this.indexRange.end,
'Index segment',
).then(this.setupSegmentIndex.bind(this));
}
}
Expand Down Expand Up @@ -484,6 +487,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) {
Expand Down Expand Up @@ -522,27 +526,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) => {
var retryCount = 0;
var 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();
});
Expand Down

0 comments on commit fd6641c

Please sign in to comment.