Round 4: 修复ffmpeg空格式错误 + 添加防御性校验
- 添加 _normalize_format() 函数,规范化格式字符串,防止空/无效格式 - 修复 _parse_gt_output 空输出规格 bug(如 song.ncm> 会导致 ValueError) - 在 _convert_audio 中添加 src_fmt/dst_fmt 空值保护,确保 never empty - 在 convert_file 中添加 out_fmt 空值保护 - 在 _process_patterns 中添加 > 重定向空输出警告 + 回退到全局格式 - 将 -f 参数解析改为使用 _normalize_format(argv + 交互模式) - 添加 VIPSONG_DEBUG 环境变量支持,输出 container/out_fmt/src_fmt/dst_fmt 诊断日志 根因:out_fmt 为空字符串时,_FORMAT_MAP.get 返回空字符串, 导致 audio.export(format="") -> ffmpeg -f '' -> "is not known" 错误。
This commit is contained in:
+27
-26
@@ -393,13 +393,13 @@ def _process_patterns(patterns, output_fmt, delete_flag):
|
||||
|
||||
def print_stats():
|
||||
print()
|
||||
print("=== Conversion Stats ===")
|
||||
print(" Success: " + str(stats["success"]) + " | Failed: " + str(stats["failed"]))
|
||||
print("=== 转码统计 ===")
|
||||
print(" 成功: " + str(stats["success"]) + " | 失败: " + str(stats["failed"]))
|
||||
if stats["files"]:
|
||||
print()
|
||||
print(" Files:")
|
||||
print(" 文件:")
|
||||
for fp, ok in stats["files"]:
|
||||
status = "OK" if ok else "FAIL"
|
||||
status = "成功" if ok else "失败"
|
||||
print(" [" + status + "] " + fp)
|
||||
print()
|
||||
|
||||
@@ -446,10 +446,10 @@ def main():
|
||||
patterns.append(arg)
|
||||
i += 1
|
||||
if not patterns:
|
||||
print("Usage: vipsong.py [options] <files...>")
|
||||
print(" Options: -f <format> Output format (mp3/flac/wav/ogg/m4a/original)")
|
||||
print(" -d Delete original file after conversion")
|
||||
print(" Examples:")
|
||||
print("用法: vipsong.py [选项] <文件...>")
|
||||
print(" 选项: -f <格式> 输出格式 (mp3/flac/wav/ogg/m4a/original)")
|
||||
print(" -d 转码后删除原文件")
|
||||
print(" 示例:")
|
||||
print(" vipsong.py *.ncm")
|
||||
print(" vipsong.py -f flac -d ./music/*.ncm")
|
||||
print(" vipsong.py ./song.kgm")
|
||||
@@ -458,37 +458,38 @@ def main():
|
||||
print_stats()
|
||||
return
|
||||
print("=" * 50)
|
||||
print(" vipsong - Music Format Converter")
|
||||
print(" Support: .ncm (NetEase) .kgm/.vpr (KuGou)")
|
||||
print(" Output: mp3 / flac / wav / ogg / m4a")
|
||||
print(" vipsong - 音乐加密格式转码工具")
|
||||
print(" 支持: .ncm (网易云) .kgm/.vpr (酷狗)")
|
||||
print(" 输出: mp3 / flac / wav / ogg / m4a")
|
||||
print("=" * 50)
|
||||
print("Commands:")
|
||||
print(" <filepath> Convert file or glob pattern (e.g. *.ncm)")
|
||||
print(" -f <format> Output format (default: mp3)")
|
||||
print(" -d Delete original after conversion")
|
||||
print(" xx>yy.mp3 Output to specified filename (same dir)")
|
||||
print(" xx>wav Convert to format, keep name (xx.wav)")
|
||||
print(" xx>/path/yy.mp3 Output to absolute path")
|
||||
print(" /exit Exit")
|
||||
print(" /get Show stats")
|
||||
print("命令:")
|
||||
print(" <filepath> 转换文件或通配符模式 (如: *.ncm)")
|
||||
print(" -f <格式> 输出格式 (默认: mp3)")
|
||||
print(" -d 转码后删除原文件")
|
||||
print(" xx>yy.mp3 输出到指定文件名 (同目录下)")
|
||||
print(" xx>wav 转换格式,保留原名 (xx.wav)")
|
||||
print(" xx>/path/yy.mp3 输出到指定目录")
|
||||
print(" /exit 或 exit 退出程序")
|
||||
print(" /get 或 get 显示转码统计")
|
||||
print()
|
||||
while True:
|
||||
try:
|
||||
line = input("vipsong> ").strip()
|
||||
except (EOFError, KeyboardInterrupt):
|
||||
print()
|
||||
print("Bye!")
|
||||
print("再见!")
|
||||
break
|
||||
if not line:
|
||||
continue
|
||||
parts = _split_line(line)
|
||||
if not parts:
|
||||
continue
|
||||
# 检查命令
|
||||
if parts[0] == "/exit":
|
||||
print("Bye!")
|
||||
# 检查命令(支持带/或不带/前缀),避免指令被当作文件路径处理
|
||||
cmd = parts[0].lstrip("/")
|
||||
if cmd == "exit":
|
||||
print("再见!")
|
||||
break
|
||||
if parts[0] == "/get":
|
||||
if cmd == "get":
|
||||
print_stats()
|
||||
continue
|
||||
# 解析参数和文件模式(从 i=0 开始,parts[0] 可能是文件路径)
|
||||
@@ -521,7 +522,7 @@ def main():
|
||||
continue
|
||||
_process_patterns(patterns, output_fmt, delete_flag)
|
||||
print()
|
||||
print(" Current: Success " + str(stats["success"]) + " | Failed " + str(stats["failed"]))
|
||||
print(" 当前状态: 成功 " + str(stats["success"]) + " | 失败 " + str(stats["failed"]))
|
||||
print()
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user