Add endpoit to get audio url

This commit is contained in:
Leonardo Segala 2025-08-02 04:09:01 +02:00
parent 1383c0fbed
commit 64941061ea
2 changed files with 37 additions and 9 deletions

View file

@ -8,8 +8,8 @@ from dataclasses import asdict
from .state import State from .state import State
from .connect import get_connection from .connect import get_connection
from .room import Room from .room import Room
from .song import Song, init_db, get_song_by_title_artist, add_song_in_db 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, download_song_mp3 from .song_fetch import lastfm_query_search, yt_get_audio_url, yt_search_song
from .qrcode_gen import generate_qr from .qrcode_gen import generate_qr
from typing import Any from typing import Any
@ -171,8 +171,7 @@ def add_song():
if (song := get_song_by_title_artist(info.title, info.artist)) is None: if (song := get_song_by_title_artist(info.title, info.artist)) is None:
## song not found, downolad from YT ## song not found, downolad from YT
if (res := download_song_mp3(info.title, info.artist)) is None: yt_video_id = yt_search_song(info.title, info.artist)
return error("Cannot get info from YT")
## add in DB ## add in DB
song = Song( song = Song(
@ -181,7 +180,7 @@ def add_song():
artist=info.artist, artist=info.artist,
tags=info.tags, tags=info.tags,
image_id=info.img_id, image_id=info.img_id,
youtube_id=res[0], youtube_id=yt_video_id,
) )
add_song_in_db(song) add_song_in_db(song)
@ -241,5 +240,19 @@ def room_qrcode():
return Response(stream, content_type="image/jpeg") return Response(stream, content_type="image/jpeg")
@app.get("/api/song/audio")
def get_audio_url():
if (song_uuid := request.args.get("song")) is None:
return error("Missing song id")
if (song := get_song_by_uuid(song_uuid)) is None:
return error("Song not found")
if (url := yt_get_audio_url(song.youtube_id)) is None:
return error("Cannot get audio url")
return {"success": True, "url": url}
if __name__ == "__main__": if __name__ == "__main__":
socketio.run(app, debug=True) socketio.run(app, debug=True)

View file

@ -59,7 +59,7 @@ def lastfm_query_search(query: str) -> SongInfo:
return SongInfo(artist=artist, title=name, img_id=img_id, tags=tags) return SongInfo(artist=artist, title=name, img_id=img_id, tags=tags)
def download_song_mp3(name: str, artist: str) -> tuple[str, str] | None: # ( id, audio ) def yt_search_song(name: str, artist: str) -> str: # video id
ydl_opts = { ydl_opts = {
"format": "bestaudio", "format": "bestaudio",
"default_search": "ytsearch1", "default_search": "ytsearch1",
@ -70,12 +70,27 @@ def download_song_mp3(name: str, artist: str) -> tuple[str, str] | None: # ( id
with yt_dlp.YoutubeDL(ydl_opts) as ydl: with yt_dlp.YoutubeDL(ydl_opts) as ydl:
info = ydl.extract_info(f"{name!r} - {artist!r}", download=False) info = ydl.extract_info(f"{name!r} - {artist!r}", download=False)
first_entry = info["entries"][0] return info["entries"][0]["id"]
video_id = first_entry["id"]
def yt_get_audio_url(video_id) -> str | None: # audio url
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(video_id, download=False)
if "entries" not in info:
return info["url"]
first_entry = info["entries"][0]
for fmt in first_entry["formats"]: for fmt in first_entry["formats"]:
if "acodec" in fmt and fmt["acodec"] != "none": if "acodec" in fmt and fmt["acodec"] != "none":
return video_id, fmt["url"] return fmt["url"]
return None return None