Files
blind/audio/inject_narrateAudio.py
T
xsl 866f363591 项目整理:重写主文档、归档过时文档、清理死代码、新增音频制作手册
文档整理:
- 重写 game/操作说明.md 为项目主文档(6游戏/6手势/旁白/模型生成音频/TTS两步流程)
- 归档过时文档至 other_docs/(林夏原始设计、旧执行文档)
- 新增 docs/音频制作执行手册.md(从零制作游戏音频的完整流程)
- docs/ 下保留旁白音色提示词、音频脚本

代码清理:
- 删除旧架构死代码: story.js / gestures.js / profile.js
- 删除耦合旧架构的过时测试目录 game/tests/

脚本配置修正:
- check_tts_env.sh: 启动脚本路径 AutoVideo → tts-server(实际位置)
- gen_narrator_samples.py: 硬编码地址改为环境变量,默认对齐 tts-server 端口 8000
2026-06-19 22:29:04 +08:00

96 lines
3.4 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.
#!/usr/bin/env python3
"""
为各游戏脚本注入 narrateAudio 字段
用法:
python audio/inject_narrateAudio.py --game shouye --dry-run
python audio/inject_narrateAudio.py --game shouye
说明:
扫描 audio/mp3/narrator/{game_id}/ 目录下已生成的 MP3
打印出对应游戏脚本中应添加的 narrateAudio 字段。
由于游戏脚本结构各异,本脚本只做"报告",不直接修改 JS 文件。
输出示例(复制粘贴到对应 scene 对象中):
s01: {
narrateAudio: '../audio/mp3/narrator/shouye/shouye_s01_narrate.mp3',
narrate: '...', // 保留原文作 TTS 兜底
...
}
"""
import os
import argparse
import glob
PROJECT_DIR = "/home/xsl/blind"
NARRATOR_DIR = os.path.join(PROJECT_DIR, "audio", "mp3", "narrator")
# 相对于 game/js/games/{game}.js 的音频路径
AUDIO_REL = "../../audio/mp3/narrator"
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--game", required=True,
help="游戏 ID (linxia/yinian/shouye/houzhen/yisheng/fu)")
parser.add_argument("--dry-run", action="store_true",
help="只列出可用文件,不输出注入建议")
args = parser.parse_args()
game_dir = os.path.join(NARRATOR_DIR, args.game)
if not os.path.isdir(game_dir):
print(f"[错误] 目录不存在: {game_dir}")
print(f"请先运行 batch_narrator_tts.py 生成音频。")
return
files = sorted(glob.glob(os.path.join(game_dir, "*.mp3")))
if not files:
print(f"[空] {game_dir}/ 中没有 MP3 文件。")
return
print(f"\n已生成的 {args.game} 旁白音频 ({len(files)} 条):\n")
if args.dry_run:
for f in files:
print(f" {os.path.basename(f)}")
return
print("// ── 将以下 narrateAudio 字段添加到对应 scene/action 对象中 ──")
print("// (保留 narrate 文字作 TTS 兜底;有了 narrateAudio 后引擎会优先播放文件)\n")
for f in files:
name = os.path.basename(f) # e.g. shouye_s01_narrate.mp3
stem = name[:-4] # e.g. shouye_s01_narrate
# 推断 scene/action key
parts = stem.split("_") # ['shouye', 's01', 'narrate']
rel_path = f"{AUDIO_REL}/{args.game}/{name}"
# 判断类型
if parts[-1] == "narrate" or parts[-1].startswith("narrate"):
field = "narrateAudio"
note = f"// → scene {parts[1]}"
elif parts[-1] == "tap" or parts[-1].startswith("tap"):
field = "narrateAudio"
note = f"// → scene {parts[1]} / tap"
elif parts[-1] == "dt":
field = "narrateAudio"
note = f"// → scene {parts[1]} / doubleTap"
elif parts[-1] == "intro":
field = "// game.introAudio"
note = "// → game 对象 intro 字段(engine.run 中用 narrateAudio 处理)"
elif "ending" in parts:
ending_id = "_".join(parts[parts.index("ending"):])
field = "narrateAudio"
note = f"// → endings.{ending_id.replace('ending_', '')} 对象"
else:
field = "narrateAudio"
note = ""
print(f" {field}: '{rel_path}', {note}")
print("\n// 提示:intro 的 narrateAudio 需在 engine.run() 里单独处理,")
print("// 或在 game 对象中加 introAudio 字段并在 engine 中检查。")
if __name__ == "__main__":
main()