export function init(audioId, dotNetHelper) { const audio = document.getElementById(audioId); if (!audio) throw new Error(`Audio element with id ${audioId} not found`); let durationReady = false; let durationValue = 0; const toNumber = (val) => { const num = Number(val); return isNaN(num) ? 0 : num; }; const loadAndPlay = (src, token, sharedPlaylistId) => { const url = new URL(src, window.location.href); if (token) url.searchParams.set('access_token', token); if (sharedPlaylistId) url.searchParams.set('shared_id', sharedPlaylistId); audio.src = url.toString(); audio.load(); durationReady = false; durationValue = 0; audio.play().catch(e => console.error('Play failed:', e)); }; const play = () => audio.play(); const pause = () => audio.pause(); const stop = () => { audio.pause(); audio.currentTime = 0; }; const setVolume = (volume) => { audio.volume = toNumber(volume); }; const setCurrentTime = (time) => { audio.currentTime = toNumber(time); }; audio.addEventListener('loadedmetadata', () => { const current = toNumber(audio.currentTime); durationValue = toNumber(audio.duration); durationReady = durationValue > 0; if (dotNetHelper && durationReady) { dotNetHelper.invokeMethodAsync('OnTimeUpdate', current, durationValue); } }); audio.addEventListener('timeupdate', () => { if (dotNetHelper && durationReady) { const current = toNumber(audio.currentTime); dotNetHelper.invokeMethodAsync('OnTimeUpdate', current, durationValue); } }); audio.addEventListener('ended', () => { if (dotNetHelper) { dotNetHelper.invokeMethodAsync('OnAudioEnded'); } }); audio.addEventListener('progress', () => { if (dotNetHelper) { if (audio.buffered.length > 0 && audio.duration) { const bufferedEnd = toNumber(audio.buffered.end(audio.buffered.length - 1)); dotNetHelper.invokeMethodAsync('OnDownloadProgress', bufferedEnd); } } }); // Возвращаем все методы, которые будут вызываться из C# return { loadAndPlay, play, pause, stop, setVolume, setCurrentTime }; }