diff --git a/backend/src/app.py b/backend/src/app.py index 247ba5f..c11cf37 100644 --- a/backend/src/app.py +++ b/backend/src/app.py @@ -9,7 +9,7 @@ from .state import State from .connect import get_connection from .room import Room from .song import Song, init_db, get_song_by_title_artist, add_song_in_db, get_song_by_uuid -from .song_fetch import lastfm_query_search, yt_get_audio_url, yt_search_song +from .song_fetch import query_search, yt_get_audio_url, yt_search_song from .qrcode_gen import generate_qr @@ -182,7 +182,8 @@ def add_song(): if (query := request.args.get("query")) is None: return error("Missing query") - info = lastfm_query_search(query) + if (info := query_search(query)) is None: + return error("Search failed") if (song := get_song_by_title_artist(info.title, info.artist)) is None: ## song not found, downolad from YT diff --git a/backend/src/song_fetch.py b/backend/src/song_fetch.py index ec15485..665e2c9 100644 --- a/backend/src/song_fetch.py +++ b/backend/src/song_fetch.py @@ -51,7 +51,23 @@ def _lastfm_getinfo(name: str, artist: str) -> tuple[str, list[str]]: # ( image ) -def lastfm_query_search(query: str) -> SongInfo: +def _yt_search(query: str) -> tuple[str, str]: + ydl_opts = { + "format": "bestaudio", + "default_search": "ytsearch1", + "outtmpl": "%(title)s.%(ext)s", + "skip_download": True, + } + + with yt_dlp.YoutubeDL(ydl_opts) as ydl: + info = ydl.extract_info(query, download=False) + + first = info["entries"][0] + + return first["track"], first["artists"][0] + + +def query_search(query: str) -> SongInfo | None: name, artist = _lastfm_search(query) img_id, tags = _lastfm_getinfo(name, artist) diff --git a/frontend/src/lib/util.ts b/frontend/src/lib/util.ts deleted file mode 100644 index df0d44e..0000000 --- a/frontend/src/lib/util.ts +++ /dev/null @@ -1 +0,0 @@ -export type FetchError = { code: number, message: string } diff --git a/frontend/src/lib/utils.ts b/frontend/src/lib/utils.ts index 203d6f8..1b806c5 100644 --- a/frontend/src/lib/utils.ts +++ b/frontend/src/lib/utils.ts @@ -65,3 +65,11 @@ export const triggerPlayNext = async function (roomId: string): Promise<[FetchEr }) return [null, songs, json["index"]] } + +export const getStreamingUrl = async function (uuid: string) { + let resp = await fetch("/api/song/audio?song=" + uuid) + + let json = await resp.json() + + return json["url"] +} diff --git a/frontend/src/routes/admin/[id]/+page.svelte b/frontend/src/routes/admin/[id]/+page.svelte index 9bcb9b4..e017cc5 100644 --- a/frontend/src/routes/admin/[id]/+page.svelte +++ b/frontend/src/routes/admin/[id]/+page.svelte @@ -3,21 +3,37 @@ import { type Song } from "$lib/types" import { onMount } from "svelte" import type { FetchError } from "$lib/types" - import { getQueueSongs, triggerPlayNext } from "$lib/utils.js" + import { getQueueSongs, getStreamingUrl, triggerPlayNext } from "$lib/utils.js" import Error from "$lib/components/Error.svelte" let { data } = $props() let queueSongs = $state([]) - let playingIndex = $state() + let playingIndex = $state(0) let returnError = $state() + let currentPlaying = $derived(queueSongs[playingIndex]) + let audioController = $state() + + async function playOnEnd() { + let url = await getStreamingUrl(currentPlaying.uuid) + if (audioController) { + audioController.src = url + audioController.play() + } + } + onMount(async () => { let songs, index ;[returnError, songs, index] = await getQueueSongs(data.roomId) queueSongs = songs playingIndex = index + + if (audioController) { + audioController.src = await getStreamingUrl(currentPlaying.uuid) + audioController.play() + } }) async function playNext() { @@ -37,5 +53,6 @@
+
{/if}