intermediateaudio
Transcript Format Ingestion
Six transcript formats rendered as the same speaker bubbles, with per-turn labels and spans that work regardless of where the transcript came from.

Configuration Fileconfig.yaml
yaml
annotation_task_name: "Transcript Formats"
task_dir: "."
port: 8000
# Six instances, six different transcript formats. All of them render as the
# same speaker bubbles, because Potato normalizes every supported format to one
# turn model before display.
#
# Here the transcripts are inlined into the data file. They can equally be paths
# to sidecar files next to the media, which is usually what your ASR tool
# already produced:
#
# "conversation": {"audio": "media/talk_01.mp3",
# "transcript": "media/talk_01.srt"}
#
# To build a data file from a folder of ASR output instead:
#
# potato transcripts ./whisper_out --media-dir ./audio -o data/items.json
# potato transcripts ./whisper_out --dry-run # what did it detect?
data_files:
- data/sample-data.json
item_properties:
id_key: id
text_key: title
instance_display:
layout:
direction: vertical
gap: 16px
fields:
- key: title
type: text
label: "Format"
- key: source_format
type: text
label: "Where this came from"
- key: conversation
type: audio_dialogue
label: "Transcript"
span_target: true
display_options:
audio_key: audio
scroll_height: 420px
show_timestamps: true
# "auto" reads the field as a sidecar path when it looks like one.
# These transcripts are inlined, so nothing is read from disk.
transcript_is_path: auto
# No fixed roster: these files use different speaker conventions
# (Host/Guest, Interviewer/Participant, speaker_0/speaker_1, tier
# names), so speakers get deterministic colors and alternating sides.
allow_speaker_assignment: auto
annotation_schemes:
# Whether the transcript survived ingestion intact, which is the judgment you
# actually want a human to make before trusting a corpus.
- annotation_type: radio
name: ingestion_quality
description: "Did this transcript come through correctly?"
labels:
- name: "clean"
tooltip: "Timings, speakers, and text all look right"
- name: "timing_off"
tooltip: "Turns are misaligned with the audio"
- name: "speakers_wrong"
tooltip: "Turns are attributed to the wrong speaker, or not attributed"
- name: "text_garbled"
tooltip: "Text is missing, truncated, or mangled"
# Per-turn labeling, bound to every turn of the conversation field.
- annotation_type: radio
name: turn_type
description: "What is this turn doing?"
labels:
- question
- answer
- aside
turn_level: true
turn_binding:
field: conversation
# Spans work over normalized turns regardless of the source format.
- annotation_type: span
name: highlights
description: "Highlight anything an annotator would need to check against the audio"
target_field: conversation
labels:
- name: unclear
key_value: "u"
- name: likely_asr_error
key_value: "e"
output_annotation_dir: "annotation_output/"
output_annotation_format: "json"
Sample Datasample-data.json
json
[
{
"id": "talk_01",
"title": "SubRip (.srt)",
"source_format": "Exported from a captioning tool. Speakers come from the \"Host:\" / \"Guest:\" prefix on each cue.",
"conversation": {
"audio": "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
"transcript": "1\n00:00:00,000 --> 00:00:06,500\nHost: Welcome back. Today we're talking about what happens to a transcript before anyone annotates it.\n\n2\n00:00:06,500 --> 00:00:12,000\nHost: You've argued that most of the errors people blame on annotators actually start upstream.\n\n3\n00:00:12,000 --> 00:00:21,400\nGuest: Right. If the diarization is wrong, every downstream label inherits that mistake, and nobody notices until analysis.\n\n4\n00:00:21,400 --> 00:00:28,900\nHost: So what would you check first, before recruiting a single annotator?\n"
}
},
{
"id": "talk_02",
"title": "WebVTT (.vtt)",
"source_format": "WebVTT. Speakers come from the <v Name> voice tags, the format's own way of marking who is talking.",
"conversation": {
"audio": "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-2.mp3",
"transcript": "WEBVTT\n\nNOTE\nExported from a captioning tool. Voice tags carry the speaker.\n\n1\n00:00:00.000 --> 00:00:07.200\n<v Interviewer>Can you describe what a normal week looked like before the change?\n\n2\n00:00:07.200 --> 00:00:16.800\n<v Participant>It was mostly reactive. You'd come in, see what broke overnight, and spend the day on that.\n\n3\n00:00:16.800 --> 00:00:24.000\n<v Interviewer>And afterwards?\n\n4\n00:00:24.000 --> 00:00:33.500\n<v Participant>Afterwards there was a plan. Not a good one at first, but the difference was having one at all.\n"
}
}
]
// ... and 4 more itemsGet This Design
This design is available in our showcase. Copy the configuration below to get started.
Quick start:
# Create your project folder mkdir transcript-formats cd transcript-formats # Copy config.yaml from above potato start config.yaml
Details
Annotation Types
radiospan
Domain
AudioSpeech
Use Cases
transcript annotationASR ingestionspeaker diarizationsubtitle annotation
Tags
audiotranscriptwhispersubtitlessrtwebvttdeepgramtextgrid
Related Designs
Audio Transcription Review
Review and correct automatic speech recognition transcriptions with waveform visualization.
likertmultiselect
Audio-Visual Sentiment Analysis
Rate sentiment in speech segments following CMU-MOSI and CMU-MOSEI multimodal annotation protocols.
likertradio
Google Speech Commands: Keyword Spotting Dataset
Google Speech Commands is a corpus of one-second spoken-word audio clips for training keyword spotting models (Warden, 2018). This Potato config reproduces the task: annotators play each clip, label the spoken word, and rate audio quality.
radioaudio_annotation