aboutsummaryrefslogtreecommitdiff
path: root/ext/js/media/audio-downloader.js
diff options
context:
space:
mode:
Diffstat (limited to 'ext/js/media/audio-downloader.js')
-rw-r--r--ext/js/media/audio-downloader.js32
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');