Skip to content

Audio Annotation

Segment audio files in Potato and assign labels to time regions. Displays an interactive waveform with playback controls, speed adjustment, and time-boundary marking.

Potato's audio annotation tool enables annotators to segment audio files and assign labels to time regions through a waveform-based interface.

Features

  • Waveform visualization
  • Time-based segment creation
  • Label assignment to segments
  • Playback controls with variable speed
  • Zoom and scroll navigation
  • Keyboard shortcuts
  • Server-side waveform caching

Basic Configuration

yaml
annotation_schemes:
  - name: "speakers"

Configuration Options

FieldTypeDefaultDescription
namestringRequiredUnique identifier for the annotation
descriptionstringRequiredInstructions shown to annotators
annotation_typestringRequiredMust be "audio_annotation"
modestring"label"Annotation mode: "label", "questions", or "both"
labelslistConditionalRequired for label or both modes
segment_schemeslistConditionalRequired for questions or both modes
min_segmentsinteger0Minimum segments required
max_segmentsintegernullMaximum segments allowed (null = unlimited)
zoom_enabledbooleantrueEnable zoom controls
playback_rate_controlbooleanfalseShow playback speed selector

Label Configuration

yaml
labels:
  - name: "speech"
    color: "#3B82F6"
    key_value: "1"
  - name: "music"
    color: "#10B981"
    key_value: "2"
  - name: "silence"
    color: "#64748B"
    key_value: "3"

Annotation Modes

Label Mode (Default)

Segments receive category labels:

yaml
annotation_schemes:
  - name: "emotion"

Questions Mode

Each segment answers dedicated questions:

yaml
annotation_schemes:
  - name: "transcription"

Both Mode

Combines labeling with per-segment questionnaires:

yaml
annotation_schemes:
  - name: "detailed_diarization"

Global Audio Configuration

Configure waveform handling in your config file:

yaml
audio_annotation:
  waveform_cache_dir: "waveform_cache/"
  waveform_look_ahead: 5
  waveform_cache_max_size: 1000
  client_fallback_max_duration: 1800
FieldDescription
waveform_cache_dirDirectory for cached waveform data
waveform_look_aheadNumber of upcoming instances to pre-compute
waveform_cache_max_sizeMaximum number of cached waveform files
client_fallback_max_durationMax seconds for browser-side waveform generation (default: 1800)

Examples

Speaker Diarization

yaml
annotation_schemes:
  - name: "diarization"

Sound Event Detection

yaml
annotation_schemes:
  - name: "sound_events"

Transcription Review

yaml
annotation_schemes:
  - name: "transcription_review"

Already have a transcript?

Everything above starts from a blank waveform: the annotator listens, marks boundaries, and labels what they find. If a transcript already exists, because you ran Whisper or downloaded captions, you probably want the other path. Potato reads 21 transcript and subtitle formats and renders the turns as speaker bubbles synced to the audio, so annotators label existing segments instead of re-creating them.

json
{"id": "int_001", "conversation": {"audio": "media/int_001.mp3",
                                   "transcript": "media/int_001.srt"}}

See Transcript Formats for the format list, and Annotating Whisper Transcripts for the walkthrough. Waveform segmentation and transcript annotation can also run in the same task when you need both.

Keyboard Shortcuts

KeyAction
SpacePlay/pause
/ Seek backward/forward
[Mark segment start
]Mark segment end
EnterCreate segment
DeleteRemove selected segment
1-9Select label
+ / -Zoom in/out
0Fit view

Data Format

Input Data

Your data file should include audio file paths or URLs:

json
[
  {
    "id": "audio_001",
    "audio_url": "https://example.com/audio/recording1.mp3"
  },
  {
    "id": "audio_002",
    "audio_url": "/data/audio/recording2.wav"
  }
]

Configure the audio field:

yaml
item_properties:
  id_key: id
  text_key: audio_url

Output Format

json
{
  "id": "audio_001",
  "annotations": {
    "diarization": [
      {
        "start": 0.0,
        "end": 5.5,
        "label": "Interviewer"
      },
      {
        "start": 5.5,
        "end": 12.3,
        "label": "Guest"
      },
      {
        "start": 12.3,
        "end": 14.0,
        "label": "Overlap"
      }
    ]
  }
}

For questions mode, segments include nested responses:

json
{
  "start": 0.0,
  "end": 5.5,
  "transcript": "Hello and welcome to the show.",
  "quality": "Clear"
}

Supported Audio Formats

  • MP3 (recommended)
  • WAV
  • OGG
  • M4A

Best Practices

  1. Pre-cache waveforms - Use server-side caching for large datasets
  2. Enable playback control - Variable speed helps with precise segmentation
  3. Use keyboard shortcuts - Much faster than clicking
  4. Define clear boundaries - Specify what constitutes segment start/end
  5. Choose appropriate mode - Use "label" for classification, "questions" for detailed annotation
  6. Set segment limits - Use min_segments to ensure coverage