| import gradio as gr |
| import whisperx |
| import torch |
| import json |
| import numpy as np |
|
|
| device = "cuda" if torch.cuda.is_available() else "cpu" |
|
|
| def align_words(audio_file, transcript): |
| audio = whisperx.load_audio(audio_file) |
|
|
| |
| FRAME = 160 |
| THRESH = 0.001 |
| speech_start = 0 |
| for i in range(0, len(audio) - FRAME, FRAME): |
| if float(np.sqrt(np.mean(audio[i:i+FRAME]**2))) > THRESH: |
| speech_start = i |
| break |
| audio_trimmed = np.ascontiguousarray(audio[speech_start:], dtype=np.float32) |
|
|
| |
| segments = [{"text": transcript, "start": 0, "end": 9999}] |
| model_a, metadata = whisperx.load_align_model(language_code="en", device=device) |
| result = whisperx.align(segments, model_a, metadata, audio_trimmed, device) |
|
|
| |
| output = [] |
| for w in result["word_segments"]: |
| start = w["start"] |
| end = w["end"] |
|
|
| |
| if start > 500: |
| start = round(start / 1000, 3) |
| end = round(end / 1000, 3) |
| else: |
| start = round(start, 3) |
| end = round(end, 3) |
|
|
| output.append({"word": w["word"], "start": start, "end": end}) |
|
|
| return json.dumps(output, indent=2) |
|
|
| demo = gr.Interface( |
| fn=align_words, |
| inputs=[ |
| gr.Audio(type="filepath", label="Audio"), |
| gr.Textbox(lines=10, label="Exact Transcript") |
| ], |
| outputs=gr.Textbox(label="Word Timestamps JSON"), |
| title="Fast Word Timestamp Alignment" |
| ) |
| demo.launch() |