输入文件格式:ffmpeg支持的视频文件
输出格式格式:mp3文件
使用方法:
注意:使用前需要先安装 ffmpeg 才行(Python最终调用的是 ffmpeg 命令)
Mac上安装 ffmpeg 命令:
brew install ffmpeg
使用说明:
python convert.py -h
输出:
usage: Python批量转换 视频 为 音频MP3(即提取音频文件) [-h] [--output-dir OUTPUT_DIR]
[--traverse]
file_path
positional arguments:
file_path 输入文件、目录路径,如果为目录,则遍历目录下的文件
optional arguments:
-h, --help show this help message and exit
--output-dir OUTPUT_DIR
(可选)输出目录路径,如果不传,则使用输入文件目录
--traverse (可选)src-path为目录是,是否遍历子目录,默认False
使用示例:
python convert.py hello.rmvb
python convert.py hello.rmvb hello.mp3
python convert.py /User/video_dir # videos根目录下有视频文件(忽略次级目录)
python convert.py /User/video_dir --output-dir /User/videos_to_mp3_dir # 产出的mp3文件放在"/User/videos-to-mp3"目录下
python convert.py /User/video_dir --output-dir /User/videos_to_mp3_dir --traverse # videos目录下有视频文件(包含次级目录)
ffmpeg命令:
ffmpeg -i source_video.avi -vn -ar 44100 -ac 2 -ab 192 -f mp3 dst_audio.mp3
说明:
- 源视频:source_video.avi
- 音频位率:192kb/s
- 输出格式:mp3
- 生成的声音:dst_audio.mp3
参数说明:
-
-i: 输入文件
-
-vn: 取消视频(不处理视频)
-
-ar: 设置音频采样率 (单位:Hz)
-
-ac: 设置声道数,1就是单声道,2就是立体声,转换单声道的TVrip可以用1(节省一半容量),高品质的DVDrip就可以用2
-
-ab: 设置比特率(单位:bit/s,也许老版是kb/s)前面-ac设为立体声时要以一半比特率来设置,比如192kbps的就设成96,转换 默认比特率都较小,要听到较高品质声音的话建议设到160kbps(80)以上。
-
-f: 指定格式(音频或视频格式)
#!/usr/bin/env python3.5 # _*_ coding:UTF-8 _*_ import argparse import os import subprocess from datetime import datetime def ffmpeg(src_path, dst_path): """ 调用ffmpeg命令,执行转换过程(比特率一般为128kbps、196kbps;要求不高的话,可以使用32kbps,减小体积) 注意:比特率的单位为bps :param src_path: 输入视频文件路径 :param dst_path: 输出文件路径 :return: bool值,转换结果成功or失败 """ command = "ffmpeg -i '{}' -vn -ar 44100 -ac 2 -ab 196k -f mp3 '{}'".format(src_path, dst_path) try: subprocess.check_call(command, shell=True) is_success = True except subprocess.CalledProcessError as e: print "error code: {}! shell command: {}".format(e.returncode, e.cmd) is_success = False return is_success def convert_dir(dir_path, output_dir, is_traverse=False): """ 批量转换视频文件 :param dir_path: 输入目录路径(内含视频文件) :param output_dir: 输出目录 :param is_traverse: 是否遍历子目录,默认False :return: 元组:转换成功数目,失败数目 """ success_num = 0 # 转换成功的文件数 fail_num = 0 # 转换失败的文件数 file_list = [] dir_list = [] for file_name in os.listdir(dir_path): if file_name.startswith("."): continue file_path = os.path.join(dir_path, file_name) if os.path.isfile(file_path): file_list.append(file_path) elif os.path.isdir(file_path): dir_list.append(file_path) else: print "暂时不支持该路径:{}".format(file_path) for file_path in sorted(file_list): print "file_path:", file_path result = convert_file(file_path, output_dir) if result: success_num += 1 else: fail_num += 1 for dir_path in sorted(dir_list): print "dir_path:", dir_path file_name = os.path.basename(dir_path) result = convert_dir(dir_path, os.path.join(output_dir, file_name), is_traverse) success_num += result[0] fail_num += result[1] return success_num, fail_num def convert_file(file_path, output_dir): """ 转换单个视频文件 :param file_path: 输入视频文件路径 :param output_dir: 输出文件目录路径 :return: bool值,转换结果成功or失败 """ if not os.path.isdir(output_dir): os.makedirs(output_dir) video_file_name = os.path.basename(file_path) name_body = video_file_name.rsplit(".", 1)[0] audio_name = name_body + ".mp3" dst_path = os.path.join(output_dir, audio_name) return ffmpeg(file_path, dst_path) def parse_arg(): """解析命令行的输入的参数""" parser = argparse.ArgumentParser(u"Python批量转换 视频 为 音频MP3(即提取音频文件)") parser.add_argument(u"file_path", help=u"输入文件、目录路径,如果为目录,则遍历目录下的文件") parser.add_argument(u"--output-dir", help=u"(可选)输出目录路径,如果不传,则使用输入文件目录") parser.add_argument(u"--traverse", action=u'store_true', help=u"(可选)src-path为目录是,是否遍历子目录,默认False") return parser.parse_args() def main(): """主入口""" try: # 检测ffmpeg是否已安装 result = subprocess.check_output("ffmpeg -version", shell=True) print "ffmpeg:\n", result except subprocess.CalledProcessError: print "ffmpeg未安装,请先安装:ffmpeg" return # 解析输入参数 command_param = parse_arg() file_path = command_param.file_path output_dir = command_param.output_dir start_time = datetime.now() success_num = 0 # 转换成功的文件数 fail_num = 0 # 转换失败的文件数 if os.path.isfile(file_path): # 文件 if not output_dir: output_dir = os.path.dirname(file_path) # 与输入文件同级目录 result = convert_file(file_path, output_dir) if result: success_num += 1 else: fail_num += 1 elif os.path.isdir(file_path): # 目录 if not output_dir: output_dir = file_path # 使用输入目录 success_num, fail_num = convert_dir(file_path, output_dir, is_traverse=command_param.traverse) else: assert False, u"file_path 不存在:'{}'".format(file) end_time = datetime.now() cost_seconds = (end_time - start_time).seconds print u"转换的成功文件数:{}个".format(success_num) print u"转换的失败文件数:{}个".format(fail_num) print u"总耗时:{}秒".format(cost_seconds) if __name__ == '__main__': main()