Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -45,13 +45,11 @@ def create_vtt(segments, file_path):
|
|
| 45 |
with open(file_path, "w", encoding="utf-8") as f:
|
| 46 |
f.write("WEBVTT\n\n")
|
| 47 |
for i, segment in enumerate(segments):
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
start = str(datetime.timedelta(seconds=int(start_seconds)))
|
| 51 |
-
end = str(datetime.timedelta(seconds=int(end_seconds)))
|
| 52 |
f.write(f"{i+1}\n")
|
| 53 |
f.write(f"{start} --> {end}\n")
|
| 54 |
-
f.write(f"{segment
|
| 55 |
|
| 56 |
def create_docx(segments, file_path, with_timestamps):
|
| 57 |
document = Document()
|
|
@@ -59,14 +57,11 @@ def create_docx(segments, file_path, with_timestamps):
|
|
| 59 |
|
| 60 |
if with_timestamps:
|
| 61 |
for segment in segments:
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
start = str(datetime.timedelta(seconds=int(start_seconds)))
|
| 66 |
-
end = str(datetime.timedelta(seconds=int(end_seconds)))
|
| 67 |
-
document.add_paragraph(f"[{start} - {end}] {text}")
|
| 68 |
else:
|
| 69 |
-
full_text = " ".join([segment
|
| 70 |
document.add_paragraph(full_text)
|
| 71 |
|
| 72 |
document.save(file_path)
|
|
@@ -84,21 +79,41 @@ def chunk_audio_numpy(file_path, chunk_length_ms=60000):
|
|
| 84 |
chunks.append((samples, len(chunk) / 1000)) # (array, duration_sec)
|
| 85 |
return chunks
|
| 86 |
|
| 87 |
-
def transcribe_long_audio(pipe, file_path, chunk_length_ms=60000):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 88 |
chunks = chunk_audio_numpy(file_path, chunk_length_ms)
|
| 89 |
segments = []
|
| 90 |
offset = 0
|
| 91 |
|
| 92 |
for samples, duration_sec in chunks:
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 99 |
offset += duration_sec
|
| 100 |
|
| 101 |
-
full_text = " ".join([seg[
|
| 102 |
return segments, full_text
|
| 103 |
|
| 104 |
# -------------------------
|
|
@@ -114,8 +129,11 @@ def transcribe_and_export(audio_file, model_size, vtt_output, docx_timestamp_out
|
|
| 114 |
pipe = get_model_pipeline(model_size, progress)
|
| 115 |
progress(0.75, desc="🎤 Transcribing audio...")
|
| 116 |
|
|
|
|
|
|
|
|
|
|
| 117 |
# Transcribe using chunked NumPy arrays
|
| 118 |
-
segments, transcribed_text = transcribe_long_audio(pipe, audio_file)
|
| 119 |
|
| 120 |
outputs = {}
|
| 121 |
progress(0.85, desc="📝 Generating output files...")
|
|
|
|
| 45 |
with open(file_path, "w", encoding="utf-8") as f:
|
| 46 |
f.write("WEBVTT\n\n")
|
| 47 |
for i, segment in enumerate(segments):
|
| 48 |
+
start = str(datetime.timedelta(seconds=int(segment["start"])))
|
| 49 |
+
end = str(datetime.timedelta(seconds=int(segment["end"])))
|
|
|
|
|
|
|
| 50 |
f.write(f"{i+1}\n")
|
| 51 |
f.write(f"{start} --> {end}\n")
|
| 52 |
+
f.write(f"{segment['text'].strip()}\n\n")
|
| 53 |
|
| 54 |
def create_docx(segments, file_path, with_timestamps):
|
| 55 |
document = Document()
|
|
|
|
| 57 |
|
| 58 |
if with_timestamps:
|
| 59 |
for segment in segments:
|
| 60 |
+
start = str(datetime.timedelta(seconds=int(segment["start"])))
|
| 61 |
+
end = str(datetime.timedelta(seconds=int(segment["end"])))
|
| 62 |
+
document.add_paragraph(f"[{start} - {end}] {segment['text'].strip()}")
|
|
|
|
|
|
|
|
|
|
| 63 |
else:
|
| 64 |
+
full_text = " ".join([segment['text'].strip() for segment in segments])
|
| 65 |
document.add_paragraph(full_text)
|
| 66 |
|
| 67 |
document.save(file_path)
|
|
|
|
| 79 |
chunks.append((samples, len(chunk) / 1000)) # (array, duration_sec)
|
| 80 |
return chunks
|
| 81 |
|
| 82 |
+
def transcribe_long_audio(pipe, file_path, chunk_length_ms=60000, language=None):
|
| 83 |
+
"""
|
| 84 |
+
Transcribe long audio in chunks.
|
| 85 |
+
language: optional, e.g., 'fr' for French, 'en' for English
|
| 86 |
+
"""
|
| 87 |
chunks = chunk_audio_numpy(file_path, chunk_length_ms)
|
| 88 |
segments = []
|
| 89 |
offset = 0
|
| 90 |
|
| 91 |
for samples, duration_sec in chunks:
|
| 92 |
+
kwargs = {"return_timestamps": True}
|
| 93 |
+
if language:
|
| 94 |
+
kwargs["language"] = language
|
| 95 |
+
|
| 96 |
+
raw_output = pipe(samples, **kwargs)
|
| 97 |
+
|
| 98 |
+
# Depending on HF version, segments may be in 'chunks' or 'segments'
|
| 99 |
+
if "chunks" in raw_output:
|
| 100 |
+
seg_list = raw_output["chunks"]
|
| 101 |
+
elif "segments" in raw_output:
|
| 102 |
+
seg_list = raw_output["segments"]
|
| 103 |
+
else:
|
| 104 |
+
# fallback: entire text as one segment
|
| 105 |
+
seg_list = [{"start": 0, "end": duration_sec, "text": raw_output.get("text", "")}]
|
| 106 |
+
|
| 107 |
+
# Make sure start/end exist
|
| 108 |
+
for seg in seg_list:
|
| 109 |
+
start = seg.get("start", 0)
|
| 110 |
+
end = seg.get("end", duration_sec)
|
| 111 |
+
text = seg.get("text", "")
|
| 112 |
+
segments.append({"start": start + offset, "end": end + offset, "text": text})
|
| 113 |
+
|
| 114 |
offset += duration_sec
|
| 115 |
|
| 116 |
+
full_text = " ".join([seg["text"] for seg in segments])
|
| 117 |
return segments, full_text
|
| 118 |
|
| 119 |
# -------------------------
|
|
|
|
| 129 |
pipe = get_model_pipeline(model_size, progress)
|
| 130 |
progress(0.75, desc="🎤 Transcribing audio...")
|
| 131 |
|
| 132 |
+
# Determine language: French-specific model defaults to 'fr'
|
| 133 |
+
language = "fr" if "FR" in model_size else None
|
| 134 |
+
|
| 135 |
# Transcribe using chunked NumPy arrays
|
| 136 |
+
segments, transcribed_text = transcribe_long_audio(pipe, audio_file, language=language)
|
| 137 |
|
| 138 |
outputs = {}
|
| 139 |
progress(0.85, desc="📝 Generating output files...")
|