This commit is contained in:
2025-05-10 08:39:55 +08:00
parent 3c5b23f4a5
commit ac3c1e79a9
4 changed files with 174 additions and 0 deletions

26
ab2png.py Normal file
View File

@@ -0,0 +1,26 @@
import UnityPy
from PIL import Image
def convert_ab_to_png(assetbundle_path, output_png_path):
env = UnityPy.load(assetbundle_path)
for obj in env.objects:
if obj.type == 28: # ClassID 28 = Texture2D
texture2d = obj.read()
image = texture2d.image
image.save(output_png_path)
print(f"已提取 Texture2D 并保存到 {output_png_path}")
return
raise Exception("AssetBundle 中没有找到 Texture2D。")
# 示例用法
if __name__ == "__main__":
import sys
if len(sys.argv) != 3:
print("用法: python ab2png.py 输入.ab 输出.png")
else:
convert_ab_to_png(sys.argv[1], sys.argv[2])

53
acb2mp3.py Normal file
View File

@@ -0,0 +1,53 @@
import os
import sys
from pathlib import Path
from subprocess import run
from loguru import logger
# 设置工作目录
WORK_DIR = Path("work/audio")
# 确保工作目录存在
WORK_DIR.mkdir(parents=True, exist_ok=True)
def convert_awb_to_wav(awb, output_wav):
"""使用 vgmstream-cli 将 AWB 文件转换为 WAV 文件"""
run(["vgmstream-cli","-o",output_wav,awb])
def convert_wav_to_mp3(wav, output_mp3):
"""使用 ffmpeg 将 WAV 文件转换为 MP3 文件"""
run(["ffmpeg", "-i", wav, f"{output_mp3}"])
if __name__ == "__main__":
if len(sys.argv) < 3:
logger.info("用法: python acb2mp3.py 输入文件 输出文件")
sys.exit(1)
input_file = sys.argv[1]
output_file = sys.argv[2]
# 获取输入文件的扩展名
input_path = Path(input_file)
output_path = Path(output_file)
# 判断输入文件是否是 .acb 文件
if input_path.suffix.lower() == ".acb":
# 假设输入文件关联的 .awb 文件在同一目录下
awb_file = input_path.with_suffix(".awb")
logger.info(awb_file)
if awb_file.exists():
# 将 .awb 转换为 WAV
wav_file = WORK_DIR / "output.wav"
convert_awb_to_wav(str(awb_file), str(wav_file))
logger.info(f"AWB 转换成功,生成文件: {wav_file}")
# 将 WAV 转换为 MP3
mp3_file = output_path.with_suffix(".mp3")
convert_wav_to_mp3(str(wav_file), str(mp3_file))
logger.info(f"WAV 转换为 MP3 成功,生成文件: {mp3_file}")
else:
logger.error(f"未找到对应的 AWB 文件: {awb_file}")
else:
logger.error(f"输入文件不是 .acb 文件: {input_path}")

0
getchart.py Normal file
View File

95
search.py Normal file
View File

@@ -0,0 +1,95 @@
import os
from ReadOpt import parse_music_xml, level_name
# 根目录
streaming_assets = "/Users/bennett/Downloads/SDEZ/Package/Sinmai_Data/StreamingAssets"
def search_music_by_id(search_id):
for asset_dir in os.listdir(streaming_assets):
root_dir = os.path.join(streaming_assets, asset_dir)
music_dir = os.path.join(root_dir, "music")
if not os.path.isdir(music_dir):
continue
for music_subdir in os.listdir(music_dir):
sub_path = os.path.join(music_dir, music_subdir)
music_xml_path = os.path.join(sub_path, "Music.xml")
if not os.path.isfile(music_xml_path):
continue
music_id, name, artist, notes = parse_music_xml(music_xml_path)
if music_id == search_id:
print(f"\n【找到曲目:{name}")
print(f" ID{music_id}")
print(f" 艺术家:{artist}")
print(f" 所在分区:{asset_dir}")
print(" 谱面信息:")
for i, note in enumerate(notes):
level_str = level_name[i] if i < len(level_name) else f"Diff{i}"
print(f" - {level_str}: 定数 {note['level']} / 显示 {note['levelshow']} / 谱师 {note['designer']}")
# ma2 文件
ma2_files = [f for f in os.listdir(sub_path) if f.endswith(".ma2")]
ma2_paths = [os.path.join(sub_path, f) for f in ma2_files]
if ma2_files:
print(" MA2 文件:")
for f in ma2_files:
print(f" - {os.path.join(sub_path, f)}")
else:
print(" MA2 文件:未找到")
# 曲绘(查 jacket 文件夹)
jacket_dir = os.path.join(root_dir, "AssetBundleImages", "jacket")
jacket_ab = f"ui_jacket_00{int(music_id)-10000}.ab"
alt_exts = [".png", ".jpg", ".jpeg"]
alt_jacket = next((f for f in os.listdir(jacket_dir)
if f.startswith(f"ui_jacket_{music_id}")
and os.path.splitext(f)[1].lower() in alt_exts), None)
print(" 曲绘文件:")
if os.path.exists(os.path.join(jacket_dir, jacket_ab)):
print(f" - {os.path.join(jacket_dir, jacket_ab)}")
elif alt_jacket:
print(f" - {os.path.join(jacket_dir, alt_jacket)}")
else:
print(" - 未找到")
# 音频文件SoundData
sound_dir = os.path.join(root_dir, "SoundData")
audio_prefix = f"music00{int(music_id)-10000}"
audio_files = [f for f in os.listdir(sound_dir) if f.lower().startswith(audio_prefix)]
print(" 音频文件:")
if audio_files:
for f in audio_files:
print(f" - {os.path.join(sound_dir, f)}")
else:
print(" - 未找到")
audio_lists = []
for f in audio_files:
audio_lists.append(os.path.join(sound_dir, f))
# 视频 dat 文件MovieData
movie_dir = os.path.join(root_dir, "MovieData")
dat_name = f"00{int(music_id)-10000}.dat"
dat_path = os.path.join(movie_dir, dat_name)
print(" 视频 DAT 文件:")
print(f" - {dat_path}" if os.path.exists(dat_path) else " - 未找到")
return [[music_id, name, artist,notes],ma2_paths,os.path.join(jacket_dir, jacket_ab),audio_lists,dat_path]
print(f"\n未找到 ID 为 {search_id} 的曲目信息。")
return None
if __name__ == "__main__":
target_id = input("请输入要搜索的曲目 ID").strip()
result = search_music_by_id(target_id)
print(result)