Add audio transcription workflow (faster-whisper) and gitignore for raw audio
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
"""
|
||||
Transcribe course book listening-exercise audio to German text using
|
||||
faster-whisper (GPU-accelerated via CTranslate2).
|
||||
|
||||
Setup (one time):
|
||||
pip install faster-whisper
|
||||
|
||||
Usage:
|
||||
python transcribe.py <path-to-audio-folder> <path-to-output-folder>
|
||||
|
||||
Example:
|
||||
python transcribe.py "D:/MenschenA1.1/audio/Lektion01" "../A1.1/course-book/transcripts/lektion-01"
|
||||
|
||||
Each audio file gets a matching .txt file with the same basename.
|
||||
Review the output — ASR on textbook dialogue audio is generally good but can
|
||||
mangle names, numbers, and fast/overlapping speech. Correct those before
|
||||
committing.
|
||||
"""
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
from faster_whisper import WhisperModel
|
||||
|
||||
# "large-v3" is most accurate; drop to "medium" if VRAM is limited (~5GB vs ~10GB).
|
||||
MODEL_SIZE = "large-v3"
|
||||
DEVICE = "cuda"
|
||||
COMPUTE_TYPE = "float16" # use "int8_float16" if you run out of VRAM
|
||||
|
||||
AUDIO_EXTENSIONS = {".mp3", ".wav", ".m4a", ".ogg", ".flac"}
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if len(sys.argv) != 3:
|
||||
print(__doc__)
|
||||
sys.exit(1)
|
||||
|
||||
audio_dir = Path(sys.argv[1])
|
||||
out_dir = Path(sys.argv[2])
|
||||
out_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
model = WhisperModel(MODEL_SIZE, device=DEVICE, compute_type=COMPUTE_TYPE)
|
||||
|
||||
audio_files = sorted(
|
||||
p for p in audio_dir.iterdir() if p.suffix.lower() in AUDIO_EXTENSIONS
|
||||
)
|
||||
if not audio_files:
|
||||
print(f"No audio files found in {audio_dir}")
|
||||
return
|
||||
|
||||
for audio_path in audio_files:
|
||||
print(f"Transcribing {audio_path.name} ...")
|
||||
segments, info = model.transcribe(str(audio_path), language="de", beam_size=5)
|
||||
|
||||
out_path = out_dir / (audio_path.stem + ".txt")
|
||||
with out_path.open("w", encoding="utf-8") as f:
|
||||
for segment in segments:
|
||||
f.write(f"[{segment.start:6.1f}s] {segment.text.strip()}\n")
|
||||
|
||||
print(f" -> {out_path}")
|
||||
|
||||
print("\nDone. Review transcripts for ASR errors before committing.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user