Initial commit: audio2text 双语字幕生成服务
- 音频/视频转双语(英/中)SRT 字幕,Docker 容器化,CPU 开发/GPU 生产同一份代码 - faster-whisper ASR(词级时间戳) + 断句时间戳重算 + NLLB 翻译(模型不共驻) - 分片上传(断点续传) + SQLite 持久化 + 主页/历史/日志页面 - 历史页文件名搜索;缓存定时清理(默认保留7天,可配置) - 双 Dockerfile(cpu/gpu) + setup/start/stop 脚本
This commit is contained in:
68
app/services/srt_writer.py
Normal file
68
app/services/srt_writer.py
Normal file
@@ -0,0 +1,68 @@
|
||||
"""SRT 字幕文件写入与双语合并。"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from .types import Subtitle
|
||||
|
||||
|
||||
def _format_ts(seconds: float) -> str:
|
||||
"""秒 → SRT 时间戳 HH:MM:SS,mmm。"""
|
||||
if seconds < 0:
|
||||
seconds = 0.0
|
||||
ms = int(round((seconds - int(seconds)) * 1000))
|
||||
s = int(seconds) % 60
|
||||
m = (int(seconds) // 60) % 60
|
||||
h = int(seconds) // 3600
|
||||
if ms == 1000: # 四舍五入进位
|
||||
ms = 0
|
||||
s += 1
|
||||
if s == 60:
|
||||
s = 0
|
||||
m += 1
|
||||
if m == 60:
|
||||
m = 0
|
||||
h += 1
|
||||
return f"{h:02d}:{m:02d}:{s:02d},{ms:03d}"
|
||||
|
||||
|
||||
def write_srt(subtitles: list[Subtitle], path: Path) -> Path:
|
||||
"""写单语 SRT。"""
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
lines: list[str] = []
|
||||
for i, sub in enumerate(subtitles, 1):
|
||||
lines.append(str(i))
|
||||
lines.append(f"{_format_ts(sub.start)} --> {_format_ts(sub.end)}")
|
||||
lines.append(sub.text)
|
||||
lines.append("")
|
||||
path.write_text("\n".join(lines), encoding="utf-8")
|
||||
return path
|
||||
|
||||
|
||||
def write_bilingual_srt(
|
||||
en_subs: list[Subtitle],
|
||||
zh_texts: list[str],
|
||||
path: Path,
|
||||
) -> Path:
|
||||
"""写双语合并 SRT:英文在上、中文在下,同一时间戳。
|
||||
|
||||
Args:
|
||||
en_subs: 英文字幕条目
|
||||
zh_texts: 与 en_subs 等长、顺序对应的中文译文
|
||||
path: 输出路径
|
||||
"""
|
||||
if len(en_subs) != len(zh_texts):
|
||||
raise ValueError(
|
||||
f"英文字幕数({len(en_subs)}) 与中文译文数({len(zh_texts)}) 不一致"
|
||||
)
|
||||
path.parent.mkdir(parents=True, exist_ok=True)
|
||||
lines: list[str] = []
|
||||
for i, (sub, zh) in enumerate(zip(en_subs, zh_texts), 1):
|
||||
lines.append(str(i))
|
||||
lines.append(f"{_format_ts(sub.start)} --> {_format_ts(sub.end)}")
|
||||
lines.append(sub.text)
|
||||
lines.append(zh)
|
||||
lines.append("")
|
||||
path.write_text("\n".join(lines), encoding="utf-8")
|
||||
return path
|
||||
Reference in New Issue
Block a user