Working around the inability to play more than 6 streams at once.

Remote sources (those starting with https?://) now get a random subdomain
prepended by default. This can be switched off by setting the 'nomunge'
attribute on the player element to a truthy value.
This commit is contained in:
Erik Thuning 2022-11-04 11:43:59 +01:00
parent 099399a92f
commit cec90328dc

@ -198,9 +198,18 @@
return wrapper;
}
function randString(length) {
var pool = 'abcdefghijklmnopqrstuvwxyz1234567890';
var out = '';
for(var i=0; i<length; i++) {
out += pool.charAt(Math.floor(Math.random() * pool.length));
}
return out;
}
class MultiPlayer extends HTMLElement {
static get observedAttributes() {
return ['play', 'play-local', 'list', 'list-local'];
return ['play', 'play-local', 'list', 'list-local', 'nomunge'];
}
attributeChangedCallback(name, oldValue, newValue) {
@ -233,12 +242,25 @@
}
this.initPlaylist(JSON.parse(newValue));
break;
case 'nomunge':
if(newValue) {
this._mungeSources = false;
} else {
this._mungeSources = true;
}
break;
}
}
constructor() {
super();
// Controls whether to prefix a random subdomain to each remote
// source in order to work around the browser limit of ~6
// connections per host. On by default.
// Controlled by the 'nomunge' attribute on this element.
this._mungeSources = true;
// raw presentation json is stored here
this._presentation = null;
@ -573,17 +595,25 @@
'preload': 'auto',
'crossorigin': 'anonymous'});
// set the initial source, with token
const defaultSource = stream.video[resolutions[defaultRes]];
video.src = `${defaultSource}?token=${token}`;
// append token to each resolution and save it in the
// video element's dataset
Object.entries(stream.video).forEach(([resolution, src]) => {
const tokenized = `${src}?token=${token}`;
let tokenized = `${src}?token=${token}`;
if(this._mungeSources) {
// In order to work around the browser's limit of ~6
// simultaneous connections per server, prepend a
// random subdomain to the source if it is remote.
const prefix = randString(6);
tokenized = src.replace(/^(https?:\/\/)(.*)/,
`$1${prefix}.$2`);
}
video.dataset[resolution] = tokenized;
});
// pick the default resolution from the dataset and use it
// as initial src
video.src = video.dataset[resolutions[defaultRes]];
// subs, if present
if(presentation.subtitles) {
for(const key in presentation.subtitles) {