项目需求
我司有个需求我们需要将视频中的音频提取出来,并且需要把提取出来的声音按照需要的时间段切片。
命令分析
1. 将视频中的音频提取出来
ffmpeg -i {file_path} -f wav -ar 16000 {file_name}
file_path: 视频的文件路径
file_name: 文件名称
-ar: 设置音频采样频率。对于输出流,它默认设置为相应输入流的频率。对于输入流,此选项仅对音频抓取设备和原始解复用器有意义,并映射到相应的解复用器选项
-i: 输入文件网址
-f: 强制输入或输出文件格式。通常会自动检测输入文件的格式,并根据输出文件的文件扩展名猜测格式,因此在大多数情况下不需要此选项。
2. 将音频按照时间段切片
ffmpeg -i {file_path} -vn -acodec copy -ss {start_time} -to {end_time} -c copy {file_name}
file_path: 视频的文件路径
start_time: 开始时间
end_time: 结束时间
file_name: 文件名称
-vn: 作为输入选项,阻止文件的所有视频流被过滤或自动选择或映射到任何输出
-acodec: 设置音频编解码器。这是 的别名-codec:a
-ss: 当用作输入选项(before -i)时,在这个输入文件中寻找 位置。请注意,在大多数格式中,无法精确查找,因此ffmpeg将查找到position之前最近的查找点
-to: 停止在位置写入输出或读取输入, -to 和 -t 是互斥的,-t 有优先权
3. 将音频压缩
ffmpeg -i {file_path} -b:a 64k -acodec mp3 -ar 44100 -ac 1 {file_name}
file_path: 视频的文件路径
file_name: 文件名称
-ac: 设置音频通道数。对于输出流,它默认设置为输入音频通道的数量。对于输入流,此选项仅对音频抓取设备和原始解复用器有意义,并映射到相应的解复用器选项。
-ar:设置音频采样频率。对于输出流,它默认设置为相应输入流的频率。对于输入流,此选项仅对音频抓取设备和原始解复用器有意义,并映射到相应的解复用器选项
4.提升音频的声音
ffmpeg -i {file_path} -filter:a "volume=5dB" {file_name}
5.查看音频分贝
ffmpeg -i {file_path} -filter_complex volumedetect -c:v copy -f null /dev/null
代码
import os
import argparse
class Ffmpeg_tools:
cmd_map = {
"mv_to_audio": "ffmpeg -i {0} -f wav -ar 16000 {1}",
"split_audio": "ffmpeg -i {0} -vn -acodec copy -ss {1} -to {2} -c copy {3}",
"zip_to_mp3": "ffmpeg -i {0} -b:a 64k -acodec mp3 -ar 44100 -ac 1 {1}",
"add_mp3_fb": "ffmpeg -i {0} -filter:a 'volume={1}dB' {2}",
"select_fb_data": "ffmpeg -i {0} -filter_complex volumedetect -c:v copy -f null /dev/null"
}
def __init__(self, name, suffix, cmd_type, times = [], fb=5):
self._name = name
self._suffix = suffix
self._file_path = "./file/{}".format(".".join([name,suffix]))
self._wav_path = "./wav_file/{}".format(".".join([name+"wav_file",'wav']))
self._cmd_type = cmd_type
self._split_path = './split_file/{}'
self._zip_file = "./zip_file/{}".format(".".join([name+"zip_file",'mp3']))
self._times = times
self.fb = fb
def run(self):
try:
params = self.construction_params()
cmds = self.construction_cmd(params=params)
for _ in cmds:
if self.excute_cmd(_):
print("成功")
else:
print("失败")
break
except Exception as e:
print(e)
def construction_cmd(self, params):
cmd_strs = []
try:
for _ in params:
cmd_strs.append(self.cmd_map.get(self._cmd_type).format(*_))
return cmd_strs
except Exception as e:
print(e)
return []
def construction_params(self):
params = []
try:
if self._cmd_type == 'mv_to_audio':
params.append([self._file_path, self._wav_path])
if self._cmd_type == 'split_audio':
for _ in range(len(self._times)):
split_path = self._split_path.format('.'.join([self._name+"split_file"+str(_), 'wav']))
params.append([self._wav_path, self._times[_][0], self._times[_][1], split_path])
if self._cmd_type == 'zip_to_mp3':
params.append([self._file_path, self._zip_file])
if self._cmd_type == 'add_mp3_fb':
split_path = self._split_path.format('.'.join([self._name, 'wav']))
params.append([split_path, self.fb, split_path])
if self._cmd_type == 'select_fb_data':
split_path = self._split_path.format('.'.join([self._name, 'wav']))
params.append([split_path])
return params
except Exception as e:
print(e)
return params
def excute_cmd(self, cmd):
try:
print(cmd)
a = os.system(cmd)
print(a)
return True
except Exception as e:
print(e)
return False
if __name__ == "__main__":
split_times = {
"PILLOWHUMPINGASMRthebestpleasuresounds": [['00:00:15','00:00:24'],['00:00:38','00:00:48'],['00:00:51','00:01:02'],['00:01:44','00:00:50'],['00:01:10','00:01:16'],['00:01:31','00:01:33'],['00:02:05','00:02:15'],['00:02:18','00:02:33'],['00:02:46','00:02:55'],['00:03:02','00:03:12'],['00:03:14','00:03:26'],['00:03:35','00:03:45'],['00:03:46','00:04:06']]
}
for i,j,k in os.walk('./file'):
for _ in k:
file_names = _.split('.')
name = file_names[0]
suffix = file_names[1]
Ffmpeg_tools(name, suffix, 'mv_to_audio').run()
Ffmpeg_tools(name, suffix, 'split_audio', split_times[name]).run()