Files
audio2text/app/services/asr_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

66 lines
2.0 KiB
Python
Raw 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.

"""语音识别服务faster-whisper输出带词级时间戳的 segments。
CPU dev: tiny.en + int8GPU prod: large-v3-turbo + float16。同一份代码。
"""
from __future__ import annotations
import logging
from pathlib import Path
from ..config import get_settings
from .model_manager import get_model_manager
from .types import Segment, Word
logger = logging.getLogger("audio2text.asr")
def transcribe(wav_path: Path) -> list[Segment]:
"""转写 wav返回 segments含词级时间戳
Args:
wav_path: 16kHz mono PCM wav
Returns:
list[Segment],每个 Segment 带词级 words若 word_timestamps 启用)。
"""
s = get_settings().asr
if not wav_path.is_file():
raise FileNotFoundError(f"音频不存在:{wav_path}")
model = get_model_manager().get_asr()
logger.debug("开始转写 %smodel=%s language=%s", wav_path.name, s.model, s.language)
segments_gen, info = model.transcribe(
str(wav_path),
language=s.language,
word_timestamps=s.word_timestamps,
vad_filter=s.vad_filter,
beam_size=5,
)
logger.debug(
"音频时长 %.1fs检测语言=%s(置信度 %.2f",
info.duration, info.language, info.language_probability,
)
segments: list[Segment] = []
for seg in segments_gen:
words: list[Word] = []
if s.word_timestamps and getattr(seg, "words", None):
for w in seg.words:
words.append(Word(
text=w.word.strip(),
start=float(w.start),
end=float(w.end),
probability=float(getattr(w, "probability", 1.0)),
))
segments.append(Segment(
text=seg.text.strip(),
start=float(seg.start),
end=float(seg.end),
words=words,
))
logger.debug("转写完成:%d 段,%d 词。",
len(segments), sum(len(s.words) for s in segments))
return segments