在玩bert-vits2的时候有对音频进行重采样的需求,故写了一下批量对音频进行重采样的脚本。
优化点:
运行结果如下·:
具体代码如下:
import os
import time
import librosa
import soundfile as sf
import concurrent.futures
from tqdm import tqdm
def resampleAudio(params):
'''
Parameters
----------
params
audioPath, outpath,target_sr #音频地址,重采样后的输出地址,目标音频的采样率
Returns
-------
'''
audioPath, outpath,target_sr=params
try:
src_sig,sr = sf.read(audioPath) #name是要 输入的wav 返回 src_sig:音频数据 sr:原采样频率
dst_sig = librosa.resample(src_sig,orig_sr=sr,target_sr=target_sr) #resample 入参三个 音频数据 原采样频率 和目标采样频率
sf.write(outpath,dst_sig,target_sr) #写出数据 参数三个 : 目标地址 更改后的音频数据 目标采样数据
return True
except Exception as e:
print(e)
return False
def Getsr(audioPath):
'''
查询音频的采样率是否更改
Returns
-------
'''
src_sig, sr = sf.read(audioPath) # name是要 输入的wav 返回 src_sig:音频数据 sr:原采样频率
return sr
def main(dirpath,target_sr):
'''
Parameters
----------
dirpath :包含要修改采样率的音频文件夹地址
target_sr:目标采样率
Returns
-------
'''
outdir=dirpath+'_'+str(target_sr)
if not os.path.exists(outdir):
os.mkdir(outdir)
cpuNum=min(1,os.cpu_count()-2)
with concurrent.futures.ThreadPoolExecutor(max_workers=cpuNum) as excutor:
futures=[]
for ret,dirs,files in os.walk(dirpath):
for fileName in files:
filepath=os.path.join(ret,fileName)
outfile=filepath.replace(dirpath,outdir)
if not os.path.exists(os.path.dirname(outfile)): #如果没有输出的这个文件夹则新建一个
os.mkdir(os.path.dirname(outfile))
params=filepath,outfile,target_sr
task=excutor.submit(resampleAudio,params)
futures.append(task)
prad=tqdm(total=len(futures))
for future in concurrent.futures.as_completed(futures):
res=future.result()
prad.update(1)
prad.close()
if __name__=="__main__":
dirpath = r'I:\audioData\UVR\test9' #更改为你的文件夹
target_sr=44100
preTime=time.time()
audioNum=len(os.listdir(dirpath))
isshow=True #是否显示过程
if isshow:
print('开始对文件夹:{}下的{}个音频的采样率都更改为:{}HZ'.format(dirpath,audioNum,target_sr))
main(dirpath,target_sr)
if isshow:
print('重采样完成,保存地址:{}\n耗费时间:{:.2f} min'.format(dirpath+'_'+str(target_sr),(time.time()-preTime)/60))
try:
audioPath = dirpath+'_'+str(target_sr)+'/'+os.listdir(dirpath)[0]
sr=Getsr(audioPath) #查询音频的采样率是否更改
print('抽样查询更改后输出文件:{}的采样率'.format(audioPath))
if sr==target_sr:
print('该音频更改成功')
except Exception as e:
print(e)
有时候要对音频改为特定的格式比如Bert-VITS2要的,采样44100+通道数为1+音频类型为wav+编码格式pcm16
这时候就需要对批量程序进行一下修改,在这里由于有多种需求,我就直接使用ffmpeg进行转,提高转化的速度和转化能力。
import os
import time
import librosa
import soundfile as sf
import concurrent.futures
from tqdm import tqdm
import subprocess
import imageio_ffmpeg
def resampleAudio(params):
'''
Parameters
----------
params
audioPath, outpath,target_sr #音频地址,重采样后的输出地址,目标音频的采样率
Returns
-------
'''
audioPath, outpath,target_sr=params
try:
# src_sig,sr = librosa.load(audioPath, sr=None) #name是要 输入的wav 返回 src_sig:音频数据 sr:原采样频率
# dst_sig = librosa.resample(src_sig,orig_sr=sr,target_sr=target_sr) #resample 入参三个 音频数据 原采样频率 和目标采样频率
#sf.write(outpath,dst_sig,target_sr) #写出数据 参数三个 : 目标地址 更改后的音频数据 目标采样数据
compress = '{} -i "{}" -acodec pcm_f32le -ac 1 -ar {} "{}"'.format(imageio_ffmpeg.get_ffmpeg_exe(), audioPath,target_sr,outpath)
f = subprocess.Popen(compress)
return True
except Exception as e:
print(e)
return False
def Getsr(audioPath):
'''
查询音频的采样率是否更改
Returns
-------
'''
src_sig, sr = sf.read(audioPath) # name是要 输入的wav 返回 src_sig:音频数据 sr:原采样频率
return sr
def main(dirpath,target_sr):
'''
Parameters
----------
dirpath :包含要修改采样率的音频文件夹地址
target_sr:目标采样率
Returns
-------
'''
outdir=dirpath+'_'+str(target_sr)
if not os.path.exists(outdir):
os.mkdir(outdir)
cpuNum=min(1,os.cpu_count()-2)
with concurrent.futures.ThreadPoolExecutor(max_workers=cpuNum) as excutor:
futures=[]
for ret,dirs,files in os.walk(dirpath):
for fileName in files:
if fileName.endswith(('wav','mp3','ogg','opus','flac','m4a')) :
filepath=os.path.join(ret,fileName)
outfile=filepath.replace(dirpath,outdir).replace(fileName.split('.')[-1],'wav')
if not os.path.exists(os.path.dirname(outfile)): #如果没有输出的这个文件夹则新建一个
os.mkdir(os.path.dirname(outfile))
params=filepath,outfile,target_sr
if not os.path.exists(outfile):
task=excutor.submit(resampleAudio,params)
futures.append(task)
prad=tqdm(total=len(futures))
for future in concurrent.futures.as_completed(futures):
res=future.result()
prad.update(1)
prad.close()
def AudioHandle():
dirpath = input('待更音频文件夹绝对地址:') #更改为你的文件夹
target_sr=44100 #更改为你的目标音频采样率
preTime=time.time()
audioNum=len(os.listdir(dirpath))
isshow=True #是否显示过程
if isshow:
print('开始对文件夹:{}下的{}个音频的采样率都更改为:{}HZ'.format(dirpath,audioNum,target_sr))
main(dirpath,target_sr)
if isshow:
print('重采样完成,保存地址:{}\n耗费时间:{:.2f} min'.format(dirpath+'_'+str(target_sr),(time.time()-preTime)/60))
try:
fileName=os.listdir(dirpath)[0]
audioPath = os.path.join(dirpath+'_'+str(target_sr),fileName.replace(fileName.split('.')[-1],'wav'))
sr=Getsr(audioPath) #查询音频的采样率是否更改
print('抽样查询更改后输出文件:{}的采样率'.format(audioPath))
if sr==target_sr:
print('该音频更改成功')
except Exception as e:
print(e)
if __name__ == "__main__":
AudioHandle()