CoolFace
Apppublic

deepsync/vad-audio-labels-experimental-2

sourceHugging Faceapache-2.0updated 2y agoView on Hugging Face
0likes
app.py93 linesDownload Raw Back to root
1import gradio as gr2import os3from uuid import uuid44from pydub.silence import detect_nonsilent5from pydub import AudioSegment6 7 8def get_labels(audio_fp, min_speech_duration_ms, min_silence_duration_ms, auto_merge, uppper_merge_threshold, max_segment_length, end_extension, extend_small_segments, show_duration_label):9    audio = AudioSegment.from_file(audio_fp.name).set_channels(1)10    speech_timestamps = detect_nonsilent(audio, min_silence_len=min_silence_duration_ms, silence_thresh=-40)11    speech_timestamps = list(filter(lambda x: x[1]-x[0] > min_speech_duration_ms, speech_timestamps))12    speech_timestamps = [{"start": s[0]/1000, "end": s[1]/1000} for s in speech_timestamps]13    labels_str = []14    labels = []15 16    uppper_merge_threshold = float(uppper_merge_threshold)17    18    for i, st in enumerate(speech_timestamps):19        labels_str.append(f"{st['start']}\t{st['end']}\tSound {i+1}")20        labels.append((float(st['start']), float(st['end']), f"Sound {i+1}"))21        22    fn = str(uuid4()) + ".txt"23    with open(fn, "w") as f:24        f.write("\n".join(labels_str))25 26    if not auto_merge:27        return fn, None28 29    gaps = [labels[i][0] - labels[i - 1][1] for i in range(1, len(labels))]30 31    duration = lambda x: float(x[1]) - float(x[0])32 33    new_labels = [list(labels[0])]34    for i in range(1, len(labels)):35        if (36            gaps[i - 1] <= uppper_merge_threshold37            and duration(new_labels[-1]) + gaps[i - 1] + duration(labels[i])38            < max_segment_length39        ):40            new_labels[-1][1] = labels[i][1]41            new_labels[-1][42                243            ] = f'{new_labels[-1][2]} |{round(gaps[i-1], 2)}s| {labels[i][2]}'44        else:45            new_labels.append(list(labels[i]))46 47    extended = [False] * (len(new_labels) - 1)48    if extend_small_segments:49        for i, nl in enumerate(new_labels[:-1]):50            if nl[1] - nl[0] <= 1.02 and nl[0] + 1.02 < new_labels[i+1][0]:51                nl[1] = nl[0] + 1.0252                extended[i] = True53 54    if end_extension:55        for i, nl in enumerate(new_labels[:-1]):56            if not extended[i]:57                if nl[1] + end_extension < new_labels[i+1][0]:58                    nl[1] = nl[1] + end_extension59 60    if show_duration_label:61        for nl in new_labels:62            nl[2] = round(nl[1] - nl[0], 3)63 64    translate_labels = list(map(lambda x: f"{x[0]}\t{x[1]}\t{x[2]}", new_labels))65 66    filename_path = f"{fn}_translate_label.txt"67    with open(filename_path, "w") as f:68        f.write("\n".join(translate_labels))69    70    return fn, filename_path71 72 73interface = gr.Interface(74    get_labels,75    [76        gr.File(type="filepath", label="Audio file", file_types=["audio"], file_count="single"),77        gr.Number(label="min_speech_duration_ms", value=40, info="default (40)"), 78        gr.Number(label="min_silence_duration_ms", value=40, info="default (40)"),79        gr.Checkbox(label="Auto merge", value=True),80        gr.Textbox(label="Gap max threshold value (seconds)", value=0.350),81        gr.Number(label="Approx Max Segment Length", value=7),82        gr.Number(label="Extend end by (seconds)", value=0),83        gr.Checkbox(label="Extend small segments (minimum 1.02 seconds)", value=False),84        gr.Checkbox(label="Show only duration in labels", value=False)85    ],86    [87        gr.File(label="VAD Labels"),88        gr.File(label="Merged Labels File")89    ]90)91 92if __name__ == "__main__":93    interface.queue().launch()