UNPKG

one

Version:

One is a React framework for web, iOS, and Android apps.

206 lines (203 loc) • 5.92 kB
import { createPlayerEvents } from "./events.mjs"; import { assertCrossOrigin, assertFlag, assertPitchQuality, assertRate, assertSeconds, assertTolerance, assertVolume, normalizeSource, rateError, resolveUpdateInterval } from "./validate.mjs"; var AudioPlayer = class { element; playerId; removed = false; events; buffering = false; finished = false; failure = null; constructor(element, id, updateIntervalMs) { this.element = element; this.playerId = id; this.events = createPlayerEvents(() => this.getStatus(), updateIntervalMs); element.addEventListener("waiting", () => { this.buffering = true; }); element.addEventListener("playing", () => { this.buffering = false; this.failure = null; }); element.addEventListener("canplay", () => { this.buffering = false; }); element.addEventListener("ended", () => { this.finished = true; }); element.addEventListener("error", () => { this.failure = element.error?.message || "audio playback failed"; }); } get id() { return this.playerId; } get currentTime() { this.assertUsable("currentTime"); return this.element.currentTime; } get duration() { this.assertUsable("duration"); const duration = this.element.duration; return Number.isFinite(duration) ? duration : 0; } get playing() { this.assertUsable("playing"); return !this.element.paused && !this.element.ended; } get paused() { this.assertUsable("paused"); return this.isLoaded && !this.playing; } get isLoaded() { this.assertUsable("isLoaded"); return this.element.readyState >= 2; } get isBuffering() { this.assertUsable("isBuffering"); return this.buffering; } get isAudioSamplingSupported() { return false; } get loop() { this.assertUsable("loop"); return this.element.loop; } set loop(value) { this.assertUsable("loop"); assertFlag(value, "AudioPlayer.loop"); this.element.loop = value; } get muted() { this.assertUsable("muted"); return this.element.muted; } set muted(value) { this.assertUsable("muted"); assertFlag(value, "AudioPlayer.muted"); this.element.muted = value; } get volume() { this.assertUsable("volume"); return this.element.volume; } set volume(value) { this.assertUsable("volume"); assertVolume(value, "AudioPlayer.volume"); this.element.volume = value; } get playbackRate() { this.assertUsable("playbackRate"); return this.element.playbackRate; } get shouldCorrectPitch() { this.assertUsable("shouldCorrectPitch"); return this.element.preservesPitch; } set shouldCorrectPitch(value) { this.assertUsable("shouldCorrectPitch"); assertFlag(value, "AudioPlayer.shouldCorrectPitch"); this.element.preservesPitch = value; } play() { this.assertUsable("play"); this.finished = false; const started = this.element.play(); if (started && typeof started.catch === "function") { started.catch((error) => { this.failure = error instanceof Error ? error.message : "audio playback failed"; }); } } pause() { this.assertUsable("pause"); this.element.pause(); } seekTo(seconds, toleranceMillisBefore, toleranceMillisAfter) { this.assertUsable("seekTo"); assertSeconds(seconds, "AudioPlayer.seekTo"); if (toleranceMillisBefore !== void 0) { assertTolerance(toleranceMillisBefore, "AudioPlayer.seekTo"); } if (toleranceMillisAfter !== void 0) { assertTolerance(toleranceMillisAfter, "AudioPlayer.seekTo"); } this.finished = false; this.element.currentTime = seconds; if (!this.element.seeking) return Promise.resolve(); return new Promise((resolve) => { this.element.addEventListener("seeked", () => resolve(), { once: true }); }); } replace(source) { this.assertUsable("replace"); const normalized = normalizeSource(source, "AudioPlayer.replace"); this.finished = false; this.failure = null; if (normalized.uri === void 0) { this.element.removeAttribute("src"); } else { this.element.src = normalized.uri; } this.element.load(); } remove() { if (this.removed) return; this.removed = true; this.events.removeAll(); this.element.pause(); this.element.removeAttribute("src"); this.element.load(); } getStatus() { this.assertUsable("getStatus"); return { currentTime: this.currentTime, didJustFinish: this.finished, duration: this.duration, error: this.failure, id: this.playerId, isBuffering: this.isBuffering, isLoaded: this.isLoaded, loop: this.loop, mute: this.muted, playbackRate: this.playbackRate, playing: this.playing, shouldCorrectPitch: this.shouldCorrectPitch }; } setPlaybackRate(rate, pitchCorrectionQuality) { this.assertUsable("setPlaybackRate"); assertRate(rate, "AudioPlayer.setPlaybackRate"); if (pitchCorrectionQuality !== void 0) { assertPitchQuality(pitchCorrectionQuality, "AudioPlayer.setPlaybackRate"); } if (rate < 0 || rate > 2) throw rateError("AudioPlayer.setPlaybackRate"); this.element.playbackRate = rate; } addListener(event, listener) { this.assertUsable("addListener"); return this.events.add(event, listener); } removeAllListeners() { this.events.removeAll(); } assertUsable(verb) { if (this.removed) throw new Error(`AudioPlayer.${verb}: the player was removed`); } }; function createPlayer(source = null, options = {}) { const normalized = normalizeSource(source, "Audio.createPlayer"); const updateIntervalMs = resolveUpdateInterval(options, "Audio.createPlayer"); assertCrossOrigin(options.crossOrigin, "Audio.createPlayer"); const element = new Audio(); element.preload = "auto"; if (options.crossOrigin !== void 0) element.crossOrigin = options.crossOrigin; if (normalized.uri !== void 0) element.src = normalized.uri; const id = `player-${AudioPlayerId.next++}`; return new AudioPlayer(element, id, updateIntervalMs); } const AudioPlayerId = { next: 1 }; export { AudioPlayer, createPlayer }; //# sourceMappingURL=player.mjs.map