本文为博主原创,未经许可严禁转载。
本文链接:https://blog.csdn.net/zyooooxie/article/details/111307652
个人博客:https://blog.csdn.net/zyooooxie
需求
我电脑上有些视频文件,用途 主要是听声音【图像是ppt】;但又占了不小的硬盘空间。
就想着用什么方法能够把音频提取出来?
之前我用PotPlayer录制过音频,但太麻烦【需要:打开视频,控制时间段,等它播放,录制】;
在网上搜索,看到有人推荐FFmpeg;
这篇分享其实内容不多,是爬坑 花的心力多,才想着写出来,让有需要的朋友少些麻烦。
下载
搜索很多答案 有的说 https://ffmpeg.zeranoe.com/builds/ (我的电脑打不开,查到ffmpeg.zeranoe.com will close on Sep 18, 2020, and all builds will be removed)、有的说 http://ffmpeg.org/ (找了半天,摸不清楚下载哪个)、还有 一些技术社区 乱七八糟的资源;
无从下手啊。
郑重推荐 https://www.videohelp.com/software/ffmpeg
https://www.videohelp.com/software/ffmpeg/old-versions 我是偏爱老版本的;
代码
class ToMp3(object):
"""提取视频文件的音频"""
def __init__(self, abs_path):
"""路径 不包含文件"""
self.path = abs_path
def cmd_function(self):
os.chdir(self.path)
video_list = [a for a in os.listdir(self.path) if a.endswith(('jpg', 'json', 'gif')) is False]
# if len(video_list) != 1:
# os.system('explorer {}'.format(self.path))
#
# raise Exception('当前文件夹{} 视频文件个数有误'.format(self.path))
for v in video_list:
self.cmd_function2(v)
print('----------------------------------------------')
def cmd_function2(self, mp4_file):
file_name, file_type = os.path.splitext(mp4_file)
print(file_type)
print(file_name)
new_name = 'test' + file_type
os.rename(mp4_file, new_name)
sleep(1)
FFMPEG_BIN = r'C:\ffmpeg\bin\ffmpeg.exe' # 不要有空格
# getmp3_cmd = '{} -i "{}" -f mp3 -vn "test.mp3" '.format(FFMPEG_BIN, new_name)
if file_type.find('mp4') != -1 or file_type.find('MP4') != -1 \
or file_type.find('flv') != -1 or file_type.find('FLV') != -1:
mp = 'test.aac'
geshi = '.aac'
# mp = 'test.mp3'
# geshi = '.mp3'
getmp3_cmd = '{} -i "{}" -acodec copy -vn {}'.format(FFMPEG_BIN, new_name, mp)
elif file_type.find('mkv') != -1:
mp = 'test.opus'
geshi = '.opus'
getmp3_cmd = '{} -i "{}" -vn -acodec copy {}'.format(FFMPEG_BIN, new_name, mp)
else:
raise Exception('格式:{}'.find(file_type))
# getmp3_cmd = ['ffmpeg', '-i', os.path.join(self.path, new_name), '-f', 'mp3', '-vn', os.path.join(self.path, 'test.mp3')]
print(getmp3_cmd)
res = subprocess.Popen(getmp3_cmd, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True)
try:
print(res.stdout.read())
except UnicodeDecodeError:
print('编码有问题')
sleep(1)
os.rename(new_name, mp4_file)
move_path = r'E:\sleep'
name = '{}{}'.format(file_name, geshi)
os.rename(mp, name)
if os.path.exists(os.path.join(move_path, name)):
e_name = file_name + str(random.randint(1, 1000)) + ''.format(geshi)
else:
e_name = name
shutil.move(name, os.path.join(move_path, e_name))
os.chdir(move_path)
last_list = os.listdir(move_path)
abc = sorted(last_list, key=lambda x: os.path.getmtime(x), reverse=True)[0]
print(abc)
if abc.find(file_name) != -1:
file_size = os.path.getsize(abc)
print(file_size, round(file_size / 1024 / 1024, 2))
if file_size > 1024: # 大于1kb 删除原始文件
# 1024Bytes 1kb
os.chdir(self.path)
os.remove(mp4_file)
else: # 删除 音频文件
os.remove(abc)
raise Exception('音频文件已删除,请查看ffmpeg打印信息')
1、最初 我是也不知道mp4、mkv 提取音频 要选啥格式,开始用的是mp3;后来看打印的信息,才做的优化;
2、每次转换完,我一般都 先去听下 实际转换后的音频文件,再去删掉 原视频文件;想着 这样的操作好麻烦,那就简单点,以音频文件大小做判断 是否去清理视频文件;
3、之前的设计 会判断文件夹内的视频文件数量,后来因为每次提取要1个 1个的搞,太麻烦;就把这个判断给注释了,目前是某文件夹的所有视频文件 都会被提取音频;
2021年10月30号更新
交流技术 欢迎+QQ 153132336 zy
个人博客 https://blog.csdn.net/zyooooxie