Transkriptformate
Alle Transkript- und Untertitelformate, die Potato liest: Whisper, WhisperX, Deepgram, AssemblyAI, AWS Transcribe, SRT, WebVTT, TTML, YouTube-Untertitel, CTM, Praat TextGrid und ELAN EAF, dazu Begleitdateien und das normalisierte Turn-Modell.
Potato liest 21 Transkript- und Untertiteleingaben und überführt sie alle in dasselbe Turn-Modell, bevor überhaupt etwas angezeigt wird. Was auch immer Ihre ASR-Pipeline oder Ihr Untertitelwerkzeug produziert hat, Sie können Potato darauf ansetzen, ohne ein Konvertierungsskript zu schreiben. Diese Seite ist die Referenz dafür, was funktioniert, wie jedes Format erkannt wird und was es jeweils mitbringt. Die Schritt-für-Schritt-Anleitungen sind Whisper-Transkripte annotieren und YouTube-Untertitel annotieren.
Eine SRT-Begleitdatei als Sprecherblasen, mit einer Frage an jedem Turn
Potato transkribiert nicht
Spracherkennung und Sprecherdiarisierung laufen, bevor Potato etwas zu sehen bekommt. Führen Sie zuerst Whisper, WhisperX, pyannote oder eine Cloud-API aus; Potato liest das Ergebnis ein. Nichts auf dieser Seite startet ein Modell.
Note: Der Think-Aloud-Modus führt sehr wohl ein lokales Whisper-Modell aus, aber zu einem anderen Zweck: Er nimmt Annotierende auf, während sie beim Arbeiten sprechen. Das ist eine Aufnahmefunktion, keine Transkriptverarbeitung.
Erkennung erfolgt über den Inhalt, nicht über die Dateiendung
Potato sieht sich an, was in der Datei steht, statt dem Namen zu vertrauen. Eine WebVTT-Datei namens captions.txt wird weiterhin als WebVTT gelesen. Praktisch heißt das: Dasselbe Transkript funktioniert eingebettet in Ihrer Datendatei oder als Begleitdatei auf der Festplatte, ohne Änderung an der Konfiguration.
Unterstützte Formate
ASR-Ausgaben
| Format | Erkannt an | Sprecher | Wortzeiten |
|---|---|---|---|
| Whisper JSON | Array segments | Nein | Ja, mit --word_timestamps |
| WhisperX / diarisiertes JSON | segments mit speaker | Ja | Ja |
| whisper.cpp JSON | Array transcription | Nein | Nein |
| Whisper TSV | Kopfzeile start/end/text | Nein | Nein |
| AWS Transcribe | results.items oder results.audio_segments | Ja | Ja |
| Deepgram | results.channels oder results.utterances | Ja, mit diarize=true | Ja |
| AssemblyAI | text plus words/utterances | Ja, mit speaker_labels | Ja |
| Rev.ai | Array monologues | Ja | Ja |
| SPoRC | Zeilen turn_text/turnText | Ja, abgeleitet | Nein |
Untertitel
| Format | Erkannt an | Sprecher |
|---|---|---|
SubRip (.srt) | Pfeile zwischen Zeitmarken, Trenner ,mmm | Über ein Name:-Präfix |
WebVTT (.vtt) | Kopfzeile WEBVTT | Über <v Name>-Tags oder ein Name:-Präfix |
SubStation Alpha (.ass, .ssa) | [Script Info] / Dialogue: | Über das Feld Name |
| TTML / DFXP | Wurzelelement <tt> | Über ein Attribut speaker/agent |
| YouTube srv1/srv2/srv3 | XML <transcript><text> | Über ein Name:-Präfix |
| YouTube json3 | Array events | Keine; automatische Untertitel haben keine |
SubRip und WebVTT decken das meiste ab, was Ihnen begegnen wird. TTML taucht in Rundfunkarchiven und in Exporten professioneller Untertitelwerkzeuge auf.
Alignment und linguistische Annotation
| Format | Erkannt an | Sprecher |
|---|---|---|
| NIST CTM | Durch Leerzeichen getrennte Spalten, numerischer Start und Dauer | Über das Kanalfeld |
| Praat TextGrid | File type = "ooTextFile" | Eine Ebene pro Sprecher |
| ELAN EAF | Wurzel ANNOTATION_DOCUMENT | Über PARTICIPANT, sonst die Ebenen-ID |
Sowohl die lange als auch die kurze TextGrid-Serialisierung wird gelesen. Bei ELAN-Dateien löst Potato ALIGNABLE_ANNOTATION und REF_ANNOTATION gegen die TIME_ORDER-Tabelle auf und liest den Medienverweis aus dem Kopfbereich.
Jede TextGrid-Ebene wird zu einem Sprecher, die leeren Intervalle dazwischen entfallen
Alles Übrige
Drei generische Formen vervollständigen die 21:
- Eine einfache Liste von
{speaker, start, end, text}-Dictionaries. - Ein Objekt
{"audio": ..., "turns": [...]}. - Ein reiner Absatz ganz ohne Zeitangaben, der als eine einzige Blase erscheint.
Nicht unterstützt
Dafür existiert kein Parser. Konvertieren Sie diese vorher.
- SAMI (
.smi), MicroDVD (.sub), SubViewer (.sbv) - Transcriber (
.trs), EXMARaLDA, CHAT/CHILDES (.cha) - Native Ausgaben von Montreal Forced Aligner und Gentle. Exportieren Sie von dort stattdessen CTM oder TextGrid.
- Azure Speech, Google Speech-to-Text und
verbose_jsonder Whisper-API in ungewöhnlichen Hüllen - RTTM-Diarisierungsdateien für sich allein
Wortweise Konfidenz wird gelesen und im Datenmodell behalten, sofern die Quelle sie liefert, aber es gibt derzeit keine Oberfläche, um sie anzusehen.
Das normalisierte Turn-Modell
Aus allen obigen Formaten wird dies:
{
"audio": "media/interview_01.mp3",
"turns": [
{
"turn_id": "t0",
"speaker": "host",
"start": 0.0,
"end": 6.5,
"text": "Welcome back.",
"words": [{"word": "Welcome", "start": 0.0, "end": 0.4, "confidence": 0.99}],
"confidence": 0.97
}
]
}words und confidence erscheinen nur, wenn die Quelle sie mitgebracht hat. speaker ist null bei nicht diarisierten Turns, die als Unassigned mit einer Auswahl erscheinen, damit Annotierende sie ergänzen können.
Automatische YouTube-Untertitel kommen ohne Sprecher an, also bleibt jeder Turn Unassigned, bis jemand einen auswählt
turn_id ist der Persistenzschlüssel für Annotationen pro Turn und für Sprecherzuweisungen. Sie stammt aus einem expliziten turn_id- oder step_id-String in der Quelle, sonst aus t{Index}. Dieselbe Datei erzeugt immer dieselben IDs, sodass Annotationen ein Neuladen überstehen.
Warning: Die Zeiteinheiten unterscheiden sich je nach Werkzeug. Whisper und Deepgram verwenden Sekunden als Fließkommazahl; AssemblyAI, die Offsets von whisper.cpp und die TSV-Ausgabe von Whisper verwenden ganzzahlige Millisekunden. Potato konvertiert an der Grenze, damit alles Weitere in Sekunden vorliegt. Wenn Ihre eigene Vorverarbeitung beides vermischt, sind die Zeiten um den Faktor 1000 falsch.
Begleitdateien
Ein Feldwert, der ein kurzer einzeiliger Pfad mit bekannter Transkriptendung ist, wird von der Festplatte gelesen statt als Text behandelt. So funktioniert genau die Ablage, die Ihr ASR-Werkzeug ohnehin erzeugt hat, mit den Mediendateien neben ihrer .srt oder .json, ganz ohne Vorverarbeitung:
{
"id": "int_001",
"conversation": {
"audio": "media/int_001.mp3",
"transcript": "media/int_001.srt"
}
}Pfade werden relativ zu task_dir aufgelöst und durchlaufen dieselbe Pfadsicherheitsprüfung wie jeder andere konfigurierte Pfad, sodass eine Datendatei nicht außerhalb des Projekts lesen kann.
Erkannte Endungen: .srt .vtt .webvtt .json .json3 .srv1 .srv2 .srv3 .ttml .dfxp .xml .ass .ssa .tsv .ctm .TextGrid .eaf .txt
Wenn Ihre Daten tatsächlich einzeilige Transkripte enthalten, die wie Dateinamen aussehen, schalten Sie die Heuristik ab:
display_options:
transcript_is_path: auto # auto (default) | true | falseKonfiguration
Anzeige: audio_dialogue
Die Audio-Dialoganzeige stellt Turns als Sprecherblasen dar, synchron zum Audio, mit einem Abspielknopf an jedem Turn.
instance_display:
fields:
- key: conversation
type: audio_dialogue
label: "Transcript"
span_target: true
display_options:
audio_key: audio
turns_key: turns
speaker_key: speaker
text_key: text
transcript_is_path: auto
show_timestamps: true
allow_speaker_assignment: auto
scroll_height: 460px| Option | Standard | Wirkung |
|---|---|---|
audio_key | audio | Unterschlüssel des Feldwerts mit der Audio-URL oder dem Pfad. |
turns_key | turns | Unterschlüssel mit der Turn-Liste. Akzeptiert auch segments. |
speaker_key / text_key | speaker / text | Schlüssel pro Turn. |
speakers | [] | Liste aus {id, name, color, side}. Nicht aufgeführte Sprecher erhalten eine deterministische Farbe und eine abwechselnde Seite. |
allow_speaker_assignment | auto | auto aktiviert die Zuweisung per Klick, wenn es nicht diarisierte Turns oder eine zu korrigierende Liste gibt. true erzwingt sie, false schaltet sie ab. |
transcript_is_path | auto | Ob der Feldwert als Pfad zu einer Begleitdatei gelesen wird. |
show_timestamps | true | Zeigt mm:ss–mm:ss an jedem Turn. |
scroll_height | 480px | Höhe des scrollbaren Transkriptbereichs. |
playback_rates | [1, 1.25, 1.5, 2] | Optionen im Geschwindigkeitsmenü. |
Schemata
Seit 2.7.1 lesen speech_transcript, voice_interaction und tiered_annotation ein Transkript direkt aus dem Instanzdatensatz und akzeptieren alle Formate auf dieser Seite. Vorher tat das nur die Anzeige audio_dialogue.
annotation_schemes:
- annotation_type: speech_transcript
name: transcript_review
description: "Mark transcription errors"
segments_key: segments # record field holding the transcript
- annotation_type: voice_interaction
name: barge_in
description: "Mark overlaps and barge-in"
turns_key: turnsDie Ebenen-Annotation kann eine Ebene aus dem Transkript vorbefüllen, sodass Annotierende ein bestehendes Alignment korrigieren, statt die Sprache von Hand neu zu segmentieren:
- annotation_type: tiered_annotation
name: tiers
source_field: audio_url
media_type: audio
transcript_field: asr_output # opt-in; omit to start from a blank timeline
transcript_tier: utterance # defaults to the first tier
tiers:
- name: utterance
labels:
- name: speech
color: "#7c3aed"Vorbefüllte Annotationen werden erst geschrieben, wenn jemand tatsächlich etwas ändert, sodass niemandem etwas zugerechnet wird, der die Instanz nur geöffnet hat.
Eine Datendatei mit potato transcripts bauen
Richten Sie den Konverter auf einen Ordner mit ASR-Ausgaben, und er schreibt eine annotationsfertige Datendatei:
# Pair transcripts to media by basename
potato transcripts ./whisper_out --media-dir ./audio -o data/interviews.json
# Media served from elsewhere
potato transcripts './captions/*.vtt' \
--media-url-prefix https://cdn.example.org/audio -o data/talks.json
# What did it detect? Writes nothing.
potato transcripts ./whisper_out --dry-run--dry-run meldet, was gefunden wurde, ohne etwas zu schreiben. Das ist der schnellste Weg, einen Ordner mit der falschen Whisper-Ausgabedatei zu erkennen:
Scanned 3 file(s):
talk_01.srt SRT 2 turns 5.0s 2 speaker(s): Alice, Bob
talk_02.vtt WebVTT 1 turns 3.0s undiarized
talk_03.json whisper.cpp JSON 1 turns 2.4s undiarized
3 item(s), 4 turn(s).
1 item(s) have no media. Pass --media-dir or --media-url-prefix to enable playback.
| Option | Zweck |
|---|---|
-o, --output | Wohin geschrieben wird. Pflicht, außer bei --dry-run. |
--format | json (Standard) oder jsonl. |
--media-dir | Medienordner, der über den Basisnamen zugeordnet wird. |
--media-url-prefix | Basis-URL für Medien statt lokaler Dateien. |
--field | Feld des Items, in das das Transkript kommt. Standard conversation. |
--id-prefix | Zeichenkette, die jeder erzeugten ID vorangestellt wird. |
--speaker-key | Quellschlüssel mit dem Sprecherlabel. |
-r, --recursive | Bezieht Unterordner ein. |
--dry-run | Meldet erkanntes Format und Turn-Anzahl je Datei. |
--emit-config | Gibt zusätzlich ein passendes config.yaml-Fragment aus. |
-q, --quiet | Unterdrückt den Bericht pro Datei. |
Item-IDs stammen aus dem Dateinamen ohne eine abschließende Medienendung, also wird aus Whispers interview_01.mp3.json ein interview_01 und nicht interview_01.mp3.
Wieder hinausexportieren
Ebenen-Annotationen lassen sich nach ELAN EAF und Praat TextGrid exportieren, sodass ein Transkript einen vollen Kreis läuft: einlesen, in Potato annotieren, exportieren, in ELAN oder Praat verfeinern und das Ergebnis wieder einlesen.
python -m potato.export --config config.yaml --format eaf --output ./out/
python -m potato.export --config config.yaml --format textgrid --output ./out/Beide Exporter arbeiten mit der Ausgabe von tiered_annotation. Andere Schemata werden über die Standardformate exportiert.
Fehlersuche
| Symptom | Was passiert ist |
|---|---|
| Alles erscheint als eine große Blase | Das Format wurde nicht erkannt und fiel auf die Absatz-Rückfallebene zurück. Führen Sie potato transcripts <file> --dry-run aus; meldet es plain text, wurden die Zeiten nie gelesen. Meist ist die Datei ein Whisper-.txt ohne jede Zeitangabe statt der .json oder .srt. |
| Keine Sprecher, alles Unassigned | Die Quelle enthält keine Sprecherlabels. Whisper allein diarisiert nicht, automatische YouTube-Untertitel auch nicht. Diarisieren Sie vorher oder lassen Sie Annotierende die Sprecher in der Oberfläche zuweisen. |
| Die Zeiten sind um Faktor 1000 falsch | Sekunden und Millisekunden wurden vorher vermischt. Die offsets von whisper.cpp, AssemblyAI und Whispers TSV sind alle in Millisekunden. |
| Der Transkriptpfad erscheint als Transkripttext | Die Begleitdatei war nicht lesbar, also wurde der Pfad als Inhalt angezeigt. Prüfen Sie, ob er unterhalb von task_dir aufgelöst wird. Die Serverprotokolle nennen den genauen Grund. |
| Ein einzeiliges Inline-Transkript wird als Dateiname gelesen | Setzen Sie transcript_is_path: false am Anzeigefeld. |
Beispielprojekt
examples/audio/transcript-formats/ im Potato-Repository zeigt sechs Formate nebeneinander, jedes aus einer Begleitdatei geladen: SubRip, WebVTT, Whisper JSON, YouTube json3, Praat TextGrid und Deepgram. Alle sechs erzeugen dieselben Sprecherblasen.
python potato/flask_server.py start examples/audio/transcript-formats/config.yaml -p 8000Dieselbe Aufgabe gibt es als herunterladbares Showcase-Design: Transcript Format Ingestion.
Implementierungsdetails stehen in der Quelldokumentation.
Weiterführend
- Whisper-Transkripte annotieren, die vollständige Anleitung
- YouTube-Untertitel annotieren, für Untertitel und ihre Grenzen
- Dialogannotation, die Sprecherblasen-Anzeige
- Audioannotation, Wellenform-Segmentierung von Grund auf
- Datenformate für die Annotation entwerfen