Skip to content

Commit 871b932

Browse files
authored
fix: detect Tencent SILK (\x02 prefix) in audio magic bytes to avoid ffmpeg failure (#8009)
* fix: detect Tencent SILK (\x02 prefix) in audio magic bytes to avoid ffmpeg failure QQ official bot sends voice in Tencent SILK format (leading \x02 byte before #!SILK_V3 magic). _get_audio_magic_type() had two off-by-one slice errors: 1. Standard SILK: header[:8] vs b'#!SILK_V3' (8 != 9 bytes) — never matched 2. Tencent SILK: not detected at all Fixes: - Standard SILK: header[:9] == b'#!SILK_V3' (correct 9-byte slice) - Tencent SILK: header[:1] == b"\x02" and header[1:10] == b'#!SILK_V3' - ensure_wav() routes detected silk to tencent_silk_to_wav() Before: QQ voice → ffmpeg → 'Invalid data found' After: QQ voice → magic detects silk → tencent_silk_to_wav → WAV OK * refactor: use startswith() for SILK magic byte detection Replace manual slice comparisons with startswith() — cleaner, less error-prone, and immune to off-by-one slice errors. Suggested by: sourcery-ai
1 parent c88025c commit 871b932

1 file changed

Lines changed: 15 additions & 2 deletions

File tree

astrbot/core/utils/media_utils.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
from astrbot import logger
1717
from astrbot.core.utils.astrbot_path import get_astrbot_temp_path
18+
from astrbot.core.utils.tencent_record_helper import tencent_silk_to_wav
1819

1920
IMAGE_COMPRESS_DEFAULT_MAX_SIZE = 1280
2021
IMAGE_COMPRESS_DEFAULT_QUALITY = 95
@@ -250,9 +251,17 @@ async def ensure_wav(audio_path: str, output_path: str | None = None) -> str:
250251
if not audio_path:
251252
return audio_path
252253

253-
if _get_audio_magic_type(audio_path) == "wav":
254+
audio_type = _get_audio_magic_type(audio_path)
255+
if audio_type == "wav":
254256
return audio_path
255257

258+
if audio_type == "silk":
259+
if output_path is None:
260+
temp_dir = get_astrbot_temp_path()
261+
os.makedirs(temp_dir, exist_ok=True)
262+
output_path = os.path.join(temp_dir, f"media_audio_{uuid.uuid4().hex}.wav")
263+
return await tencent_silk_to_wav(audio_path, output_path)
264+
256265
return await convert_audio_to_wav(audio_path, output_path)
257266

258267

@@ -291,7 +300,11 @@ def _get_audio_magic_type(audio_path: str) -> str:
291300
if header[:4] == b"ftyp" and b"mp4" in header[:8]:
292301
return "mp4"
293302

294-
if header[:8] == b"#!SILK_V3":
303+
if header.startswith(b"#!SILK_V3"):
304+
return "silk"
305+
306+
# Tencent SILK: leading \x02 byte before #!SILK_V3
307+
if header.startswith(b"\x02#!SILK_V3"):
295308
return "silk"
296309

297310
return ""

0 commit comments

Comments
 (0)