Skip to content

Commit ad3814c

Browse files
committed
Fix: opus cover art support, now using mutagen which is already a dependancy of spotiflac
1 parent 464a5e8 commit ad3814c

1 file changed

Lines changed: 38 additions & 1 deletion

File tree

backend/providers/spotify.py

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import asyncio
2+
import base64
23
import json
34
import os
45
import pathlib
56
import re
67
import shutil
8+
import struct
79
from typing import AsyncGenerator, Any
810

911
def _is_playlist_url(url: str) -> bool:
@@ -104,7 +106,7 @@ async def _spotiflac_stream(
104106
yield f"data: Output folder : {dest_note}\n\n"
105107
yield f"data: $ {' '.join(command)}\n\n"
106108
yield "data: \n\n"
107-
yield "data: ⏳ SpotiFLAC is running. Output may appear in batches this is normal for the binary.\n\n"
109+
yield "data: ⏳ SpotiFLAC is running. Output may appear in batches - this is normal for the binary.\n\n"
108110

109111
# Attempt to find playlist title (unlikely)
110112
if is_playlist and playlist_folder:
@@ -216,6 +218,7 @@ async def _spotiflac_stream(
216218
else: # opus
217219
ffmpeg_cmd = [
218220
"ffmpeg", "-y", "-i", str(flac_path),
221+
"-vn",
219222
"-map_metadata", "0",
220223
"-c:a", "libopus",
221224
"-b:a", "320k",
@@ -230,6 +233,40 @@ async def _spotiflac_stream(
230233
)
231234
await proc.wait()
232235
if proc.returncode == 0:
236+
# Embed cover art for opus via mutagen
237+
if output_format == "opus":
238+
try:
239+
from mutagen.flac import FLAC
240+
from mutagen.oggopus import OggOpus
241+
242+
flac_tags = FLAC(str(flac_path))
243+
if flac_tags.pictures:
244+
pic = flac_tags.pictures[0]
245+
246+
# Build METADATA_BLOCK_PICTURE binary structure
247+
mime = pic.mime.encode("utf-8")
248+
desc = pic.desc.encode("utf-8")
249+
data = pic.data
250+
251+
block = struct.pack(">I", pic.type)
252+
block += struct.pack(">I", len(mime)) + mime
253+
block += struct.pack(">I", len(desc)) + desc
254+
block += struct.pack(
255+
">IIIII",
256+
pic.width, pic.height,
257+
pic.depth, pic.colors,
258+
len(data)
259+
)
260+
block += data
261+
262+
ogg = OggOpus(str(out_path))
263+
ogg["metadata_block_picture"] = [
264+
base64.b64encode(block).decode("ascii")
265+
]
266+
ogg.save()
267+
except Exception as cover_err:
268+
yield f"data: ⚠️ Cover art embedding failed (file is still OK): {cover_err}\n\n"
269+
233270
flac_path.unlink() # Delete original FLAC
234271
transcoded += 1
235272
else:

0 commit comments

Comments
 (0)