32 lines
1.6 KiB
JavaScript
32 lines
1.6 KiB
JavaScript
(function (root) {
|
|
'use strict';
|
|
function progressiveSource(current, videoSource) {
|
|
return current?.eqAudioUrl || current?.localUrl || current?.audioUrl || videoSource || '';
|
|
}
|
|
function needsAlignment(time, clock, threshold = 0.3) {
|
|
return Number.isFinite(time) && Number.isFinite(clock) && Math.abs(time - clock) >= threshold;
|
|
}
|
|
function create() {
|
|
const pending = new WeakMap();
|
|
function play(element) {
|
|
if (pending.has(element)) return pending.get(element);
|
|
if (!element.paused) return Promise.resolve();
|
|
let request;
|
|
try { request = Promise.resolve(element.play()); } catch (error) { request = Promise.reject(error); }
|
|
// Preserve the intent to play after an OS interruption; the watchdog retries.
|
|
request = request.catch(() => {}).finally(() => { if (pending.get(element) === request) pending.delete(element); });
|
|
pending.set(element, request); return request;
|
|
}
|
|
function resume(element, clock) {
|
|
// An ended element is finished, not interrupted: play() would restart it from 0.
|
|
if (!element || !element.paused || element.ended || pending.has(element)) return;
|
|
if (clock && element !== clock && needsAlignment(element.currentTime, clock.currentTime)) element.currentTime = clock.currentTime;
|
|
return play(element);
|
|
}
|
|
return { play, resume, reset: element => pending.delete(element) };
|
|
}
|
|
const api = { progressiveSource, needsAlignment, create };
|
|
if (typeof module !== 'undefined' && module.exports) module.exports = api;
|
|
else { root.AudioContinuity = api; root.audioContinuity = create(); }
|
|
})(globalThis);
|