106 lines
3.5 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.

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 = {}
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'
with open(flac_path, 'wb') as f:
audio.export(f, format='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:
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 and os.path.exists(flac_path):
safe_remove(flac_path)
return False
def batch_convert():
deleted_count = 0
error_count = 0
# 自动根据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工具 (增强安全版) ===")
print(f"当前CPU核心数: {os.cpu_count()}")
print("开始批量转换...\n")
batch_convert()
input("\n按任意键退出...")