Files
SoundGame/tools/check_all_assets.py
T

91 lines
3.7 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
# -*- coding: utf-8 -*-
"""全项目音频资产终检(R5)。
检查 8 个游戏 web/<game>/audio/:
1. 每个 .ogg 都有同名 .m4a(反之亦然)
2. voice/male 与 voice/female 的 id 集合一致(storyline/rpg 的平铺 NPC/角色句除外)
3. 无 0 字节文件;ogg/m4a 均可被 ffprobe 解码且时长 > 0
输出 Markdown 报告到 stdout(重定向进 docs/audio/final-asset-check.md)。
"""
import os
import subprocess
import sys
ROOT = "/home/xsl/SoundGame/web"
GAMES = ["storyline", "escape", "simon", "rhythm", "space", "rpg", "radio", "dungeon"]
# 平铺 voice 文件(角色/NPC,单音色,不做性别集合一致性要求)
FLAT_OK = {"storyline", "rpg", "radio"}
def ids(d, ext):
if not os.path.isdir(d):
return set()
return {f[: -len(ext)] for f in os.listdir(d) if f.endswith(ext)}
def main():
problems = []
print("# 全项目音频资产终检(R5 建立,批次 1 起含 radio/dungeon,2026-09-01)\n")
print("| 游戏 | ogg | m4a | 0字节 | 解码失败 | voice male/female id 一致 |")
print("|---|---|---|---|---|---|")
for g in GAMES:
base = os.path.join(ROOT, g, "audio")
oggs, m4as, zero, bad = [], [], [], []
for dirpath, _dirs, files in os.walk(base):
for f in files:
p = os.path.join(dirpath, f)
if os.path.getsize(p) == 0:
zero.append(p)
if f.endswith(".ogg"):
oggs.append(p)
elif f.endswith(".m4a"):
m4as.append(p)
# 双格式配对
o_set = {p[:-4] for p in oggs}
m_set = {p[:-4] for p in m4as}
for p in sorted(o_set - m_set):
problems.append(f"{g}: 缺 m4a —— {p}.ogg")
for p in sorted(m_set - o_set):
problems.append(f"{g}: 缺 ogg —— {p}.m4a")
# 解码校验(抽查全量 ffprobe)
for p in oggs + m4as:
r = subprocess.run(["ffprobe", "-v", "error", "-show_entries", "format=duration",
"-of", "csv=p=0", p], capture_output=True, text=True)
try:
if float(r.stdout.strip()) <= 0:
bad.append(p)
except ValueError:
bad.append(p)
for p in zero:
problems.append(f"{g}: 0 字节 —— {p}")
for p in bad:
problems.append(f"{g}: 解码失败/时长为 0 —— {p}")
# voice 性别集合一致性
vm = ids(os.path.join(base, "voice", "male"), ".ogg")
vf = ids(os.path.join(base, "voice", "female"), ".ogg")
if vm == vf and vm:
pair = f"✅ 各 {len(vm)}"
else:
pair = f"❌ male={len(vm)} female={len(vf)}"
for i in sorted(vm - vf):
problems.append(f"{g}: voice 缺 female/{i}")
for i in sorted(vf - vm):
problems.append(f"{g}: voice 缺 male/{i}")
flat = ids(os.path.join(base, "voice"), ".ogg")
flat_note = f"(平铺 {len(flat)} 个角色/NPC 句,豁免)" if g in FLAT_OK and flat else \
(f"(⚠️ 非豁免游戏存在平铺 {len(flat)} 个)" if flat and g not in FLAT_OK else "")
print(f"| {g} | {len(oggs)} | {len(m4as)} | {len(zero)} | {len(bad)} | {pair}{flat_note} |")
print()
if problems:
print(f"## 问题清单({len(problems)} 条)\n")
for p in problems:
print(f"- {p}")
return 1
print("## 结论\n\n全部通过:双格式配对完整、无 0 字节、全部可解码、voice 性别目录 id 集合一致(storyline/rpg/radio 平铺角色句按约定豁免)。")
return 0
if __name__ == "__main__":
sys.exit(main())