mirror of
https://gitea.pjck.top/Cookies/CookiesChartConverter.git
synced 2025-12-14 12:56:54 +08:00
修改 无pv不输出 修改 44100Hz
This commit is contained in:
@@ -15,9 +15,10 @@ def convert_awb_to_wav(awb, output_wav):
|
|||||||
run(["vgmstream-cli","-o",output_wav,awb])
|
run(["vgmstream-cli","-o",output_wav,awb])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def convert_wav_to_mp3(wav, output_mp3):
|
def convert_wav_to_mp3(wav, output_mp3):
|
||||||
"""使用 ffmpeg 将 WAV 文件转换为 MP3 文件"""
|
"""使用 ffmpeg 将 WAV 文件转换为 44100Hz 的 MP3 文件"""
|
||||||
run(["ffmpeg", "-i", wav, f"{output_mp3}"])
|
run(["ffmpeg", "-y", "-i", wav, "-ar", "44100", output_mp3])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
52
convert.py
52
convert.py
@@ -14,32 +14,33 @@ def build_maidata_txt(
|
|||||||
title: str = "",
|
title: str = "",
|
||||||
freemsg: str = "",
|
freemsg: str = "",
|
||||||
bpm: str = "",
|
bpm: str = "",
|
||||||
first_notes: dict = None, # {1: 0.123, 2: ..., ...}
|
first_notes: dict = None, # {2: 0.123, 3: ..., ...}
|
||||||
levels: dict = None, # {1: "3", 2: "5", ...}
|
levels: dict = None, # {2: "3", 3: "5", ...}
|
||||||
designers: dict = None, # {1: "作者A", 2: ..., ...}
|
designers: dict = None, # {2: "作者A", 3: ..., ...}
|
||||||
charts: dict = None, # {1: "谱面数据\n...", ...},
|
charts: dict = None, # {2: "谱面数据\n...", ...}
|
||||||
levelnum: int = None,
|
levelnum: int = None,
|
||||||
) -> str:
|
) -> str:
|
||||||
maidata = [f"&title={title}", f"&freemsg={freemsg}", f"&wholebpm={bpm}", "&first=0"]
|
# 限制 levelnum 在 [2, 6]
|
||||||
|
levelnum = max(2, min(levelnum, 6))
|
||||||
|
|
||||||
# 1~6 难度
|
maidata = [
|
||||||
for i in range(1, levelnum+1):
|
f"&title={title}",
|
||||||
|
f"&artist={freemsg}",
|
||||||
|
f"&wholebpm={bpm}",
|
||||||
|
"&first=0"
|
||||||
|
]
|
||||||
|
|
||||||
|
for i in range(2, levelnum + 2):
|
||||||
first = f"{first_notes.get(i):.3f}" if first_notes and i in first_notes else ""
|
first = f"{first_notes.get(i):.3f}" if first_notes and i in first_notes else ""
|
||||||
lv = levels.get(i, "") if levels else ""
|
|
||||||
des = designers.get(i, "") if designers else ""
|
|
||||||
chart = charts.get(i, "") if charts else ""
|
|
||||||
|
|
||||||
maidata.append(f"&first_{i}={first}")
|
maidata.append(f"&first_{i}={first}")
|
||||||
|
|
||||||
|
for i in range(2, levelnum + 2):
|
||||||
|
|
||||||
for i in range(2, levelnum+1):
|
|
||||||
lv = levels.get(i, "") if levels else ""
|
lv = levels.get(i, "") if levels else ""
|
||||||
des = designers.get(i, "") if designers else ""
|
des = designers.get(i, "") if designers else ""
|
||||||
maidata.append(f"&lv_{i}={lv}")
|
maidata.append(f"&lv_{i}={lv}")
|
||||||
maidata.append(f"&des_{i}={des}")
|
maidata.append(f"&des_{i}={des}")
|
||||||
|
|
||||||
for i in range(2, levelnum):
|
for i in range(2, levelnum + 2):
|
||||||
chart = charts.get(i, "") if charts else ""
|
chart = charts.get(i, "") if charts else ""
|
||||||
maidata.append(f"&inote_{i}=")
|
maidata.append(f"&inote_{i}=")
|
||||||
maidata.append(chart.strip())
|
maidata.append(chart.strip())
|
||||||
@@ -50,6 +51,7 @@ def build_maidata_txt(
|
|||||||
return "\n".join(maidata)
|
return "\n".join(maidata)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def convert_to_simai_folder(result,output_folder):
|
def convert_to_simai_folder(result,output_folder):
|
||||||
npof = output_folder
|
npof = output_folder
|
||||||
output_folder = Path(output_folder)
|
output_folder = Path(output_folder)
|
||||||
@@ -61,17 +63,24 @@ def convert_to_simai_folder(result,output_folder):
|
|||||||
os.makedirs(of)
|
os.makedirs(of)
|
||||||
name = info[1]
|
name = info[1]
|
||||||
artist = info[2]
|
artist = info[2]
|
||||||
designers = {i + 1: item["designer"] for i, item in enumerate(info[3])}
|
designers = {i + 2: item["designer"] for i, item in enumerate(info[3])}
|
||||||
levels = {i + 1: item["levelshow"] for i, item in enumerate(info[3])}
|
levels = {i + 2: item["levelshow"] for i, item in enumerate(info[3])}
|
||||||
ma2_list = result[1]
|
ma2_list = result[1]
|
||||||
ab_file = result[2]
|
ab_file = result[2]
|
||||||
acb_list = result[3]
|
acb_list = result[3]
|
||||||
|
awb_file = next((f for f in acb_list if f.endswith('.awb')), None)
|
||||||
dat_file = result[4]
|
dat_file = result[4]
|
||||||
convert_results = {}
|
convert_results = {}
|
||||||
for mai in ma2_list:
|
for path in ma2_list:
|
||||||
convert_results.update({ma2_list.index(mai)+1: ma2tosimai(mai)})
|
filename = os.path.basename(path)
|
||||||
|
try:
|
||||||
|
num = int(filename[-6:-4]) # 提取 _00 → 0
|
||||||
|
level = num + 2 # 转换为 Simai 难度等级
|
||||||
|
convert_results[level] = ma2tosimai(path)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"处理 {filename} 时出错: {e}")
|
||||||
|
|
||||||
convert_awb_to_wav(acb_list[1],f"work/{id}/temp.wav")
|
convert_awb_to_wav(awb_file,f"work/{id}/temp.wav")
|
||||||
convert_wav_to_mp3(f"work/{id}/temp.wav",f"work/{id}/track.mp3")
|
convert_wav_to_mp3(f"work/{id}/temp.wav",f"work/{id}/track.mp3")
|
||||||
|
|
||||||
convert_ab_to_png(ab_file,f"work/{id}/bg.png")
|
convert_ab_to_png(ab_file,f"work/{id}/bg.png")
|
||||||
@@ -102,6 +111,7 @@ def convert_to_simai_folder(result,output_folder):
|
|||||||
else:
|
else:
|
||||||
print(f"文件 {file_name} 不存在,跳过复制")
|
print(f"文件 {file_name} 不存在,跳过复制")
|
||||||
|
|
||||||
|
|
||||||
if os.path.exists(source_folder):
|
if os.path.exists(source_folder):
|
||||||
shutil.rmtree(source_folder)
|
shutil.rmtree(source_folder)
|
||||||
|
|
||||||
@@ -119,8 +129,6 @@ def convert_to_simai_folder(result,output_folder):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# 示例调用
|
# 示例调用
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
23
pv_decode.py
23
pv_decode.py
@@ -20,6 +20,23 @@ def convert_ivf_to_mp4(ivf_path: Path, output_mp4_path: Path):
|
|||||||
str(output_mp4_path)
|
str(output_mp4_path)
|
||||||
], check=True)
|
], check=True)
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
def get_video_duration(path: Path) -> float:
|
||||||
|
"""使用 ffprobe 获取视频时长(单位:秒)"""
|
||||||
|
try:
|
||||||
|
result = subprocess.run(
|
||||||
|
["ffprobe", "-v", "error", "-show_entries", "format=duration",
|
||||||
|
"-of", "default=noprint_wrappers=1:nokey=1", str(path)],
|
||||||
|
stdout=subprocess.PIPE,
|
||||||
|
stderr=subprocess.STDOUT,
|
||||||
|
text=True
|
||||||
|
)
|
||||||
|
return float(result.stdout.strip())
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取视频时长失败: {e}")
|
||||||
|
return 0.0
|
||||||
|
|
||||||
def dat_to_mp4(dat_file: str, id: str):
|
def dat_to_mp4(dat_file: str, id: str):
|
||||||
""" 将 .dat 文件当作 .usm 文件处理,提取并转换为 .mp4 """
|
""" 将 .dat 文件当作 .usm 文件处理,提取并转换为 .mp4 """
|
||||||
dat_path = Path(dat_file).resolve()
|
dat_path = Path(dat_file).resolve()
|
||||||
@@ -41,10 +58,16 @@ def dat_to_mp4(dat_file: str,id:str):
|
|||||||
print(f"[2/3] 转换为 MP4 ...")
|
print(f"[2/3] 转换为 MP4 ...")
|
||||||
convert_ivf_to_mp4(ivf_path, mp4_path)
|
convert_ivf_to_mp4(ivf_path, mp4_path)
|
||||||
|
|
||||||
|
duration = get_video_duration(mp4_path)
|
||||||
|
if duration < 1.0:
|
||||||
|
print(f"⚠️ 视频时长 {duration:.2f}s 太短,跳过生成 pv.mp4")
|
||||||
|
return None
|
||||||
|
|
||||||
print(f"[3/3] 成功生成:{mp4_path}")
|
print(f"[3/3] 成功生成:{mp4_path}")
|
||||||
process_video(mp4_path, work_dir / "pv.mp4")
|
process_video(mp4_path, work_dir / "pv.mp4")
|
||||||
return mp4_path
|
return mp4_path
|
||||||
|
|
||||||
|
|
||||||
# === 示例用法 ===
|
# === 示例用法 ===
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
import sys
|
import sys
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ def search_music_by_id(search_id):
|
|||||||
# ma2 文件
|
# ma2 文件
|
||||||
ma2_files = [f for f in os.listdir(sub_path) if f.endswith(".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]
|
ma2_paths = [os.path.join(sub_path, f) for f in ma2_files]
|
||||||
|
ma2_paths.sort()
|
||||||
if ma2_files:
|
if ma2_files:
|
||||||
print(" MA2 文件:")
|
print(" MA2 文件:")
|
||||||
for f in ma2_files:
|
for f in ma2_files:
|
||||||
|
|||||||
Reference in New Issue
Block a user