diff options
Diffstat (limited to 'ext/js/media/audio-downloader.js')
-rw-r--r-- | ext/js/media/audio-downloader.js | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/ext/js/media/audio-downloader.js b/ext/js/media/audio-downloader.js index 0991d14d..4142e3f4 100644 --- a/ext/js/media/audio-downloader.js +++ b/ext/js/media/audio-downloader.js @@ -18,6 +18,7 @@ /* global * JsonSchema * NativeSimpleDOMParser + * RequestBuilder * SimpleDOMParser * StringUtil */ @@ -50,7 +51,7 @@ class AudioDownloader { return []; } - async downloadTermAudio(sources, preferredAudioIndex, term, reading) { + async downloadTermAudio(sources, preferredAudioIndex, term, reading, idleTimeout) { const errors = []; for (const source of sources) { let infoList = await this.getTermAudioInfoList(source, term, reading); @@ -61,7 +62,7 @@ class AudioDownloader { switch (info.type) { case 'url': try { - return await this._downloadAudioFromUrl(info.url, source.type); + return await this._downloadAudioFromUrl(info.url, source.type, idleTimeout); } catch (e) { errors.push(e); } @@ -241,21 +242,42 @@ class AudioDownloader { return url.replace(/\{([^}]*)\}/g, (m0, m1) => (Object.prototype.hasOwnProperty.call(data, m1) ? `${data[m1]}` : m0)); } - async _downloadAudioFromUrl(url, sourceType) { + async _downloadAudioFromUrl(url, sourceType, idleTimeout) { + let signal; + let onProgress = null; + let idleTimer = null; + if (typeof idleTimeout === 'number') { + const abortController = new AbortController(); + ({signal} = abortController); + const onIdleTimeout = () => { + abortController.abort('Idle timeout'); + }; + onProgress = (done) => { + clearTimeout(idleTimer); + idleTimer = done ? null : setTimeout(onIdleTimeout, idleTimeout); + }; + idleTimer = setTimeout(onIdleTimeout, idleTimeout); + } + const response = await this._requestBuilder.fetchAnonymous(url, { method: 'GET', mode: 'cors', cache: 'default', credentials: 'omit', redirect: 'follow', - referrerPolicy: 'no-referrer' + referrerPolicy: 'no-referrer', + signal }); if (!response.ok) { throw new Error(`Invalid response: ${response.status}`); } - const arrayBuffer = await response.arrayBuffer(); + const arrayBuffer = await RequestBuilder.readFetchResponseArrayBuffer(response, onProgress); + + if (idleTimer !== null) { + clearTimeout(idleTimer); + } if (!await this._isAudioBinaryValid(arrayBuffer, sourceType)) { throw new Error('Could not retrieve audio'); |