diff --git a/acb2mp3.py b/acb2mp3.py index 8215b8f..24acab9 100644 --- a/acb2mp3.py +++ b/acb2mp3.py @@ -15,9 +15,10 @@ def convert_awb_to_wav(awb, output_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}"]) + """使用 ffmpeg 将 WAV 文件转换为 44100Hz 的 MP3 文件""" + run(["ffmpeg", "-y", "-i", wav, "-ar", "44100", output_mp3]) if __name__ == "__main__": diff --git a/convert.py b/convert.py index de0b1de..bda7c54 100644 --- a/convert.py +++ b/convert.py @@ -11,35 +11,36 @@ from pv_decode import dat_to_mp4 # 假设你已实现以下函数 def build_maidata_txt( - title: str = "", - freemsg: str = "", - bpm: str = "", - first_notes: dict = None, # {1: 0.123, 2: ..., ...} - levels: dict = None, # {1: "3", 2: "5", ...} - designers: dict = None, # {1: "作者A", 2: ..., ...} - charts: dict = None, # {1: "谱面数据\n...", ...}, - levelnum:int = None, + title: str = "", + freemsg: str = "", + bpm: str = "", + first_notes: dict = None, # {2: 0.123, 3: ..., ...} + levels: dict = None, # {2: "3", 3: "5", ...} + designers: dict = None, # {2: "作者A", 3: ..., ...} + charts: dict = None, # {2: "谱面数据\n...", ...} + levelnum: int = None, ) -> str: - maidata = [f"&title={title}", f"&freemsg={freemsg}", f"&wholebpm={bpm}", "&first=0"] + # 限制 levelnum 在 [2, 6] + levelnum = max(2, min(levelnum, 6)) - # 1~6 难度 - for i in range(1, levelnum+1): + maidata = [ + 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 "" - 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}") - - - for i in range(2, levelnum+1): + for i in range(2, levelnum + 2): lv = levels.get(i, "") if levels else "" des = designers.get(i, "") if designers else "" maidata.append(f"&lv_{i}={lv}") 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 "" maidata.append(f"&inote_{i}=") maidata.append(chart.strip()) @@ -50,6 +51,7 @@ def build_maidata_txt( return "\n".join(maidata) + def convert_to_simai_folder(result,output_folder): npof = output_folder output_folder = Path(output_folder) @@ -61,17 +63,24 @@ def convert_to_simai_folder(result,output_folder): os.makedirs(of) name = info[1] artist = info[2] - designers = {i + 1: item["designer"] for i, item in enumerate(info[3])} - levels = {i + 1: item["levelshow"] for i, item in enumerate(info[3])} + designers = {i + 2: item["designer"] for i, item in enumerate(info[3])} + levels = {i + 2: item["levelshow"] for i, item in enumerate(info[3])} ma2_list = result[1] ab_file = result[2] acb_list = result[3] + awb_file = next((f for f in acb_list if f.endswith('.awb')), None) dat_file = result[4] convert_results = {} - for mai in ma2_list: - convert_results.update({ma2_list.index(mai)+1: ma2tosimai(mai)}) + for path in ma2_list: + 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_ab_to_png(ab_file,f"work/{id}/bg.png") @@ -102,6 +111,7 @@ def convert_to_simai_folder(result,output_folder): else: print(f"文件 {file_name} 不存在,跳过复制") + if os.path.exists(source_folder): shutil.rmtree(source_folder) @@ -119,8 +129,6 @@ def convert_to_simai_folder(result,output_folder): - - # 示例调用 if __name__ == "__main__": diff --git a/pv_decode.py b/pv_decode.py index 1947caf..6853dae 100644 --- a/pv_decode.py +++ b/pv_decode.py @@ -20,7 +20,24 @@ def convert_ivf_to_mp4(ivf_path: Path, output_mp4_path: Path): str(output_mp4_path) ], check=True) -def dat_to_mp4(dat_file: str,id:str): +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): """ 将 .dat 文件当作 .usm 文件处理,提取并转换为 .mp4 """ dat_path = Path(dat_file).resolve() base_name = dat_path.stem @@ -41,10 +58,16 @@ def dat_to_mp4(dat_file: str,id:str): print(f"[2/3] 转换为 MP4 ...") 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}") - process_video(mp4_path, work_dir/"pv.mp4") + process_video(mp4_path, work_dir / "pv.mp4") return mp4_path + # === 示例用法 === if __name__ == "__main__": import sys diff --git a/search.py b/search.py index 47015f7..381624e 100644 --- a/search.py +++ b/search.py @@ -31,6 +31,7 @@ def search_music_by_id(search_id): # 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.sort() if ma2_files: print(" MA2 文件:") for f in ma2_files: