This repository has been archived on 2026-08-12. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
Cyrene/scripts/voice/extract_cyrene_animew.py
T
AskaEth 41f653b672 refactor: QQ → OBv11 重命名 + 平台格式统一抽象
- 所有对外称呼从 QQ 改为 OBv11(注释/提示词/日志/配置项)
- 新增 PlatformFormat 结构体,统一管理平台消息标记格式
- defaultPlatformFormats() 注册表替代硬编码 qqTargetRe
- extractProactiveMessage 改为 Thinker 方法,遍历格式注册表匹配
- 配置项重命名: QQ_BOT_PORT → OBV11_BOT_PORT, QQBotPort → OBv11BotPort
- 标记格式: 【QQ群聊】→【OBv11群聊】、【QQ私聊】→【OBv11私聊】

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-22 20:48:07 +08:00

143 lines
4.3 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
"""
使用 AnimeWwise 引擎无头提取昔涟语音。
不需要 GUI,直接调用 extract.py 的核心逻辑。
"""
import os
import sys
# 添加 AnimeWwise 到路径
AWW_DIR = r"D:\Project\Code\Uni\Cyrene-Voice-Model\tools\AnimeWwise"
sys.path.insert(0, AWW_DIR)
os.chdir(AWW_DIR)
from extract import WwiseExtract
# 输入目录
HSR_AUDIO = r"D:\MeowG\HonkaiStar_Rail\StarRail_Data\Persistent\Audio\AudioPackage\Windows\Chinese(PRC)"
OUTPUT_DIR = r"D:\Project\Code\Uni\Cyrene-Voice-Model\data\cyrene_extracted"
MAP_FILE = "hkrpg.map"
print("=" * 60)
print("昔涟语音提取 (AnimeWwise Headless)")
print("=" * 60)
# 1. 初始化提取器
extractor = WwiseExtract()
# 2. 加载映射
print("\n[1/4] 加载角色映射...")
extractor.load_map(MAP_FILE)
# 3. 加载音频文件
print("\n[2/4] 加载 .pck 文件...")
pck_files = sorted([
os.path.join(HSR_AUDIO, f)
for f in os.listdir(HSR_AUDIO)
if f.endswith(".pck") and ("VoBanks" in f or "External_del_3." in f)
])
print(f" 找到 {len(pck_files)} 个目标 .pck 文件")
# 进度回调
def progress(data):
if data[0] == "total":
pct = int(data[1])
if pct % 20 == 0:
print(f" 加载进度: {pct:.0f}%")
file_structure = extractor.load_folder(
_map=MAP_FILE,
files=pck_files,
diff_path="",
base_path=HSR_AUDIO,
progress=progress,
)
# 4. 搜索昔涟
print("\n[3/4] 搜索昔涟语音...")
def search_cyrene(structure, path=""):
"""递归搜索文件结构中包含昔涟相关名称的文件"""
results = []
cyrene_terms = ['cyrene', 'mimi', 'xilian', 'mem', 'de_moi_ge']
# 搜索文件夹
folders = structure.get("folders", {})
for folder_name, folder_content in folders.items():
sub_path = f"{path}/{folder_name}" if path else folder_name
results.extend(search_cyrene(folder_content, sub_path))
# 搜索文件
for file_entry in structure.get("files", []):
file_name = file_entry[0].lower()
file_path = f"{path}/{file_entry[0]}"
for term in cyrene_terms:
if term in file_name or term in file_path.lower():
results.append((path, file_entry[0], file_entry[1]))
break
return results
matches = search_cyrene(file_structure)
print(f" 找到 {len(matches)} 个昔涟相关文件")
if len(matches) == 0:
print("\n 未匹配到昔涟,显示所有顶层目录结构:")
folders = file_structure.get("folders", {})
for name in sorted(folders.keys()):
count = len(folders[name].get("files", []))
# 递归统计
def count_all(s):
total = len(s.get("files", []))
for v in s.get("folders", {}).values():
total += count_all(v)
return total
total = count_all(folders[name])
print(f" {name}/ ({total} files)")
# 也搜一下其他可能的名称
print("\n 搜索所有包含'voice'的路径...")
voice_matches = search_cyrene(file_structure)
# 换个方式搜
def search_all(structure, prefix=""):
for folder_name, folder_content in structure.get("folders", {}).items():
sub = f"{prefix}/{folder_name}" if prefix else folder_name
sub_lower = sub.lower()
if any(t in sub_lower for t in ['voice', 'char', 'npc', 'player', 'avatar']):
print(f" {sub}/")
search_all(folder_content, sub)
search_all(file_structure)
else:
for path, name, meta in matches[:30]:
print(f" {path}/{name}")
# 5. 提取
if matches:
print(f"\n[4/4] 提取 {len(matches)} 个文件到 {OUTPUT_DIR}...")
output_files = []
for path, name, meta in matches:
output_files.append({
"path": path.split("/") if path else [],
"name": name,
"source": meta["source"],
"offset": meta["offset"],
"size": meta["size"],
"original_name": meta["original_name"],
})
extractor.extract_files(
_input=HSR_AUDIO,
files=output_files,
output=OUTPUT_DIR,
_format="wav",
progress=progress,
)
print(f"\n完成!文件保存在 {OUTPUT_DIR}")
else:
print("\n未找到昔涟语音。可能需要用 AnimeWwise GUI 手动浏览文件结构。")
extractor.reset()