feat: embed album art in ID3 tags on download

APIC tag now embeds the track's artwork (if it exists) into the MP3
file when downloading. Supports PNG, JPEG, and WebP. Key and BPM were
already being written — this was the missing piece.
This commit is contained in:
rin.kagamine committed 2026-05-31 11:15:52 -04:00
1 parent 6c926203f0
commit 1903d8bd2a
1 file changed
+16 -1
+16 -1
View File
@@ -135,7 +135,7 @@ async def stream_audio(clip_id: str):
return FileResponse(file_path, media_type="audio/mpeg", filename=clip["filename"]) return FileResponse(file_path, media_type="audio/mpeg", filename=clip["filename"])
from mutagen.mp3 import MP3 from mutagen.mp3 import MP3
from mutagen.id3 import ID3, TIT1, TIT2, TPE1, TALB, COMM, TBPM, TKEY from mutagen.id3 import ID3, TIT1, TIT2, TPE1, TALB, COMM, TBPM, TKEY, APIC, PictureType
@app.get("/api/clips/{clip_id}/download") @app.get("/api/clips/{clip_id}/download")
async def download_clip(clip_id: str): async def download_clip(clip_id: str):
@@ -197,6 +197,21 @@ async def download_clip(clip_id: str):
if clip.get("key"): if clip.get("key"):
audio.tags["TKEY"] = TKEY(encoding=3, text=clip["key"]) audio.tags["TKEY"] = TKEY(encoding=3, text=clip["key"])
# Album art
if clip.get("artwork_filename"):
artwork_path = ARTWORK_DIR / clip["artwork_filename"]
if artwork_path.exists():
artwork_data = artwork_path.read_bytes()
ext = artwork_path.suffix.lower()
mime = {'.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', '.webp': 'image/webp'}.get(ext, 'image/jpeg')
audio.tags["APIC"] = APIC(
encoding=3,
mime=mime,
type=PictureType.COVER_FRONT,
desc='Cover',
data=artwork_data
)
# Also store the prompt in a custom tag for reference # Also store the prompt in a custom tag for reference
if clip.get("prompt"): if clip.get("prompt"):
audio.tags["TIT1"] = TIT1(encoding=3, text=clip["prompt"][:100]) audio.tags["TIT1"] = TIT1(encoding=3, text=clip["prompt"][:100])