<gh_stars>0
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
import glob
import os
import threading
import tqdm
from functools import partial
from pydub import AudioSegment
from pydub.silence import detect_silence
from multiprocessing import Pool


def split(_audio_path: str, _out_dir: str, _cut_index: int = 0, silence_len = 100, min_len = 0):
    sound = AudioSegment.from_file(_audio_path, format = "wav")
    file_name = os.path.basename(_audio_path).split(".")[0]
    start_end = detect_silence(sound, silence_len, -70, 1)
    if len(start_end) == 0:
        sound.export(os.path.join(_out_dir, f"{file_name}_{str(_cut_index).zfill(3)}.wav"), format("wav"))
        _cut_index += 1
        return _cut_index
    durations = []
    index = 0
    limit_len = 0
    while index < len(start_end) - 1:
        audio_seg: AudioSegment = None
        while audio_seg is None or audio_seg.duration_seconds * 1000 < limit_len:
            se = start_end[index]
            end = se[1]
            next_se = start_end[index + 1]
            next_start = next_se[0]
            du = next_start - end
            if audio_seg is None:
                duration = du
            else:
                duration = audio_seg.duration_seconds * 1000 + du

            if duration + silence_len > limit_len:  # 满足长度要求
                if audio_seg is None:  # 第一个片段就满足长度要求，silence_len + seg + silence_len
                    audio_start = end - silence_len  # 音频起始时间
                    audio_end = next_start + silence_len
                else:  # 多个片段满足要求，silence_len + seg...seg + silence_len
                    audio_start = end
                    audio_end = next_start + silence_len
            else:
                if audio_seg is None:  # 第一个片段不满足长度要求，silence_len + seg
                    audio_start = end - silence_len  # 音频起始时间
                    audio_end = next_start
                else:  # 多个片段不满足长度要求，silence_len + sge + seg
                    audio_start = end  # 音频起始时间
                    audio_end = next_start

                # 如果是倒数第二个，即最后一个音频已经处理。此时需要拼接上240的间隔
                if index == len(start_end) - 2:
                    audio_end += silence_len

            if audio_seg is None:
                audio_seg = sound[audio_start:audio_end]
            else:
                audio_seg = audio_seg + sound[audio_start:audio_end]
            index += 1

            # 最后一个，结束循环
            if index == len(start_end) - 1:
                break

        durations.append(audio_seg.duration_seconds)

        # 只是时长满足的导出
        if audio_seg.duration_seconds > min_len:
            audio_seg.export(os.path.join(_out_dir, f"{file_name}_{str(_cut_index).zfill(6)}_{int(audio_seg.duration_seconds)}.wav"), format("wav"))
            _cut_index += 1
    return _cut_index


if __name__ == '__main__':
    # 参数
    parser = argparse.ArgumentParser()
    parser.add_argument("--input_dir", default = "./sample", type = str, help = "要切分的音频目录，仅支持wav格式")
    parser.add_argument("--out_dir", default = "./cut", type = str, help = "要切分的音频目录，仅支持wav格式")
    parser.add_argument("--workers", default = "50", type = int, help = "线程数量")
    parser.add_argument("--silence_len", default = "100", type = int, help = "头尾空白时长")
    parser.add_argument("--min_len", default = "2", type = float, help = "最短时长")
    args = parser.parse_args()
    input_dir = args.input_dir
    out_dir = args.out_dir
    workers = args.workers
    min_len = args.min_len
    silence_len = args.silence_len
    os.makedirs(out_dir, exist_ok = True)
    assert os.path.exists(input_dir)

    # 读取音频文件路径
    wav_files = glob.glob(os.path.join(input_dir, "*.wav"))
    cut_index = 0

    with Pool(workers) as pool:
        partial_fn = partial(split, _out_dir = out_dir, _cut_index = cut_index, silence_len = silence_len, min_len = min_len)
        pool_map = pool.imap_unordered(partial_fn, wav_files)
        for result in tqdm.tqdm(pool_map, total = len(wav_files), desc = '切分音频文件'):
            cut_index = result

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import argparse
import glob
import os
import threading
import tqdm
from functools import partial
from pydub import AudioSegment
from pydub.silence import detect_silence
from multiprocessing import Pool


def split(_audio_path: str, _out_dir: str, _cut_index: int = 0, silence_len = 100, min_len = 0):
    sound = AudioSegment.from_file(_audio_path, format = "wav")
    file_name = os.path.basename(_audio_path).split(".")[0]
    start_end = detect_silence(sound, silence_len, -70, 1)
    if len(start_end) == 0:
        sound.export(os.path.join(_out_dir, f"{file_name}_{str(_cut_index).zfill(3)}.wav"), format("wav"))
        _cut_index += 1
        return _cut_index
    durations = []
    index = 0
    limit_len = 0
    while index < len(start_end) - 1:
        audio_seg: AudioSegment = None
        while audio_seg is None or audio_seg.duration_seconds * 1000 < limit_len:
            se = start_end[index]
            end = se[1]
            next_se = start_end[index + 1]
            next_start = next_se[0]
            du = next_start - end
            if audio_seg is None:
                duration = du
            else:
                duration = audio_seg.duration_seconds * 1000 + du

            if duration + silence_len > limit_len:  # 满足长度要求
                if audio_seg is None:  # 第一个片段就满足长度要求，silence_len + seg + silence_len
                    audio_start = end - silence_len  # 音频起始时间
                    audio_end = next_start + silence_len
                else:  # 多个片段满足要求，silence_len + seg...seg + silence_len
                    audio_start = end
                    audio_end = next_start + silence_len
            else:
                if audio_seg is None:  # 第一个片段不满足长度要求，silence_len + seg
                    audio_start = end - silence_len  # 音频起始时间
                    audio_end = next_start
                else:  # 多个片段不满足长度要求，silence_len + sge + seg
                    audio_start = end  # 音频起始时间
                    audio_end = next_start

                # 如果是倒数第二个，即最后一个音频已经处理。此时需要拼接上240的间隔
                if index == len(start_end) - 2:
                    audio_end += silence_len

            if audio_seg is None:
                audio_seg = sound[audio_start:audio_end]
            else:
                audio_seg = audio_seg + sound[audio_start:audio_end]
            index += 1

            # 最后一个，结束循环
            if index == len(start_end) - 1:
                break

        durations.append(audio_seg.duration_seconds)

        # 只是时长满足的导出
        if audio_seg.duration_seconds > min_len:
            audio_seg.export(os.path.join(_out_dir, f"{file_name}_{str(_cut_index).zfill(6)}_{int(audio_seg.duration_seconds)}.wav"), format("wav"))
            _cut_index += 1
    return _cut_index


if __name__ == '__main__':
    # 参数
    parser = argparse.ArgumentParser()
    parser.add_argument("--input_dir", default = "./sample", type = str, help = "要切分的音频目录，仅支持wav格式")
    parser.add_argument("--out_dir", default = "./cut", type = str, help = "要切分的音频目录，仅支持wav格式")
    parser.add_argument("--workers", default = "50", type = int, help = "线程数量")
    parser.add_argument("--silence_len", default = "100", type = int, help = "头尾空白时长")
    parser.add_argument("--min_len", default = "2", type = float, help = "最短时长")
    args = parser.parse_args()
    input_dir = args.input_dir
    out_dir = args.out_dir
    workers = args.workers
    min_len = args.min_len
    silence_len = args.silence_len
    os.makedirs(out_dir, exist_ok = True)
    assert os.path.exists(input_dir)

    # 读取音频文件路径
    wav_files = glob.glob(os.path.join(input_dir, "*.wav"))
    cut_index = 0

    with Pool(workers) as pool:
        partial_fn = partial(split, _out_dir = out_dir, _cut_index = cut_index, silence_len = silence_len, min_len = min_len)
        pool_map = pool.imap_unordered(partial_fn, wav_files)
        for result in tqdm.tqdm(pool_map, total = len(wav_files), desc = '切分音频文件'):
            cut_index = result
#!/usr/bin/python3 # -*- coding: utf-8 -*- # 满足长度要求 # 第一个片段就满足长度要求，silence_len + seg + silence_len # 音频起始时间 # 多个片段满足要求，silence_len + seg...seg + silence_len # 第一个片段不满足长度要求，silence_len + seg # 音频起始时间 # 多个片段不满足长度要求，silence_len + sge + seg # 音频起始时间 # 如果是倒数第二个，即最后一个音频已经处理。此时需要拼接上240的间隔 # 最后一个，结束循环 # 只是时长满足的导出 # 参数 # 读取音频文件路径