Files
audio2text/app/services/ffmpeg_service.py
zikai 00e2a95fb7 Initial commit: audio2text 双语字幕生成服务
- 音频/视频转双语(英/中)SRT 字幕,Docker 容器化,CPU 开发/GPU 生产同一份代码
- faster-whisper ASR(词级时间戳) + 断句时间戳重算 + NLLB 翻译(模型不共驻)
- 分片上传(断点续传) + SQLite 持久化 + 主页/历史/日志页面
- 历史页文件名搜索;缓存定时清理(默认保留7天,可配置)
- 双 Dockerfile(cpu/gpu) + setup/start/stop 脚本
2026-07-06 06:54:19 +00:00

65 lines
1.9 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""ffmpeg 服务:从视频/音频文件提取 16kHz 单声道 PCM wav。
16kHz mono PCM 正是 Whisper 的标准输入,省去模型内重采样。
"""
from __future__ import annotations
import logging
import shutil
import subprocess
from pathlib import Path
logger = logging.getLogger("audio2text.ffmpeg")
class FFmpegError(RuntimeError):
pass
def extract_audio(
src: Path,
out_wav: Path,
sample_rate: int = 16000,
) -> Path:
"""提取音频为 16kHz 单声道 PCM wav。
Args:
src: 输入视频/音频文件
out_wav: 输出 wav 路径
sample_rate: 采样率,默认 16000Whisper 标准)
Returns:
out_wav 路径
Raises:
FFmpegError: ffmpeg 不可用或提取失败
"""
if shutil.which("ffmpeg") is None:
raise FFmpegError("ffmpeg 未安装;容器内应通过 apt 装好。")
if not src.is_file():
raise FFmpegError(f"源文件不存在:{src}")
out_wav.parent.mkdir(parents=True, exist_ok=True)
# -vn 去视频;-ac 1 单声道;-ar 16k 采样率;-c:a pcm_s16le 16bit PCM
cmd = [
"ffmpeg", "-y", "-loglevel", "error",
"-i", str(src),
"-vn", "-ac", "1", "-ar", str(sample_rate),
"-c:a", "pcm_s16le",
str(out_wav),
]
logger.debug("提取音频:%s -> %s", src.name, out_wav.name)
logger.debug("ffmpeg 命令:%s", " ".join(cmd))
try:
result = subprocess.run(cmd, capture_output=True, text=True, timeout=3600)
except subprocess.TimeoutExpired as exc:
raise FFmpegError(f"ffmpeg 超时(>1h{src}") from exc
if result.returncode != 0:
raise FFmpegError(
f"ffmpeg 失败 (code={result.returncode}): {result.stderr.strip()[:500]}"
)
if not out_wav.is_file():
raise FFmpegError(f"ffmpeg 未生成输出文件:{out_wav}")
return out_wav