Untertitel-Übersetzung (Übersetzen von Untertiteln)
Überblick
Übersetzen Sie Untertiteldateien (SRT, ASR-JSON mit Wort-Zeitstempeln oder Video/Audio) in zweisprachige (vereinfachtes Chinesisch + Originalsprache) ASS-Untertitel. Der Ablauf ist fest in 6 Schritten vorgegeben, die vollständig und in der richtigen Reihenfolge ausgeführt werden müssen, ohne Schritte auszulassen oder die Reihenfolge zu ändern:
- Eingabe-Normalisierung + ASR-Transkription (Video/Audio; SRT überspringen; ASR erkennt Sprache automatisch)
- Zeitstempel → YAML (Skript + Modellprüfung, einschließlich Satzteilungs-Plausibilitätsprüfung)
- Korrekturlesen des Originaltextes + erneute Zeitstempel-Prüfung (zweites Abhören, Kreuzvalidierung; Fehler/Drift direkt im YAML korrigieren, inklusive Reparatur durch segmentierte Neutranskription)
- Batch-Übersetzung (Glossar + Anmerkungs-Untertitel)
- Korrekturlesen der Übersetzung
- Zusammenführen zu ASS (Skript)
Die Skripte befinden sich im scripts/-Verzeichnis dieses Skills (auf gleicher Ebene wie SKILL.md). Beim Ausführen eines Skripts bezieht sich <skill_dir> auf das Verzeichnis, in dem sich diese SKILL.md befindet.
Umgebung und Konfiguration
- Erforderlich:
ffmpeg,python(mitpyyaml) sowie das lokale ASR-Tool q3asr (Qwen3-ASR GGUF plattformübergreifende CLI). - Ausführungspriorität:
run_transcribe.py --exe> UmgebungsvariableTRANSCRIBE_EXE> automatischer Download. Standardmäßig automatischer Download: Lädt je nachos/arch/Backenddas q3asr-Binary aus den Releases vonywwzwb/qwen3-asr-universalherunter und speichert es im Cache unter~/.cache/opencode-translate/asr/(erster Download benötigt Internet, danach wird es wiederverwendet). Bei manueller Angabe setzen SieTRANSCRIBE_EXE(Linux/macOS aufq3asr, Windows aufq3asr.exe) und müssen diese Datei nicht ändern.
Arbeitsverzeichnis (temporäre Isolation)
Jeder Übersetzungsauftrag erhält ein eigenes temporäres Arbeitsverzeichnis, in dem alle Zwischenprodukte gesammelt werden. Nach Abschluss wird es auf einen Schlag bereinigt:
- Verzeichnis erstellen:
mkdir -p "$TEMP/opencode/<Basisname der Eingabedatei>"($TEMPist das temporäre Systemverzeichnis, unter Windows%TEMP%, z. B.C:\Users\zwb\AppData\Local\Temp; der Basisname ist der Dateiname ohne Erweiterung). - Die Eingabedatei (Video/Audio/SRT) in dieses Verzeichnis kopieren. Alle folgenden Operationen werden innerhalb dieses Verzeichnisses ausgeführt.
- Alle Zwischenprodukte (mp3, txt, srt, json,
main.yaml,seg*.yamlusw.) werden hier erstellt und verschmutzen nicht das Verzeichnis der Eingabedatei. - Nach Abschluss wird die finale
.ass-Datei in das Verzeichnis der Eingabedatei (oder an einen vom Benutzer angegebenen Ort) kopiert. - Der Benutzer kann zur Bereinigung einfach das gesamte Arbeitsverzeichnis löschen.
Das Glossar bleibt davon unberührt:
terminology.yamlwird global im Skill-Verzeichnis geteilt (siehe Schritt 4) und nicht in das Arbeitsverzeichnis gelegt.
Schritt 1: Eingabe-Normalisierung + ASR-Transkription
Bereiten Sie das Audio je nach Eingabetyp vor:
- Video (mkv/mp4/mov usw.): Zuerst in Mono 16 kHz MP3 konvertieren:
ffmpeg -y -i <input>.mkv -vn -map 0:a:0 -ac 1 -ar 16000 -c:a libmp3lame <input>.mp3 - Audio (mp3/wav/m4a usw.): Ebenfalls in einheitliches Mono 16 kHz mp3 konvertieren, Ausgabe als
<basename>.mono.mp3(z. B.demo.mp3→demo.mono.mp3), um Konflikte mit gleichnamigen Originaldateien zu vermeiden. - SRT: Diesen Schritt überspringen (keine Normalisierung oder ASR nötig), direkt zu Schritt 2 (Zeitstempel → YAML) gehen.
Wenn die Eingabe Audio/Video ist, ASR-Transkription ausführen (immer auf das oben normalisierte mp3 anwenden: Video: <input>.mp3, Audio: <basename>.mono.mp3):
python3 <skill_dir>/scripts/run_transcribe.py <audio>.mp3 -y
Fehlt die ASR-Laufzeit, wird automatisch das passende Zip für
os/arch/Backendaus dem neuesten Release vonywwzwb/qwen3-asr-universalheruntergeladen und unter~/.cache/opencode-translate/asr/zwischengespeichert. Backend automatisch erkennen: Beim ersten Lauf wird die optimale Lösung für den Rechner ermittelt (cuda→vulkan→metal→cpu, basierend auf Existenz vonnvidia-smi/vulkaninfo). Das Ergebnis wird inconfig.yamlim Skill-Verzeichnis gespeichert (wieterminology.yamldauerhaft geteilt) und bei späteren Läufen direkt wiederverwendet; bei Maschinenwechsel wird eine leichte Überprüfung durchgeführt, bei Fehlschlag eine neue Erkennung gestartet. Standardmodell ist 1.7B, gemeinsam mit dem Backend inconfig.yamlgespeichert; beim ersten Lauf von q3asr automatisch heruntergeladen nach~/.cache/q3asr/models/(bei vorhandenem Cache wird dieser wiederverwendet). Überschreiben mit Umgebungsvariablen:TRANSCRIBE_BACKEND(cuda/vulkan/metal/cpu),TRANSCRIBE_MODEL(z. B. 1.7b/0.6b),TRANSCRIBE_ASR_VER(Standard latest). Manuelle Angabe vonTRANSCRIBE_EXEhat weiterhin höchste Priorität.
- Produziert gleichnamige
<audio>.txt,<audio>.srt,<audio>.json(Wort-Zeitstempel[{text,start,end}], in Sekunden). - Segmentierte Neutranskription mit
--out, um Überschreiben der Vollprodukt-Dateien zu vermeiden:run_transcribe.pybenennt.txt/.srt/.jsonnach dem Namen der eingegebenen Audiodatei. Bei einer Fenster-Neutranskription (--seek-start) für dasselbe mp3 würde ohne--outdas Vollprodukt<audio>.jsonüberschrieben werden. Mit--out <Name>(z. B.--out seg1) wird das Audio als<Name>.mp3kopiert und transkribiert, die Ausgabedateien landen als<Name>.jsonusw., das Vollprodukt-JSON bleibt erhalten. - ASR erkennt Sprache automatisch (Qwen3-ASR unterstützt mehrere Sprachen); zum Erzwingen einer Sprache
-l <Sprache>übergeben. - Lange Audiodateien: Zuerst mit
ffprobe -v error -show_entries format=duration -of default=noprint_wrappers=1:nokey=1 <audio>.mp3die Dauer ermitteln und dem Bash-Befehl ein ausreichend großes Timeout geben (lokales 1.7B-Modell etwa 0,05× Audiodauer in Sekunden plus Modellinitialisierung).
Fehlerbehebung
- ASR fehlgeschlagen (Exit-Code ungleich 0): Bei Fehlschlag von
run_transcribe.pywird automatisch das Ende vonlogs/latest.logausgegeben; anhand des Logendes lokalisieren; bei GPU-/Grafikstack-bezogenen Fehlern mit--no-dml --no-vulkanerneut versuchen. - Automatisch heruntergeladene Laufzeit kann nicht starten (z. B. fehlende
libllama.somit FehlerFailed to load dynlib/dll): Eine lokal verfügbare q3asr-Installation oder bereits entpackte Laufzeit verwenden undTRANSCRIBE_EXEdarauf setzen; diese Datei muss nicht geändert werden. - Müllzeichen
!!!/ Bildschirmflackern: UmgebungsvariableGGML_VK_DISABLE_F16=1setzen und erneut transkribieren (Vulkan deaktiviert fp16, um Inkompatibilitäten mit einigen Treibern zu vermeiden). - ffmpeg nicht vorhanden: Sofort stoppen, zuerst ffmpeg installieren und sicherstellen, dass es im PATH ist, dann Schritt 1 fortsetzen.
Schritt 2: Zeitstempel → YAML
Je nach Quelle das passende Skript wählen:
- Audio/Video-Quelle (
<audio>.json): Ausführenpython3 <skill_dir>/scripts/timestamp_to_yaml.py <audio>.json main.yaml(optional--max-widthfür maximale Zeilenbreite, Standard 30;--gapfür Pausenschwelle in Sekunden, Standard 1,5) - SRT-Quelle: Ausführen
python3 <skill_dir>/scripts/srt_to_yaml.py <input>.srt main.yaml
Erzeugt die Zwischendatei main.yaml:
main:
- from: 00:00:02,003
to: 00:00:05,069
en: |
Narrator:
TODAY ON "HOW IT'S MADE"...
- from: 00:00:26,227
to: 00:00:28,026
en: |
ALUMINUM FOIL...
Nach der Konvertierung sofort einen Kollaps-Check durchführen (Skript, unbedingt vor manueller Überprüfung): ASR-Zeitstempel kollabieren häufig – mehrere Cues drängen sich in dieselbe Sekunde (sogar mit Dauer Null), Text ist verstümmelt. Vor der mechanischen Überprüfung zuerst das Skript laufen lassen:
python3 <skill_dir>/scripts/check_collapse.py main.yaml
- Erkennt:
zero(Dauer Null, from==to),cluster(3+ Cues teilen denselben Startzeitpunkt = vollständiger Kollaps),order(Reihenfolge fehlerhaft),overlap(Zeitüberlappungen). - Exit-Code: 0 bei sauberem Zustand, 1 bei Problemen. Bei
zero/clustergemäß Schritt 3 ("Segmentierte Neutranskription als Reparatur") den Bereich behandeln. - Die aus einer Fenster-Neutranskription stammenden
seg*.yaml-Dateien mit--stricterneut prüfen (Alarm schon bei 2 Cues in derselben Sekunde):python3 <skill_dir>/scripts/check_collapse.py seg.yaml --strict– auch die Fenster-Neutranskription selbst kollabiert oft am Ende; vor dem Zusammenfügen zuerst selbst prüfen.
Nach der Konvertierung muss eine Überprüfung (Modellbewertung) erfolgen: Das Skript teilt Sätze automatisch an Punkten, Ausrufezeichen, Fragezeichen oder langen Pausen, teilt zu lange Sätze automatisch nach Breite auf und hat bereits zu kurze Fragmente automatisch zusammengeführt (einsame Fragmente innerhalb eines Satzes werden an benachbarte angehängt, einsame Einzelzeichen ohne Satzendzeichen werden an den nächsten Satz angehängt). Das Konvertierungsskript enthält eine automatische Zusammenführung "hängen gebliebener" Satzteile: ASR/Breitenteilung schneidet Sätze oft an Funktionswörtern ab (Endung mit the/a/to/any/each/boil/known usw.) oder erzeugt nach einem halluzinierten Punkt klein weitergeschriebene Fortsetzungen (plasters./is applied.), oder hinterlässt einzelne Wortköpfe (Plasters/are made of...). timestamp_to_yaml.py führt diese Fragmente automatisch mit dem nächsten Satz zusammen, um den manuellen Arbeitsaufwand zu reduzieren. Bei der Überprüfung: prüfen, ob die Satzteilung natürlich ist; zu lange oder unnatürlich geteilte Sätze neu aufteilen (bevorzugt an weichen Trennstellen wie Aufzählungskommas oder Kommas).
- Extrem kurze Fragmente müssen zusammengeführt werden: Wenn ein Cue nur 1-2 Wörter enthält oder eindeutig ein Fragment aus einem vollständigen Satz ist (z. B. ein einzelnes
Mercury,,The), mit edit in den vorherigen oder nächsten Satz einfügen, sodass jeder Untertitel eine vollständige Sinneinheit bildet. Kurze Titelsätze (Cheese.,Tights.) sind ausgenommen. - Audio/Video-Quelle: Bei erneuter Aufteilung muss das ursprüngliche JSON gelesen werden, um die
from/to-Zeiten jedes Teilfragments anhand der Wort-Token-Start- und Endzeiten zu aktualisieren (SRT hat keine Wort-Zeitstempel, dieser Punkt gilt nicht).
Satzteilungs-Plausibilitätsprüfung (jeden Cue einzeln beurteilen, muss durchgeführt werden): Das Skript teilt mechanisch nach Breite/Pause, schneidet dabei oft Sätze mitten durch. Jeden Cue anhand der folgenden Kriterien prüfen; bei Unangemessenheit mit edit zusammenführen oder Teilungspunkt verschieben:
- Jeder Cue muss eine vollständige Sinneinheit sein: Darf nicht mit einem freistehenden Präposition/ Konjunktion enden. Steht am Zeilenende
and,or,as,where,which,before,to,of,intousw., ist der Teilungspunkt falsch; das Wort sollte in die nächste Zeile oder vollständig zusammengeführt werden. - Teilungspunkte vor Nebensatz-/Parallelkonjunktionen setzen, nicht danach. Beispiel:
assure quantity distribution/before they're carried...(nicht...distribution before/they're carried...);come down 2,000 times per minute/to cut a total of 8,000...(nicht...to cut a/total of 8,000...). - Präpositionalphrasen derselben Sinneinheit nicht trennen:
5 hours of workals Ganzes belassen, nicht in5 hours/of workaufteilen;the brush and roller areanicht inthe brush and/roller areaaufteilen. - Fragment, das erst nach Zusammenführung einen vollständigen Satz ergibt, zusammenführen: Z. B.
...cuts the billet strips into+small, equal-sized pieces.zu einem Cue zusammenführen;...responsible for the+cloudiness of the beer.zusammenführen. - Chinesische Satzteilung spiegelt die englische wider: Die Zeilengrenze der chinesischen Übersetzung sollte mit dem englischen Cue übereinstimmen, das Zeilenende darf ebenfalls nicht freistehend sein (z. B.
按量分配,gefolgt von随后被送往..., sollte随后in die nächste Zeile verschoben werden;落下2000次,切割出sollte geändert werden zu落下2000次/短短60秒内总计切割出8000根). - Nach Zusammenführung/Verschiebung des Teilungspunkts muss das ursprüngliche JSON gelesen werden, um
from/toanhand der Wort-Token-Start- und Endzeiten des neuen Fragments zu aktualisieren.
Schritt 3: Korrekturlesen des Originaltextes
Lesen Sie jedes en-Feld Satz für Satz durch, suchen Sie Rechtschreibfehler, Hörfehler, fehlende Wörter und korrigieren Sie en in main.yaml direkt mit dem edit-Werkzeug. Listen Sie die Änderungspunkte in der Antwort auf. Es ist verboten, nur einen Hinweis zu geben, ohne den Originaltext zu ändern.
Behalten Sie das Standardformat von main.yaml bei ( - from: + en: |-Block, siehe Beispiel in Schritt 2): Nur lokale Edits durchführen, das gesamte File nicht mit Skripten neu formatieren (z. B. yaml.safe_dump neu schreiben), um Einrückungen und Block-Skalar-Format nicht zu beschädigen.
Segmentierte Neutranskription als Reparatur (Halluzinationen/fehlerhafte Zeitstempel)
Finden Sie eine defekte Region (Cue mit ungewöhnlich langer Dauer, Textmüll, Zeitüberlappungen der Cues):
- Fenster wählen: Beginn des defekten Bereichs etwa 3s nach vorne, Ende etwa 3s nach hinten verschieben, erhalte
XundD = Ende - X. - Diesen Abschnitt neutranskribieren (unbedingt mit
--out, sonst wird das Vollprodukt<audio>.jsonüberschrieben):python3 <skill_dir>/scripts/run_transcribe.py <audio>.mp3 --seek-start X --duration D --out seg1 -y(Zeitstempel relativ zum Segmentanfang, Ausgabe istseg1.json). - Selbstprüfung des neu transkribierten Segments:
python3 <skill_dir>/scripts/check_collapse.py seg1.yaml --strict. Fenster-Neutranskription kollabiert oft selbst (mehrere Cues drängen sich in dieselbe Sekunde); beizero/clusterzuerst das Fenster verkleinern und erneut transkribieren, nicht weiter zusammenfügen. - Absolute Zeit wiederherstellen:
python3 <skill_dir>/scripts/timestamp_to_yaml.py seg1.json seg.yaml --offset X(Skript führt hängengebliebene Satzteile automatisch zusammen, siehe Schritt 2). - Abdeckung prüfen: Nach
--offsetsollte dastodes letzten Cues inseg.yaml≈X + Dsein. Deutlich früher alsX + D(Ausgabe der Neutranskription abgeschnitten) → Fenster vergrößern und erneut transkribieren, nicht weiter zusammenfügen. - Zusammenfügen (unbedingt mit Fensterparametern):
python3 <skill_dir>/scripts/splice_yaml.py main.yaml seg.yaml main.new.yaml --seek-start X --duration D. Das Skript löscht basierend auf dem angeforderten Fenster, nicht auf dem Inhaltsbereich des Segments, und überprüft die Abdeckung – falls das neu transkribierte Segment abgeschnitten wurde, meldet das Skript einen Fehler und verweigert das Zusammenfügen (notfalls mit--force, aber zuerst das Fenster vergrößern und erneut transkribieren). - Überprüfung: Ausgabe von splice prüfen (Liste der gelöschten Cues + Wortanzahl-Warnung + LOSS-Zeilen). Jeder splice gibt standardmäßig die Liste der gelöschten Cues aus; erscheint eine
LOSS:-Zeile, bedeutet das, dass der Text eines gelöschten Cues im neu transkribierten Inhalt nicht vorkommt – wenn es ein vollständiger Satz ist, Fenster vergrößern und erneut transkribieren. Erscheint eineBOUNDARY:-Zeile, bedeutet das, dass ein gelöschter Cue die Fenstergrenze überschreitet (Start vor dem Fenster oder Ende nach dem Fenster), sein Inhalt könnte mitten durchgeschnitten worden sein – prüfen, ob das Fenster den Cue tatsächlich abdeckt, sonst Fenster vergrößern und erneut transkribieren. Nach Bestätigung, dass keine Wörter fehlen, mit edit den Inhalt vonmain.yamldurchmain.new.yamlersetzen; bei Wortverlust Fenster vergrößern und erneut transkribieren oder manuell mit edit korrigieren.
Zusammenfügen unbedingt mit splice_yaml.py, manuelles Einfügen neu transkribierter Segmente verboten: Das manuelle Einfügen neuer Cues in main.yaml führt leicht zu doppelten/überlappenden Cues (derselbe from erscheint zweimal); das Ersetzen über das Zeitfenster mit dem Skript vermeidet dies. Tritt nach dem Ersetzen ein doppelter from auf, wurde zu viel zusammengefügt; mit splice wiederholen.
Erneute Zeitstempel-Prüfung (zweites Abhören, Kreuzvalidierung)
Zwei aufeinanderfolgende Transkriptionen derselben Audiodatei ergeben deutlich driftende Wort-Zeitstempel (gemessen: max delta zwischen zwei Durchläufen kann Dutzende Sekunden betragen, einige Cues unterscheiden sich um 12-40s). Daher sind die Zeitstempel aus einem Durchlauf nicht vollständig vertrauenswürdig. Nach der Erstellung des YAML muss ein zweiter vollständiger Transkriptionsdurchlauf durchgeführt werden, um die Zeitstempel mit den aktuellen Cues kreuzzuvalidieren:
- Audio für zweiten Durchlauf kopieren (erstes JSON nicht überschreiben):
cp <audio>.mp3 <audio>.pass2.mp3, dannpython3 <skill_dir>/scripts/run_transcribe.py <audio>.pass2.mp3 -y, Ausgabe<audio>.pass2.json(oder--out pass2verwenden, um das manuelle cp zu sparen, gleicher Effekt). - Cue für Cue prüfen:
python3 <skill_dir>/scripts/compare_timestamps.py main.yaml <audio>.pass2.json --threshold 1.0. Das Skript lokalisiert dasenjedes Cues anhand des normalisierten Texts in den Wort-Token des zweiten Durchlaufs und gibtdelta start/endaus (Zeit des aktuellen Cues − Wort-Zeit des zweiten Durchlaufs) mit<<<-Markierung. Standardschwelle ist 1,0s (der zweite Durchlauf driftet selbst, 0,5s ergäbe zu viele falsch Positive). - Bei Cues mit
<<<oderNOT FOUNDpräzise Korrektur durchführen: Das zweite Abhören ist nur ein Detektor, keine Autorität – es driftet selbst (das gesamte Segment kann insgesamt versetzt sein), daher dürfen die Zeitstempel des zweiten Durchlaufs nicht direkt zur Korrektur vonfrom/toverwendet werden. Stattdessen immer nach dem oben beschriebenen Ablauf "Segmentierte Neutranskription als Reparatur" für dieses Fenster vorgehen: Fenster etwa 3s vor und nach dem Cue neu transkribieren → mit--offsetabsolute Zeit wiederherstellen → mitsplice_yaml.pyzusammenfügen, das Ergebnis der Fenster-Neutranskription als maßgeblich verwenden. Stimmt die Fenster-Neutranskription mit dem zweiten Durchlauf überein, sind die Zeiten im Haupt-YAML tatsächlich falsch; korrigieren. Bestätigt sie, dass das Haupt-YAML richtig ist, nicht ändern. - Kreuzvalidierung auf der Übersetzungsseite:
compare_timestamps.pykann mit--fullfür jedes YAML die Deltas aller Cues ausgeben, um den Drift-Trend insgesamt zu erfassen. - Wiederholen, bis keine
<<<und keineNOT FOUNDmehr vorhanden sind (oder manuell bestätigt).
Hinweis: Auch das zweite Abhören kann selbst driften oder abweichenden Text liefern (daher
NOT FOUND), daher ist letztlich die segmentierte Fenster-Neutranskription + manuelles Abhören maßgeblich;compare_timestamps.pyist nur ein Detektor, um verdächtige Cues schnell zu finden.
Schritt 4: Batch-Übersetzung
Vor Beginn der Übersetzung <skill_dir>/terminology.yaml lesen (leere Datei erstellen, falls nicht vorhanden). Das Glossar befindet sich im Verzeichnis dieses Skills (bei globaler Installation maschinenweit) und wird über Videos, Projekte und Sitzungen hinweg dauerhaft geteilt, um eine konsistente Übersetzung von Personen-/Orts-/Eigennamen in verschiedenen Videos zu gewährleisten. Wenn während der Übersetzung ein neuer Begriff auftaucht, diesen zuerst in <skill_dir>/terminology.yaml eintragen und dann verwenden; die Groß-/Kleinschreibung wird ignoriert.
Hinweis: Wenn
<skill_dir>sich vom aktuellen Projekt unterscheidet (globale Installation), ist das Glossar die einzige globale Instanz; es wird kein separatesterminology.yamlim Projekt gepflegt.
Die Übersetzung erfolgt im strukturierten Batch-Output mit Skript-Schreiben, nicht Satz für Satz mit edit:
- Batch-Übersetzung (max. 50 Sätze pro Batch): In der Antwort einen strukturierten Übersetzungsblock ausgeben –
startist die 0-basierte Cue-Nummer des ersten Satzes dieses Batches inmain.yaml,translation-Liste entspricht Satz für Satz in der gleichen Reihenfolge wie die Cues in main.yaml. Es ist verboten, auf einmal die Übersetzung aller Untertitel auszugeben. Nach Fertigstellung eines Batches und Bestätigung (Skript-Schreiben + Stichprobenprüfung) den nächsten Batch bearbeiten.
start: 0 # Cue-Nummer des ersten Satzes dieses Batches (0-basiert)
translation:
- Übersetzung Satz 1
- Übersetzung Satz 2
- |
Erste Zeile der mehrzeiligen Übersetzung
Zweite Zeile der mehrzeiligen Übersetzung
- Übersetzung Satz 4
-
Skript-Schreiben: Den obigen strukturierten Block als
batch.yamlspeichern (im Arbeitsverzeichnis) und ausführen:python3 <skill_dir>/scripts/apply_translations.py main.yaml batch.yaml main.new.yamlDas Skript fügt daschs-Feld präzise nach jedemen-Block anhand der Cue-Nummer ein, ohne die Datei neu zu formatieren (nicht safe_dump), Anmerkungen und andere Zeilen bleiben unverändert. Nach Prüfungcp main.new.yaml main.yaml.--overwrite: Vorhandene chs ersetzen (Standardmäßig wird bei vorhandenem chs ein Fehler gemeldet, um versehentliches stilles Überschreiben zu verhindern)--dry-run: Nur ausgeben, wie viele Einträge geschrieben würden, ohne zu speichern- Das Skript prüft, ob
start + Anzahlden Rahmen nicht überschreitet; bei Überschreitung Fehlermeldung, anhalten undstartprüfen
-
Vor dem endgültigen Übernehmen der Übersetzung selbst prüfen: Jede Übersetzung muss die unten stehenden Übersetzungsregeln einhalten (kein Punkt/Komma am Satzende, Zahlen arabisch, Glossar-Konsistenz, Zeilengrenzen spiegeln englischen Cue wider). Nach Fertigstellung eines Batches manuell die ersten und letzten Übersetzungen des Batches stichprobenartig prüfen und bestätigen, dass die Cue-Nummern mit dem Inhalt übereinstimmen (insbesondere prüfen, ob
startim Übersetzungsblock gleichstart + Anzahl des vorherigen Batchesist).
Die endgültige Prüfung erfolgt dennoch mit dem edit-Werkzeug Satz für Satz – das Batch-Schreiben dient zum "Einfüllen", die manuelle edit zum "Feintuning".
main:
- from: 00:00:02,003
to: 00:00:05,069
en: |
Narrator:
TODAY ON "HOW IT'S MADE"...
chs: |
旁白:
今天的《造物小百科》……
Übersetzungsregeln
- Sinngemäße Übersetzung priorisieren, nicht wortwörtlich. Wortstellung und Position je nach chinesischem Satzbau und Satzlänge anpassen; Sätze können zusammengefasst oder geteilt werden, um einen flüssigen und natürlichen chinesischen Satz zu gewährleisten.
- Eigennamen einheitlich über das Glossar verwenden. Personen-, Orts-, Werk-, Markennamen usw. in
terminology.yamleinheitlich übersetzen und vor jeder Übersetzung zuerst lesen. Die Begriffssuche ignoriert Groß-/Kleinschreibung. Neue Begriffe vor der Verwendung zuerst zum Glossar hinzufügen:
terminology:
Susan: 苏珊
Texas: 德州
HOW IT'S MADE: 造物小百科
- Satzendzeichen. Wenn das letzte Zeichen eines Übersetzungstextes ein Punkt
。oder ein Komma (vollbreit,oder halbbreit,) ist, dieses direkt entfernen. Beispiel: "欢迎收看本期节目。" → "欢迎收看本期节目". Punkte/Kommas sind nur im Satzinneren erlaubt, nicht als Satzendezeichen der Übersetzung. - Zahlen in arabischen Ziffern schreiben. Zahlen in der Übersetzung nach Möglichkeit in arabischen Ziffern schreiben: 三到八小时 → 3-8 小时、二十年前 → 20 年前、六千克面粉 → 6000 克面粉、百分之九十五 → 95%、四点四米 → 4.4 米、750 摄氏度 → 750 摄氏度. Ausgenommen sind Zahlen in Eigennamen/Titeln (z. B. "How It's Made", Jahreszahlen, Modelle).
- Anmerkungs-Untertitel. Bei im chinesischen Kontext seltenen lokalen Bräuchen, Feiertagen, Fachbegriffen, angloamerikanischen Maßeinheiten usw. im Untertitel eine kurze Anmerkung von maximal 20 Zeichen (etwa 4 Zeichen pro Sekunde) hinzufügen und in die
annotations-Liste inmain.yamleintragen. Derselbe Begriff wird nur beim ersten Auftreten mit einer Anmerkung versehen.
annotations:
- from: 00:00:02,003
text: 造物小百科:科普纪录片栏目
Anmerkungsregeln:
- Jede Anmerkung maximal 20 Zeichen, so präzise wie möglich.
frommit der Startzeit des entsprechenden Untertitel-Cues abgleichen.tomuss nicht ausgefüllt werden;yaml_to_ass.pyberechnet die Endzeit automatisch mit 4 Zeichen/Sekunde.- Treten bei demselben Satz (gleiche Startzeit) mehrere Anmerkungen auf, führt das Skript diese zu einem Ereignis zusammen, das übereinander angezeigt wird.
- Überschreitet die Endzeit einer Anmerkung die Startzeit der nächsten, klemmt das Skript die Endzeit der vorherigen auf den Beginn der nächsten (vor dieser), um zeitliche Überlappungen zu vermeiden.
- Angloamerikanische Maßeinheiten: Die Anmerkung gibt direkt die standardisierte SI-Einheitenumrechnung für den konkreten Zahlenwert des Satzes an, z. B. "500磅≈227公斤", "60英里≈96.6公里/时", "62°F≈17°C"; erklärt nicht die Bedeutung der Einheit selbst (wie "britische Gewichtseinheit"). Bei Einheitenumrechnungen wird ≈ zur Angabe der Näherung verwendet; unterschiedliche Zahlenwerte müssen jedes Mal umgerechnet werden, Ausnahme "nur beim ersten Auftreten" gilt hier nicht.
Schritt 5: Korrekturlesen der Übersetzung
Alle chs vollständig durchlesen, auf Übersetzungsfehler, Auslassungen, inkonsistente Terminologie, falsche Zeitachsen prüfen und mit dem edit-Werkzeug korrigieren.
Nach dem Korrekturlesen das gesamte main.yaml noch einmal durchgehen und Zahlen, die sich für arabische Ziffern eignen, direkt mit edit in arabische Ziffern umwandeln:
- Zahlen als englische Wörter in
en(Hörtranskript):three to eight hours→3 to 8 hours、six thousand kilos→6,000 kilos、twenty years ago→20 years ago、half a centimeter→0.5 centimeter、seventy-five→75、first/second→1st/2nd. - Zahlen als chinesische Zeichen in
chs(Übersetzung): 二十年前 → 20 年前、三到八小时 → 3-8 小时、六千公斤 → 6000 公斤、百分之九十五 → 95%、四点四米 → 4.4 米. - Zahlen in Eigennamen/Titeln/Jahreszahlen/Modellen unverändert lassen (z. B. "How It's Made", Jahreszahlen in
Narrator:). - Nur eindeutige Fälle ändern; bei Unsicherheit den Originaltext beibehalten.
Schritt 6: Zusammenführen zu ASS
Ausführen: python3 <skill_dir>/scripts/yaml_to_ass.py main.yaml output.ass --check
--check prüft die Cue-Integrität (Überlappungen / Dauer Null / Reihenfolgefehler); bei Fehlern wird eine Meldung ausgegeben und das Programm beendet, um die Ausgabe einer fehlerhaften Datei zu verhindern. Nach dem Zusammenführen die fertige .ass-Datei in das Verzeichnis der Eingabedatei kopieren (z. B. neben das Video), damit der Benutzer sie direkt verwenden kann; die Zwischenprodukte im Arbeitsverzeichnis kann der Benutzer nach Bedarf bereinigen.
Erzeugtes Format (Vorlage ist im Skript eingebettet, die wichtigsten Punkte sind):
[Script Info]
ScriptType: v4.00+
PlayResX: 1920
PlayResY: 1080
WrapStyle: 2
[V4+ Styles]
Format: Name, Fontname, Fontsize, PrimaryColour, SecondaryColour, OutlineColour, BackColour, Bold, Italic, Underline, StrikeOut, ScaleX, ScaleY, Spacing, Angle, BorderStyle, Outline, Shadow, Alignment, MarginL, MarginR, MarginV, Encoding
Style: Translation,Noto Sans CJK SC,56,&H00FFFFFF,&H000000FF,&H00141414,&H80000000,-1,0,0,0,100,100,0,0,1,3,1,2,80,80,81,1
Style: Original,Noto Sans CJK SC,36,&H00FFFFFF,&H000000FF,&H00141414,&H80000000,-1,0,0,0,100,100,0,0,1,2,1,2,80,80,45,1
Style: Annotation,Noto Sans CJK SC,26,&H00FFE066,&H000000FF,&H00141414,&H80000000,-1,0,0,0,100,100,0,0,1,1,1,7,40,40,20,1
[Events]
Format: Layer, Start, End, Style, Name, MarginL, MarginR, MarginV, Effect, Text
Ausgabe als drei unabhängige Spuren, um eine nachträgliche Anpassung der Stile Spur für Spur zu ermöglichen (jede Spur verwendet eigene Layer und Styles, können in Aegisub/Schnittsoftware separat bearbeitet werden):
| Layer | Style | Inhalt | Schriftgröße/Position |
|---|---|---|---|
| 0 | Translation | Vereinfachtes Chinesisch (Übersetzung) | fs56, Hauptzeile unten |
| 1 | Original | Text in Originalsprache | fs36, direkt unter der Übersetzung |
| 2 | Annotation | Anmerkung | fs26, obere linke Ecke |
Layout-Anforderungen:
- Übersetzung ist primär: Große Schrift unten (Layer 0).
- Original ist sekundär: Kleine Schrift unter der Übersetzung (Layer 1).
- Anmerkungen in der oberen linken Ecke (Layer 2, Alignment 7).
Beispielereignis:
Dialogue: 0,0:00:02.00,0:00:05.06,Translation,,0,0,0,,今天的《造物小百科》……
Dialogue: 1,0:00:02.00,0:00:05.06,Original,,0,0,0,,Narrator: TODAY ON "HOW IT'S MADE"...
Dialogue: 2,0:00:02.00,0:00:03.62,Annotation,,0,0,0,,造物小百科:科普纪录片栏目
Häufige Fehler (Common Mistakes)
| Fehler | Richtiges Vorgehen |
|---|---|
| YAML übersprungen und direkt ASS ausgegeben | Erst main.yaml konvertieren, dann übersetzen, dann zusammenführen |
| ASS manuell statt per Skript geschrieben | Mit yaml_to_ass.py zusammenführen, Anmerkungszeiten werden vom Skript berechnet |
| Vor ASS-Ausgabe keine Integritätsprüfung | Mit yaml_to_ass.py --check auf Überlappungen/Dauer Null/Reihenfolgefehler prüfen |
| Alle Untertitel auf einmal übersetzt | Max. 50 Sätze pro Batch, strukturierten Übersetzungsblock ausgeben, per Skript schreiben |
| chs einzeln mit edit geschrieben | Mit apply_translations.py batch-schreiben, edit nur für die endgültige Prüfung verwenden |
Batch-start-Nummer falsch | start muss = start des vorherigen Batches + Anzahl des vorherigen Batches sein; bei Überschreitung meldet das Skript einen Fehler |
| Vorhandene Übersetzung still überschrieben | Standardmäßig wird bei vorhandenem chs ein Fehler gemeldet; nur bei sicherer Notwendigkeit --overwrite verwenden |
| Inkonsistente Übersetzung von Personen-/Ortsnamen | In terminology.yaml eintragen, vor jeder Übersetzung zuerst lesen |
| Anmerkung länger als 20 Zeichen | Kürzen, nur notwendige Informationen behalten |
| Endzeit der Anmerkung willkürlich eingetragen | Vom Skript mit 4 Zeichen/Sekunde berechnen lassen |
| Mehrere Anmerkungen zum selben Satz nicht übereinander angezeigt | Skript führt automatisch zu zwei übereinanderliegenden Zeilen zusammen |
| Trennungspräpositionen am Zeilenende nicht korrigiert | Splice-Punkte an Konjunktionen/Nebensatzgrenzen setzen, nicht nach freistehenden Präpositionen |
| Nach Zusammenführung/Verschiebung des Teilungspunkts keine Zeitaktualisierung | Ursprüngliches JSON lesen und from/to aktualisieren |
| Im zweiten Durchlauf gefundene Abweichungen nicht korrigiert | compare_timestamps.py ist nur ein Detektor; Korrektur durch segmentierte Fenster-Neutranskription |
Ausführungsreihenfolge (Ablauf)
- Schritt 1: Eingabe normalisieren + ASR-Transkription (für Video/Audio)
- Schritt 2: Zeitstempel → YAML konvertieren + Kollaps-Check + Satzteilungs-Plausibilitätsprüfung
- Schritt 3: Originaltext Korrektur lesen + erneute Zeitstempel-Prüfung (zweites Abhören) + segmentierte Neutranskription (falls nötig)
- Schritt 4: Batch-Übersetzung (Glossar + Anmerkungs-Untertitel)
- Schritt 5: Übersetzung Korrektur lesen + Zahlen normalisieren
- Schritt 6: Zusammenführen zu ASS + Ausgabe-Kopie
Jeder Schritt muss nacheinander ausgeführt werden, keine Schritte überspringen oder die Reihenfolge vertauschen.