feat: extract_text.py – YouTube-URL → Textdatei in einem Schritt
- Kombiniert yt_untertitel.py und vtt2txt.py; die VTT bleibt temporär - Standardsprache ist die des Original-Audios (original_language()) - -o Ausgabedatei, Standard output.txt - Tests ohne Netz, README Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
b0b79515ca
commit
ba61434798
1 changed files with 246 additions and 5 deletions
77
extract_text.py
Executable file
77
extract_text.py
Executable file
|
|
@ -0,0 +1,77 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Lädt die Untertitel eines YouTube-Videos und speichert ihren Text als Datei
|
||||
(yt_untertitel.py + vtt2txt.py in einem Schritt)."""
|
||||
from pathlib import Path
|
||||
import argparse
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
from vtt2txt import vtt_to_lines
|
||||
from yt_untertitel import (
|
||||
YT_DLP, available_tracks, choose_track, download, fetch_info, original_language,
|
||||
)
|
||||
|
||||
|
||||
def parse_args():
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Lädt die Untertitel eines YouTube-Videos und speichert den Text."
|
||||
)
|
||||
parser.add_argument("-u", "--url", required=True, help="YouTube-URL des Videos")
|
||||
parser.add_argument(
|
||||
"-l", "--lang",
|
||||
help="Sprache der Untertitel, z. B. de (Standard: Sprache des Original-Audios)",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-o", "--output", type=Path, default=Path("output.txt"),
|
||||
help="Ausgabedatei (Standard: output.txt)",
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.output.is_dir():
|
||||
parser.error(f"-o/--output ist ein Verzeichnis: {args.output}")
|
||||
if shutil.which(YT_DLP) is None:
|
||||
parser.error(f"{YT_DLP} nicht gefunden (Installation: pip install yt-dlp).")
|
||||
return args
|
||||
|
||||
|
||||
def main():
|
||||
args = parse_args()
|
||||
|
||||
info = fetch_info(args.url)
|
||||
print(f"Video: {info.get('title', '?')}")
|
||||
|
||||
lang = args.lang or original_language(info)
|
||||
chosen = choose_track(info, lang) if lang else None
|
||||
if chosen is None:
|
||||
manual, original = available_tracks(info)
|
||||
wanted = f"„{lang}“" if lang else "der Originalsprache"
|
||||
raise SystemExit(
|
||||
f"Keine Untertitel in {wanted} (weder manuell noch automatisch in "
|
||||
f"Originalsprache).\n"
|
||||
f"Manuell: {', '.join(manual) or '–'}\n"
|
||||
f"Automatisch (Originalsprache): {', '.join(original) or '–'}"
|
||||
)
|
||||
track, is_auto = chosen
|
||||
kind = "automatische" if is_auto else "manuelle"
|
||||
print(f"Lade {kind} Untertitel „{track}“ …", flush=True)
|
||||
|
||||
# The VTT file is only an intermediate step
|
||||
with tempfile.TemporaryDirectory() as tmp:
|
||||
target_base = Path(tmp) / "untertitel"
|
||||
download(args.url, track, is_auto, target_base)
|
||||
vtt = Path(f"{target_base}.{track}.vtt")
|
||||
if not vtt.is_file():
|
||||
raise SystemExit("yt-dlp hat keine Untertitel-Datei geschrieben.")
|
||||
lines = vtt_to_lines(vtt.read_text(encoding="utf-8-sig"))
|
||||
|
||||
if not lines:
|
||||
raise SystemExit("Die Untertitel enthalten keinen Text.")
|
||||
|
||||
args.output.parent.mkdir(parents=True, exist_ok=True)
|
||||
args.output.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
||||
words = sum(len(line.split()) for line in lines)
|
||||
print(f"Gespeichert: {args.output} ({len(lines)} Zeilen, {words} Wörter)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Loading…
Reference in a new issue