diff --git a/furumi-node-player/client/src/FurumiPlayer.tsx b/furumi-node-player/client/src/FurumiPlayer.tsx index c960250..7a38ac5 100644 --- a/furumi-node-player/client/src/FurumiPlayer.tsx +++ b/furumi-node-player/client/src/FurumiPlayer.tsx @@ -68,7 +68,7 @@ export function FurumiPlayer() { Array<{ result_type: string; slug: string; name: string; detail?: string }> >([]) const [searchOpen, setSearchOpen] = useState(false) - const searchSelectRef = useRef<(type: string, slug: string) => void>(() => {}) + const searchSelectRef = useRef<(type: string, slug: string) => void>(() => { }) const queueActionsRef = useRef<{ playIndex: (i: number) => void @@ -333,8 +333,18 @@ export function FurumiPlayer() { if (i < 0 || i >= q.items.length) return dispatch(playAtIndex(i)) const track = store.getState().queue.items[i] - audio.src = `${API_ROOT}/stream/${track.slug}` - void audio.play().catch(() => {}) + // TODO remove after auth refactor + preloadStream(track.slug).then(response => { + console.log('response', response) + audio.src = URL.createObjectURL(response?.data) + void audio.play().catch(() => { }) + // Optionally revoke old object URL if needed to avoid memory leaks + // if (oldSrc?.startsWith('blob:')) { + // URL.revokeObjectURL(oldSrc) + // } + }) + // audio.src = `${API_ROOT}/stream/${track.slug}` + // void audio.play().catch(() => {}) if (window.history && window.history.replaceState) { const url = new URL(window.location.href) url.searchParams.set('t', track.slug) @@ -550,28 +560,28 @@ export function FurumiPlayer() { const clearQueueBtn = document.getElementById('btnClearQueue') clearQueueBtn?.addEventListener('click', () => clearQueuePlayback()) - ;(async () => { - const url = new URL(window.location.href) - const urlSlug = url.searchParams.get('t') - if (urlSlug) { - try { - const { detail } = await dispatch(fetchTrackDetail(urlSlug)).unwrap() - addTrackToQueue( - { - slug: detail.slug, - title: detail.title, - artist: detail.artist_name, - album_slug: detail.album_slug, - duration: detail.duration_secs, - }, - true, - ) - } catch { - // fetchTrackDetail rejected — track not found or error + ; (async () => { + const url = new URL(window.location.href) + const urlSlug = url.searchParams.get('t') + if (urlSlug) { + try { + const { detail } = await dispatch(fetchTrackDetail(urlSlug)).unwrap() + addTrackToQueue( + { + slug: detail.slug, + title: detail.title, + artist: detail.artist_name, + album_slug: detail.album_slug, + duration: detail.duration_secs, + }, + true, + ) + } catch { + // fetchTrackDetail rejected — track not found or error + } } - } - void showArtists() - })() + void showArtists() + })() return () => { queueActionsRef.current = null diff --git a/furumi-node-player/client/src/furumiApi.ts b/furumi-node-player/client/src/furumiApi.ts index 135e573..bdf4114 100644 --- a/furumi-node-player/client/src/furumiApi.ts +++ b/furumi-node-player/client/src/furumiApi.ts @@ -44,6 +44,6 @@ export async function getTrackInfo(trackSlug: string): Promise null) + return await furumiApi.get(`/stream/${trackSlug}`, { responseType: 'blob' }).catch(() => null) }