diff --git a/Json/download_config_CN.json b/Json/download_config_CN.json index f8a8455..5fda8a4 100644 --- a/Json/download_config_CN.json +++ b/Json/download_config_CN.json @@ -1,15 +1,15 @@ { "version": "1.0.8610", "vol.1.data": { - "url": "https://down-cdn.lolicon.team/hosting_file/NEKOPARA/vol.1.7z" + "url": "https://down-cdn.ovofish.com/hosting_file/NEKOPARA/vol.1.7z" }, "vol.2.data": { - "url": "https://down-cdn.lolicon.team/hosting_file/NEKOPARA/vol.2.7z" + "url": "https://down-cdn.ovofish.com/hosting_file/NEKOPARA/vol.2.7z" }, "vol.3.data": { - "url": "https://down-cdn.lolicon.team/hosting_file/NEKOPARA/vol.3.7z" + "url": "https://down-cdn.ovofish.com/hosting_file/NEKOPARA/vol.3.7z" }, "vol.4.data": { - "url": "https://down-cdn.lolicon.team/hosting_file/NEKOPARA/vol.4.7z" + "url": "https://down-cdn.ovofish.com/hosting_file/NEKOPARA/vol.4.7z" } } diff --git a/Python/wav_flac_music/Readme.md b/Python/wav_flac_music/Readme.md index b8cd619..16946c4 100644 --- a/Python/wav_flac_music/Readme.md +++ b/Python/wav_flac_music/Readme.md @@ -9,5 +9,6 @@ 运行前请先安装依赖库 ``` -pip install pydub mutagen eyed3 +pip install pydub mutagen eyed3 +pyinstaller -i ./q.ico --onefile --version-file version_info.rc main.py ``` diff --git a/Python/wav_flac_music/main.py b/Python/wav_flac_music/main.py index 8d5dca8..b7fc3c9 100644 --- a/Python/wav_flac_music/main.py +++ b/Python/wav_flac_music/main.py @@ -1,71 +1,106 @@ import os +import time from pydub import AudioSegment import eyed3 from mutagen.flac import FLAC +from concurrent.futures import ThreadPoolExecutor + +def safe_remove(file_path, max_retries=3): + """安全删除文件,带有重试机制""" + for i in range(max_retries): + try: + os.remove(file_path) + return True + except PermissionError: + time.sleep(0.1 * (i+1)) + return False + +def convert_sample_width(audio): + """处理非常规sample width""" + try: + if audio.sample_width not in [1, 2, 3, 4]: + return audio.set_sample_width(2) + return audio + except Exception as e: + print(f"采样位数修复失败: {str(e)}") + return None def convert_and_clean(wav_path): + flac_path = None try: - # 增强版元数据读取 + audio = AudioSegment.from_file(wav_path, format='wav') + audio = convert_sample_width(audio) + if audio is None: + raise ValueError("不支持的音频格式") + tags = {} - audiofile = eyed3.load(wav_path) - - # 处理无标签文件 - if audiofile is not None and audiofile.tag is not None: - tags = { - 'ARTIST': audiofile.tag.artist or '', - 'ALBUM': audiofile.tag.album or '', - 'TITLE': audiofile.tag.title or '', - 'GENRE': audiofile.tag.genre.name if audiofile.tag.genre else '', - 'DATE': str(audiofile.tag.getBestDate()) or '', - 'TRACKNUMBER': str(audiofile.tag.track_num[0]) if audiofile.tag.track_num else '' - } - else: - # 从文件名提取基础信息 - filename = os.path.basename(wav_path) - base_info = os.path.splitext(filename)[0].split('-', 1) - if len(base_info) > 1: - tags['ARTIST'] = base_info[0].strip() - tags['TITLE'] = base_info[1].strip() + try: + audiofile = eyed3.load(wav_path) + if audiofile and audiofile.tag: + tags = { + 'ARTIST': audiofile.tag.artist or '', + 'ALBUM': audiofile.tag.album or '', + 'TITLE': audiofile.tag.title or '', + 'GENRE': audiofile.tag.genre.name if audiofile.tag.genre else '', + 'DATE': str(audiofile.tag.getBestDate()) or '', + 'TRACKNUMBER': str(audiofile.tag.track_num[0]) if audiofile.tag.track_num else '' + } + except Exception as e: + print(f"元数据读取警告: {str(e)}") - # 转换音频格式 flac_path = os.path.splitext(wav_path)[0] + '.flac' - AudioSegment.from_wav(wav_path).export(flac_path, format='flac') + + with open(flac_path, 'wb') as f: + audio.export(f, format='flac') - # 写入FLAC元数据 if tags: flac_audio = FLAC(flac_path) flac_audio.delete() flac_audio.update(tags) flac_audio.save() - # 安全删除验证 if os.path.exists(flac_path) and os.path.getsize(flac_path) > 0: - os.remove(wav_path) - print(f"成功转换并删除: {wav_path}") - return True + if safe_remove(wav_path): + print(f"成功转换并删除: {wav_path}") + return True return False except Exception as e: print(f"处理失败 {wav_path}: {str(e)}") - if 'flac_path' in locals() and os.path.exists(flac_path): - os.remove(flac_path) + if flac_path and os.path.exists(flac_path): + safe_remove(flac_path) return False def batch_convert(): deleted_count = 0 error_count = 0 - for root, _, files in os.walk('.'): - for file in files: - if file.lower().endswith('.wav'): - full_path = os.path.join(root, file) - if convert_and_clean(full_path): + # 自动根据CPU核心数设置线程数(核心数*2) + max_workers = os.cpu_count() * 2 or 4 + + with ThreadPoolExecutor(max_workers=max_workers) as executor: + futures = [] + for root, _, files in os.walk('.'): + for file in files: + if file.lower().endswith('.wav'): + full_path = os.path.join(root, file) + futures.append(executor.submit(convert_and_clean, full_path)) + + for future in futures: + try: + if future.result(): deleted_count += 1 else: error_count += 1 + except Exception as e: + print(f"线程执行出错: {str(e)}") + error_count += 1 print(f"\n转换总结:\n成功转换并删除: {deleted_count} 个文件\n失败文件: {error_count} 个") if __name__ == "__main__": print("=== WAV转FLAC工具 (增强安全版) ===") - batch_convert() \ No newline at end of file + print(f"当前CPU核心数: {os.cpu_count()}") + print("开始批量转换...\n") + batch_convert() + input("\n按任意键退出...") \ No newline at end of file diff --git a/Python/wav_flac_music/q.ico b/Python/wav_flac_music/q.ico new file mode 100644 index 0000000..64f857e Binary files /dev/null and b/Python/wav_flac_music/q.ico differ diff --git a/Python/wav_flac_music/version_info.rc b/Python/wav_flac_music/version_info.rc new file mode 100644 index 0000000..18e89e9 --- /dev/null +++ b/Python/wav_flac_music/version_info.rc @@ -0,0 +1,33 @@ + +VSVersionInfo( + ffi=FixedFileInfo( + filevers=(0, 0, 1, 3), + prodvers=(0, 0, 1, 3), + mask=0x3f, + flags=0x0, + OS=0x40004, + fileType=0x1, + subtype=0x0, + date=(0, 0) + ), + kids=[ + StringFileInfo( + [ + StringTable( + u'040904B0', + [ + StringStruct(u'CompanyName', u'肇庆发呆鱼传媒文化有限公司'), + StringStruct(u'FileDescription', u'wav to flac convert'), + StringStruct(u'FileVersion', u'0.0.1.3'), + StringStruct(u'InternalName', u'Main'), + StringStruct(u'LegalCopyright', u'Copyright (C) 2024'), + StringStruct(u'OriginalFilename', u'BandMusic.exe'), + StringStruct(u'ProductName', u'金牌音乐'), + StringStruct(u'ProductVersion', u'0.0.1.3') + ] + ) + ] + ), + VarFileInfo([VarStruct(u'Translation', [1033, 1200])]) + ] +) \ No newline at end of file