34 lines
1.2 KiB
Python
34 lines
1.2 KiB
Python
"""Декодирование сжатого аудио (mp3/ogg/...) в float32.
|
|
|
|
Использует PyAV — ffmpeg-библиотеки вкомпилированы в пакет av
|
|
(он уже есть как зависимость faster-whisper), системный ffmpeg не нужен.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import io
|
|
from typing import Tuple
|
|
|
|
import av
|
|
import numpy as np
|
|
|
|
|
|
def decode_audio_bytes(data: bytes) -> Tuple[np.ndarray, int]:
|
|
"""Байты аудиофайла → (float32 mono [-1..1], samplerate)."""
|
|
container = av.open(io.BytesIO(data))
|
|
try:
|
|
stream = container.streams.audio[0]
|
|
samplerate = int(stream.rate)
|
|
resampler = av.AudioResampler(format="flt", layout="mono")
|
|
pieces = []
|
|
for frame in container.decode(stream):
|
|
for out in resampler.resample(frame):
|
|
arr = out.to_ndarray()
|
|
if arr.ndim == 2: # (channels, samples) → mono
|
|
arr = arr[0] if arr.shape[0] == 1 else arr.mean(axis=0)
|
|
pieces.append(np.asarray(arr, dtype=np.float32))
|
|
finally:
|
|
container.close()
|
|
|
|
if not pieces:
|
|
return np.zeros(0, dtype=np.float32), samplerate
|
|
return np.concatenate(pieces), samplerate |