UNPKG

@aituber-onair/voice

Version:

Voice synthesis library for AITuber OnAir

96 lines (95 loc) 3.38 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.BrowserAudioPlayer = void 0; /** * Browser-based audio player implementation using HTMLAudioElement */ class BrowserAudioPlayer { constructor() { this.audioElement = null; this.isPlayingAudio = false; if (typeof window !== 'undefined' && typeof document !== 'undefined') { this.audioElement = document.createElement('audio'); this.audioElement.addEventListener('ended', () => { this.handlePlaybackEnd(); }); } } async play(audioBuffer, audioElementId) { return new Promise((resolve, reject) => { try { if (typeof window === 'undefined' || typeof document === 'undefined') { resolve(); return; } const blob = new Blob([audioBuffer], { type: 'audio/wav' }); const url = URL.createObjectURL(blob); let audioEl = this.audioElement; if (audioElementId) { const customAudioEl = document.getElementById(audioElementId); if (customAudioEl) { audioEl = customAudioEl; } } if (!audioEl) { reject(new Error('Audio element not available')); return; } const onEnded = () => { URL.revokeObjectURL(url); audioEl?.removeEventListener('ended', onEnded); audioEl?.removeEventListener('error', onError); this.handlePlaybackEnd(); resolve(); }; const onError = (e) => { URL.revokeObjectURL(url); audioEl?.removeEventListener('ended', onEnded); audioEl?.removeEventListener('error', onError); this.isPlayingAudio = false; reject(new Error(`Audio playback error: ${e.message}`)); }; audioEl.addEventListener('ended', onEnded); audioEl.addEventListener('error', onError); this.isPlayingAudio = true; audioEl.src = url; audioEl.play().catch((error) => { URL.revokeObjectURL(url); this.isPlayingAudio = false; reject(error); }); } catch (error) { this.isPlayingAudio = false; reject(error); } }); } stop() { if (this.audioElement) { this.audioElement.pause(); this.audioElement.currentTime = 0; } this.isPlayingAudio = false; } isPlaying() { return this.isPlayingAudio; } setOnComplete(callback) { this.onCompleteCallback = callback; } dispose() { this.stop(); if (this.audioElement) { this.audioElement.remove(); this.audioElement = null; } } handlePlaybackEnd() { this.isPlayingAudio = false; if (this.onCompleteCallback) { this.onCompleteCallback(); } } } exports.BrowserAudioPlayer = BrowserAudioPlayer;