mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
update components
This commit is contained in:
parent
c6b706f48a
commit
5de2e610ce
35 changed files with 1420 additions and 1130 deletions
83
dashboard-ui/bower_components/hls.js/src/utils/attr-list.js
vendored
Normal file
83
dashboard-ui/bower_components/hls.js/src/utils/attr-list.js
vendored
Normal file
|
@ -0,0 +1,83 @@
|
|||
|
||||
// adapted from https://github.com/kanongil/node-m3u8parse/blob/master/attrlist.js
|
||||
class AttrList {
|
||||
|
||||
constructor(attrs) {
|
||||
if (typeof attrs === 'string') {
|
||||
attrs = AttrList.parseAttrList(attrs);
|
||||
}
|
||||
for(var attr in attrs){
|
||||
if(attrs.hasOwnProperty(attr)) {
|
||||
this[attr] = attrs[attr];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
decimalInteger(attrName) {
|
||||
const intValue = parseInt(this[attrName], 10);
|
||||
if (intValue > Number.MAX_SAFE_INTEGER) {
|
||||
return Infinity;
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
hexadecimalInteger(attrName) {
|
||||
if(this[attrName]) {
|
||||
let stringValue = (this[attrName] || '0x').slice(2);
|
||||
stringValue = ((stringValue.length & 1) ? '0' : '') + stringValue;
|
||||
|
||||
const value = new Uint8Array(stringValue.length / 2);
|
||||
for (let i = 0; i < stringValue.length / 2; i++) {
|
||||
value[i] = parseInt(stringValue.slice(i * 2, i * 2 + 2), 16);
|
||||
}
|
||||
return value;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
hexadecimalIntegerAsNumber(attrName) {
|
||||
const intValue = parseInt(this[attrName], 16);
|
||||
if (intValue > Number.MAX_SAFE_INTEGER) {
|
||||
return Infinity;
|
||||
}
|
||||
return intValue;
|
||||
}
|
||||
|
||||
decimalFloatingPoint(attrName) {
|
||||
return parseFloat(this[attrName]);
|
||||
}
|
||||
|
||||
enumeratedString(attrName) {
|
||||
return this[attrName];
|
||||
}
|
||||
|
||||
decimalResolution(attrName) {
|
||||
const res = /^(\d+)x(\d+)$/.exec(this[attrName]);
|
||||
if (res === null) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
width: parseInt(res[1], 10),
|
||||
height: parseInt(res[2], 10)
|
||||
};
|
||||
}
|
||||
|
||||
static parseAttrList(input) {
|
||||
const re = /(.+?)=((?:\".*?\")|.*?)(?:,|$)/g;
|
||||
var match, attrs = {};
|
||||
while ((match = re.exec(input)) !== null) {
|
||||
var value = match[2], quote = '"';
|
||||
|
||||
if (value.indexOf(quote) === 0 &&
|
||||
value.lastIndexOf(quote) === (value.length-1)) {
|
||||
value = value.slice(1, -1);
|
||||
}
|
||||
attrs[match[1]] = value;
|
||||
}
|
||||
return attrs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default AttrList;
|
|
@ -18,19 +18,21 @@ class XhrLoader {
|
|||
}
|
||||
|
||||
abort() {
|
||||
if (this.loader && this.loader.readyState !== 4) {
|
||||
var loader = this.loader,
|
||||
timeoutHandle = this.timeoutHandle;
|
||||
if (loader && loader.readyState !== 4) {
|
||||
this.stats.aborted = true;
|
||||
this.loader.abort();
|
||||
loader.abort();
|
||||
}
|
||||
if (this.timeoutHandle) {
|
||||
window.clearTimeout(this.timeoutHandle);
|
||||
if (timeoutHandle) {
|
||||
window.clearTimeout(timeoutHandle);
|
||||
}
|
||||
}
|
||||
|
||||
load(url, responseType, onSuccess, onError, onTimeout, timeout, maxRetry, retryDelay, onProgress = null, frag = null) {
|
||||
this.url = url;
|
||||
if (frag && !isNaN(frag.byteRangeStartOffset) && !isNaN(frag.byteRangeEndOffset)) {
|
||||
this.byteRange = frag.byteRangeStartOffset + '-' + frag.byteRangeEndOffset;
|
||||
this.byteRange = frag.byteRangeStartOffset + '-' + (frag.byteRangeEndOffset-1);
|
||||
}
|
||||
this.responseType = responseType;
|
||||
this.onSuccess = onSuccess;
|
||||
|
@ -47,9 +49,9 @@ class XhrLoader {
|
|||
|
||||
loadInternal() {
|
||||
var xhr = this.loader = new XMLHttpRequest();
|
||||
xhr.onload = this.loadsuccess.bind(this);
|
||||
xhr.onerror = this.loaderror.bind(this);
|
||||
xhr.onreadystatechange = this.statechange.bind(this);
|
||||
xhr.onprogress = this.loadprogress.bind(this);
|
||||
|
||||
xhr.open('GET', this.url, true);
|
||||
if (this.byteRange) {
|
||||
xhr.setRequestHeader('Range', 'bytes=' + this.byteRange);
|
||||
|
@ -63,24 +65,33 @@ class XhrLoader {
|
|||
xhr.send();
|
||||
}
|
||||
|
||||
loadsuccess(event) {
|
||||
window.clearTimeout(this.timeoutHandle);
|
||||
this.stats.tload = performance.now();
|
||||
this.onSuccess(event, this.stats);
|
||||
}
|
||||
|
||||
loaderror(event) {
|
||||
if (this.stats.retry < this.maxRetry) {
|
||||
logger.warn(`${event.type} while loading ${this.url}, retrying in ${this.retryDelay}...`);
|
||||
this.destroy();
|
||||
window.setTimeout(this.loadInternal.bind(this), this.retryDelay);
|
||||
// exponential backoff
|
||||
this.retryDelay = Math.min(2 * this.retryDelay, 64000);
|
||||
this.stats.retry++;
|
||||
} else {
|
||||
window.clearTimeout(this.timeoutHandle);
|
||||
logger.error(`${event.type} while loading ${this.url}` );
|
||||
this.onError(event);
|
||||
statechange(event) {
|
||||
var xhr = event.currentTarget,
|
||||
status = xhr.status,
|
||||
stats = this.stats;
|
||||
// don't proceed if xhr has been aborted
|
||||
// 4 = Response from server has been completely loaded.
|
||||
if (!stats.aborted && xhr.readyState === 4) {
|
||||
// http status between 200 to 299 are all successful
|
||||
if (status >= 200 && status < 300) {
|
||||
window.clearTimeout(this.timeoutHandle);
|
||||
stats.tload = performance.now();
|
||||
this.onSuccess(event, stats);
|
||||
} else {
|
||||
// error ...
|
||||
if (stats.retry < this.maxRetry) {
|
||||
logger.warn(`${status} while loading ${this.url}, retrying in ${this.retryDelay}...`);
|
||||
this.destroy();
|
||||
window.setTimeout(this.loadInternal.bind(this), this.retryDelay);
|
||||
// exponential backoff
|
||||
this.retryDelay = Math.min(2 * this.retryDelay, 64000);
|
||||
stats.retry++;
|
||||
} else {
|
||||
window.clearTimeout(this.timeoutHandle);
|
||||
logger.error(`${status} while loading ${this.url}` );
|
||||
this.onError(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue