From a49439a52248e8fd34f2ade4b4e63b26c925aa5e Mon Sep 17 00:00:00 2001 From: Eduard Kuzmenko Date: Fri, 9 Jul 2021 18:59:15 +0300 Subject: [PATCH] Improve streaming --- src/components/wrappers.ts | 5 ++++ src/lib/serviceWorker/stream.ts | 43 +++++++++++++++++++++------------ 2 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/components/wrappers.ts b/src/components/wrappers.ts index d9820b81..5df44a3c 100644 --- a/src/components/wrappers.ts +++ b/src/components/wrappers.ts @@ -329,6 +329,11 @@ export function wrapVideo({doc, container, message, boxWidth, boxHeight, withTai } } + video.addEventListener('error', (e) => { + console.error("Error " + video.error.code + "; details: " + video.error.message); + preloader.detach(); + }, {once: true}); + if(!noAutoDownload && f) { f(); f = null; diff --git a/src/lib/serviceWorker/stream.ts b/src/lib/serviceWorker/stream.ts index b918f7e2..430e1232 100644 --- a/src/lib/serviceWorker/stream.ts +++ b/src/lib/serviceWorker/stream.ts @@ -161,18 +161,26 @@ class Stream { }); } + private preloadChunk(offset: number) { + if(this.loadedOffsets.has(offset)) { + return; + } + + this.loadedOffsets.add(offset); + this.requestFilePart(offset, this.limitPart, true); + } + private preloadChunks(offset: number, end: number) { if(end > this.info.size) { end = this.info.size; } - for(; offset < end; offset += this.limitPart) { - if(this.loadedOffsets.has(offset)) { - continue; + if(!offset) { // load last chunk for bounds + this.preloadChunk(alignOffset(offset, this.limitPart)); + } else { // don't preload next chunks before the start + for(; offset < end; offset += this.limitPart) { + this.preloadChunk(offset); } - - this.loadedOffsets.add(offset); - this.requestFilePart(offset, this.limitPart, true); } } @@ -184,7 +192,7 @@ class Stream { return possibleResponse; } - const [offset, end] = range; + let [offset, end] = range; /* if(info.size > limitPart && isSafari && offset === limitPart) { //end = info.size - 1; @@ -195,21 +203,26 @@ class Stream { const limit = end && end < this.limitPart ? alignLimit(end - offset + 1) : this.limitPart; const alignedOffset = alignOffset(offset, limit); + if(!end) { + end = Math.min(offset + limit, this.info.size - 1); + } + return this.requestFilePart(alignedOffset, limit).then(ab => { //log.debug('[stream] requestFilePart result:', result); + // if(isSafari) { + if(offset !== alignedOffset || end !== (alignedOffset + limit)) { + ab = ab.slice(offset - alignedOffset, end - alignedOffset + 1); + } + const headers: Record = { 'Accept-Ranges': 'bytes', - 'Content-Range': `bytes ${alignedOffset}-${alignedOffset + ab.byteLength - 1}/${this.info.size || '*'}`, - 'Content-Length': `${ab.byteLength}`, + 'Content-Range': `bytes ${offset}-${offset + ab.byteLength - 1}/${this.info.size || '*'}`, + 'Content-Length': `${ab.byteLength}` }; - if(this.info.mimeType) headers['Content-Type'] = this.info.mimeType; - - if(isSafari) { - ab = ab.slice(offset - alignedOffset, end - alignedOffset + 1); - headers['Content-Range'] = `bytes ${offset}-${offset + ab.byteLength - 1}/${this.info.size || '*'}`; - headers['Content-Length'] = `${ab.byteLength}`; + if(this.info.mimeType) { + headers['Content-Type'] = this.info.mimeType; } // simulate slow connection