使用python写的mp4转mp3的转换程序
问Claude:
使用python写一个mp4转mp3的转换程序 实现功能:
1.调用ffmpeg进行转换
2.可以单文件方式也可以批量方式转换,如果程序启动时传入的是单文件的路径,则采用单文件转换方式,如果传入的是目录路径,则将该目录下的文件批量转换
3.如果目录下已存在已转换的MP3文件,则忽略该文件不进行转换
4.可通过传入参数指定转换后的文件的保存路径,默认为保存在视频文件相同目录下
5.MP3的码率可以配置,默认为192K
6.如果程序启动时没有传入任何参数,则提示用户输入参数,并等待用户的输入完成
7.要在控制台里显示转换的进度信息
8.转换完成后播放系统提示音提醒
Claude答:
import os import sys import subprocess import argparse import platform import glob import time from pathlib import Path def play_notification_sound(): """播放系统提示音""" system = platform.system() try: if system == "Windows": import winsound winsound.MessageBeep() elif system == "Darwin": # macOS subprocess.call(["afplay", "/System/Library/Sounds/Ping.aiff"]) else: # Linux和其他系统 subprocess.call(["paplay", "/usr/share/sounds/freedesktop/stereo/complete.oga"]) except Exception as e: print(f"无法播放系统提示音: {e}") def get_duration(file_path): """使用ffmpeg获取媒体文件的时长""" cmd = ["ffmpeg", "-i", file_path, "-f", "null", "-"] # 使用bytes模式并指定encoding='utf-8', errors='replace'进行解码 result = subprocess.run(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE) # 使用errors='replace'安全地解码,替换无法解码的字符 stderr_text = result.stderr.decode('utf-8', errors='replace') for line in stderr_text.split('\n'): if "Duration" in line: time_str = line.split("Duration: ")[1].split(",")[0].strip() h, m, s = time_str.split(':') return float(h) * 3600 + float(m) * 60 + float(s) return None def convert_mp4_to_mp3(input_path, output_path=None, bitrate="192k"): """使用ffmpeg将MP4文件转换为MP3""" if output_path is None: # 使用与输入文件相同的目录,但扩展名为.mp3 output_path = os.path.splitext(input_path)[0] + ".mp3" # 检查输出文件是否已存在 if os.path.exists(output_path): print(f"输出文件已存在: {output_path}. 跳过转换。") return False # 获取视频时长,用于计算进度 duration = get_duration(input_path) # 准备ffmpeg命令 cmd = [ "ffmpeg", "-i", input_path, "-vn", # 不包含视频 "-acodec", "libmp3lame", "-ab", bitrate, "-f", "mp3", output_path ] # 启动进程并监控进度 - 不使用universal_newlines,改用bytes模式 process = subprocess.Popen( cmd, stderr=subprocess.PIPE, # 移除universal_newlines=True ) # 用于进度跟踪的变量 start_time = time.time() last_update = 0 line_buffer = b"" # 逐行读取输出以更新进度 while True: chunk = process.stderr.read(1) if not chunk and process.poll() is not None: break if chunk: line_buffer += chunk if chunk == b'\n' or chunk == b'\r': try: # 安全解码行,替换无法解码的字符 line = line_buffer.decode('utf-8', errors='replace') if "time=" in line and duration: # 提取当前时间 time_str = line.split("time=")[1].split()[0] if ":" in time_str: h, m, s = time_str.split(':') current_time = float(h) * 3600 + float(m) * 60 + float(s) else: current_time = float(time_str) # 每秒最多更新一次进度 current = time.time() if current - last_update >= 1: progress = min(100, (current_time / duration) * 100) print(f"\r转换中: {os.path.basename(input_path)} - {progress:.1f}%", end="") last_update = current except Exception as e: # 处理解析错误 pass line_buffer = b"" # 等待进程完成 process.wait() print() # 进度完成后换行 # 检查转换是否成功 if process.returncode == 0: print(f"成功转换: {output_path}") return True else: print(f"转换失败: {input_path}") return False def process_input(input_path, output_dir=None, bitrate="192k"): """处理单个文件或目录中的所有MP4文件""" converted_count = 0 total_count = 0 if os.path.isfile(input_path): # 单文件模式 if not input_path.lower().endswith('.mp4'): print(f"输入文件不是MP4格式: {input_path}") return 0, 1 # 确定输出路径 if output_dir: output_path = os.path.join(output_dir, os.path.splitext(os.path.basename(input_path))[0] + ".mp3") else: output_path = os.path.splitext(input_path)[0] + ".mp3" # 如果输出目录不存在,创建它 os.makedirs(os.path.dirname(output_path), exist_ok=True) # 执行转换 success = convert_mp4_to_mp3(input_path, output_path, bitrate) return 1 if success else 0, 1 elif os.path.isdir(input_path): # 批量模式 - 处理目录中的所有MP4文件 mp4_files = glob.glob(os.path.join(input_path, "*.mp4")) total_count = len(mp4_files) if total_count == 0: print(f"目录中没有找到MP4文件: {input_path}") return 0, 0 print(f"找到{total_count}个MP4文件等待转换") for i, file_path in enumerate(mp4_files, 1): print(f"\n处理文件 {i}/{total_count}: {os.path.basename(file_path)}") # 确定输出路径 if output_dir: output_path = os.path.join(output_dir, os.path.splitext(os.path.basename(file_path))[0] + ".mp3") else: output_path = os.path.splitext(file_path)[0] + ".mp3" # 如果输出目录不存在,创建它 os.makedirs(os.path.dirname(output_path), exist_ok=True) # 执行转换 if convert_mp4_to_mp3(file_path, output_path, bitrate): converted_count += 1 return converted_count, total_count else: print(f"输入路径不存在: {input_path}") return 0, 0 def main(): parser = argparse.ArgumentParser(description="将MP4视频文件转换为MP3音频文件") parser.add_argument("input", nargs="?", help="输入MP4文件或包含MP4文件的目录") parser.add_argument("-o", "--output", help="MP3文件的输出目录(默认:与输入相同)") parser.add_argument("-b", "--bitrate", default="192k", help="MP3码率(默认:192k)") args = parser.parse_args() # 如果没有提供参数,提示用户输入 if not args.input: print("未提供输入参数。请输入所需信息。") args.input = input("请输入MP4文件路径或包含MP4文件的目录路径: ").strip() output_choice = input("是否要指定输出目录? (y/n): ").strip().lower() if output_choice == 'y': args.output = input("请输入输出目录路径: ").strip() bitrate_choice = input("是否要指定自定义码率? (y/n): ").strip().lower() if bitrate_choice == 'y': args.bitrate = input("请输入码率 (例如: 128k, 192k, 320k): ").strip() # 验证输入路径 if not os.path.exists(args.input): print(f"错误: 输入路径不存在: {args.input}") return 1 # 如果提供了输出目录,验证它 if args.output and not os.path.isdir(args.output): try: os.makedirs(args.output, exist_ok=True) print(f"已创建输出目录: {args.output}") except Exception as e: print(f"创建输出目录时出错: {e}") return 1 # 处理输入 print(f"\n开始转换过程...") print(f"输入: {args.input}") print(f"输出目录: {args.output or '与输入相同'}") print(f"码率: {args.bitrate}") print("-" * 50) start_time = time.time() converted, total = process_input(args.input, args.output, args.bitrate) elapsed_time = time.time() - start_time # 打印摘要 print("\n" + "=" * 50) print(f"转换完成!") print(f"成功转换: {converted}/{total} 个文件") print(f"总耗时: {elapsed_time:.2f} 秒") print("=" * 50) # 播放提示音 play_notification_sound() return 0 if __name__ == "__main__": sys.exit(main())
这个程序实现了您请求的所有功能:
- 使用ffmpeg进行MP4到MP3的转换
- 支持单文件和批量转换模式:
- 如果输入是文件路径,则只转换该文件
- 如果输入是目录路径,则转换该目录下所有MP4文件
- 如果目标目录已存在对应的MP3文件,则跳过该文件
- 可以通过-o或–output参数指定输出目录
- 可以通过-b或–bitrate参数设置MP3码率,默认为192k
- 如果启动时没有提供参数,会进入交互模式提示用户输入
- 在转换过程中显示进度信息
- 转换完成后播放系统提示音
使用方法
基本用法:
python mp4_to_mp3.py 视频文件.mp4
指定输出目录:
广告
python mp4_to_mp3.py 视频文件.mp4 -o 输出目录
指定码率:
python mp4_to_mp3.py 视频文件.mp4 -b 320k
批量转换整个目录:
python mp4_to_mp3.py 视频目录
无参数启动(会提示输入):
python mp4_to_mp3.py
程序运行需要预先安装ffmpeg,并确保ffmpeg命令可以在系统路径中访问。