一、问题:大批量的音频测试文件,无法满足测试需求

项目测试需要往平台中上传一批音频文件进行算法测试, 平台规定的音频的时长必须在10-30s内, 而从算法开发人员那里获取到的3000条音频文件都是32s时长, 因此无法将测试数据上传到平台进行测试。

基于以上问题,需要在项目体测之前将3000条音频文件都转换成30s以内的文件,手动裁剪的话费时费力,且没有那么多的时间和人力去处理。因此想到了编写工具脚本来批量处理这些音频文件

二、解决思路:批量裁剪音频文件

网上搜索到python中的第三方库pydub中有很多音频文件处理的方法,以下是脚本的实现思路

1、调用脚本,传参:音频文件路径、音频文件格式,裁剪模式,裁剪的起点,裁剪的终点

  音频文件格式:一般是mp3、wav格式

  裁剪模式:分为模式1和模式2, 输入的是模式1的话,则将一条音频裁剪成相等时长的两段音频文件(生成了2条音频);输入的是模式2的话,则裁剪出起点                            和终点之间的一段音频文件(生成了1条音频)

  裁剪的起点、裁剪的终点:即按照指定的音频的开始时间位置和结束时间位置进行裁剪,参数值的单位为秒

2、根据 音频文件路径参数,先在此路径下生成一个名为“separateResultFile”的文件夹,若已存在此文件夹,则删除重新创建,若未存在此文件夹,则直接创建

3、根据1中输入的参数,读取音频文件夹下的所有文件,并循环处理每一条文件,并将处理后生成的音频文件保存到“separateResultFile”文件夹中

三、解决过程:采用python中的第三方库pydub进行批量处理音频文件

如下图所示,是实现的代码。用到了pydub 库中的AudioSegment  和 pydub.utils 中的make_chunks 

from pydub import AudioSegment
from pydub.utils import make_chunks
import os, re,shutil

def mikdir(path):
    folder=os.path.exists(path)
    if not folder:
        os.makedirs(path)
    else:
        shutil.rmtree(path)
        os.makedirs(path)
    return path

def audioFileSeparate(filepath,audiofile_type,separate_mode,starttime=0,endtime=0):
    """
    :param filepath: 音频文件存放的文件夹路径
    :param audiofile_type: 音频文件格式(mp3、wav等格式)
    :param separate_mode: 裁剪模式(1:裁剪成长度相等的两段视频,2:输入起止时间进行裁剪)
    :param starttime,endtime: 如果模式为2时,需要输入裁剪的开始时间和结束时间,单位为秒
    :return:无
    """
    #创建分割后存储的文件夹
    savepath=mikdir(os.path.join(filepath,"separateResultFile"))
    # # 循环目录下所有文件
    for eachfile in os.listdir(filepath):  # 循环目录
        #audiofilename = re.findall(r"(.*?)\.wav", eachfile)  # 取出.mp3后缀的文件名
        print(eachfile)
        try:
            if eachfile:
                audiofile_path = os.path.join(filepath, eachfile)
                audiofile = AudioSegment.from_file_using_temporary_files(file=audiofile_path,
                                                                         format=audiofile_type)  # 打开指定格式的文件
                # mp3 = AudioSegment.from_file('P:/ai测试数据/光纤/光纤/异常//{}'.format(eachfile), "wav")  # 打开mp3文件
                #         # # mp3[17*1000+500:].export(filename[0], format="mp3") # 切割前17.5秒并覆盖保存,与以下代码不可同时使用
                audioDuration = audiofile.duration_seconds
                if separate_mode == 1:
                    # size = 16000  # 切割的毫秒数 10s=10000
                    chunks = make_chunks(audiofile, audioDuration // 2 * 1000)  # 将文件平分成两个
                    for i, chunk in enumerate(chunks):
                        chunk_name = "{}-{}.wav".format(eachfile.split(".")[0], i)  # 也可以自定义名字
                        # chunk.export('P:/ai测试数据/光纤/光纤/异常分割后/{}'.format(chunk_name), format=audiofile_type)  # 新建的保存文件夹
                        chunk.export(savepath+ "/" + chunk_name, format=audiofile_type)  # 新建的保存文件夹
                elif separate_mode == 2:
                    audioAfterSeparate = audiofile[starttime*1000:endtime*1000]
                    audioAfterSeparate_name = "{}-{}.wav".format(eachfile.split(".")[0], 0)  # 也可以自定义名字
                    audioAfterSeparate.export(savepath + "/" + audioAfterSeparate_name, format=audiofile_type)
                else:
                    print("separate_mode 参数只能是1或2, 您输入的参数有误")
            else:
                print("文件夹下无视频文件,请确认一下文件夹路径")

        except PermissionError:
            pass

if __name__ == '__main__':
    #audioFileSeparate(filepath="C:\\Users\\chenna9\\Desktop\\test",audiofile_type="wav",separate_mode=2,starttime=0,endtime=30)
    audioFileSeparate(filepath="C:\\Users\\chenna9\\Desktop\\test", audiofile_type="wav", separate_mode=2, starttime=0,
                      endtime=30)

 

四、总结

1、脚本实现过程中,出现了permissionError 的问题,问题得到了一定程度的解决,但最后还是会有这个报错,所有并没有真正意义上的解决,最后是将此报错忽略了,具体解放方法可查看此的随笔 :python--python脚本中保存处理后的音频文件到指定文件夹时报错permission denied 的问题

2、将文件夹下的所有文件,获取到并循环处理每一个音频文件, 其实这里是有问题的,有可能此文件夹下有非音频类型的文件,所有应该是获取到指定的格式的文件并对此文件进行处理。

不过由于时间有限,且工作中都是一个文件夹下都是音频文件,所有此需求点比较低,没有实现,后续有需要的话再优化把。

3、其实代码里异常捕捉和处理的功能没有实现,奈何自己这块还有点薄弱,后续加强这一块的学习和使用把。