音訊標註
在 Potato 中切分音訊,在互動式波形上標記時間區段,支援播放速度控制、縮放,以及用於轉寫的逐段問題。
Potato 的音訊標註工具讓標註者通過基於波形的介面切分音訊檔案,並給時間區段分配標籤。
功能
- 波形視覺化
- 按時間建立區段
- 給區段分配標籤
- 可變速的播放控制
- 縮放與滾動導航
- 鍵盤快捷鍵
- 服務端波形快取
基本配置
預設模式要求標註者劃出區段並給每一段打標籤,所以說話人分離任務只需要寫好標籤:
annotation_schemes:
- name: "speakers"
description: "Mark when each speaker is talking"
annotation_type: "audio_annotation"
labels:
- name: "Speaker 1"
color: "#3B82F6"
- name: "Speaker 2"
color: "#10B981"配置選項
| 欄位 | 類型 | 預設值 | 說明 |
|---|---|---|---|
name | 字串 | 必填 | 該標註的唯一標識 |
description | 字串 | 必填 | 展示給標註者的說明 |
annotation_type | 字串 | 必填 | 必須是 "audio_annotation" |
mode | 字串 | "label" | 標註模式:"label"、"questions" 或 "both" |
labels | 列表 | 視情況 | label 或 both 模式下必填 |
segment_schemes | 列表 | 視情況 | questions 或 both 模式下必填 |
min_segments | 整數 | 0 | 至少需要的區段數 |
max_segments | 整數 | null | 允許的最大區段數(null 表示不限) |
zoom_enabled | 布林值 | true | 啟用縮放控制元件 |
playback_rate_control | 布林值 | false | 顯示播放速度選擇器 |
waveform | 布林值 | true | 顯示波形 |
spectrogram | 布林值 | false | 在波形旁顯示聲譜圖 |
spectrogram_options | 字典 | — | 聲譜圖的 FFT 大小、頻率範圍和配色 |
source_field | 字串 | "" | 當一個條目帶有多個音訊檔案時,本方案所標註的展示欄位 |
方案缺了它所在模式需要的輸入,Potato 就拒絕載入,所以 label 和 both 缺 labels 會失敗,questions 和 both 缺 segment_schemes 會失敗。
標籤配置
給每個標籤配一個 key_value,標註者不用離開波形就能給區段打標籤;在區段一個接一個出現的說話人分離任務裡,這一點很要緊:
labels:
- name: "speech"
color: "#3B82F6"
key_value: "1"
- name: "music"
color: "#10B981"
key_value: "2"
- name: "silence"
color: "#64748B"
key_value: "3"標註模式
標籤模式(預設)
區段拿到類別標籤。每個區段回答的都是同一個單選問題時,用這個模式:
annotation_schemes:
- name: "emotion"
description: "Label the emotion in each segment"
annotation_type: "audio_annotation"
mode: "label"
labels:
- name: "happy"
color: "#22C55E"
- name: "sad"
color: "#3B82F6"
- name: "angry"
color: "#EF4444"
- name: "neutral"
color: "#64748B"問題模式
每個區段回答專門的問題。segment_schemes 裡的子方案就是普通的標註方案,只是按區段逐個渲染,所以每個子方案都要寫齊它自己那種類型需要的欄位,比如 likert 量表需要 size、min_label 和 max_label:
annotation_schemes:
- name: "transcription"
description: "Transcribe each segment"
annotation_type: "audio_annotation"
mode: "questions"
segment_schemes:
- name: "transcript"
annotation_type: "text"
description: "Enter the transcription"
- name: "confidence"
annotation_type: "likert"
description: "How confident are you?"
size: 5
min_label: "Not confident"
max_label: "Very confident"兩者兼用模式
把打標籤和逐段問卷結合起來。每個區段都要標註者既選標籤又填一份表單,所以只在確實兩樣都要的那一遍標註裡用它:
annotation_schemes:
- name: "detailed_diarization"
description: "Label speakers and add notes"
annotation_type: "audio_annotation"
mode: "both"
labels:
- name: "Speaker A"
color: "#3B82F6"
- name: "Speaker B"
color: "#10B981"
segment_schemes:
- name: "notes"
annotation_type: "text"
description: "Any notes about this segment?"全域音訊配置
Potato 在服務端計算波形資料並快取,因為瀏覽器要自己渲染波形,就得先把整個檔案下載下來解碼。快取在配置檔案裡設定:
audio_annotation:
waveform_cache_dir: "waveform_cache/"
waveform_look_ahead: 5
waveform_cache_max_size: 1000
client_fallback_max_duration: 1800| 欄位 | 預設值 | 說明 |
|---|---|---|
waveform_cache_dir | — | 存放快取波形資料的目錄 |
waveform_look_ahead | 5 | 預先計算的後續條目數量 |
waveform_cache_max_size | 100 | 快取波形檔案的最大數量 |
client_fallback_max_duration | 1800 | 沒有可用快取波形時,瀏覽器願意渲染的最長檔案時長(秒) |
標註者翻條目的速度快過服務端預計算時,調高 waveform_look_ahead;研究涉及的檔案多過快取容量時,調高 waveform_cache_max_size。
示例
說話人分離
說話人分離最能體現播放速度的價值:標註者會放慢音訊,好把邊界卡在說話人切換的位置,又會在某個人連說很久的地方加快播放:
annotation_schemes:
- name: "diarization"
description: "Identify who is speaking at each moment"
annotation_type: "audio_annotation"
mode: "label"
labels:
- name: "Interviewer"
color: "#8B5CF6"
key_value: "1"
- name: "Guest"
color: "#EC4899"
key_value: "2"
- name: "Overlap"
color: "#F59E0B"
key_value: "3"
zoom_enabled: true
playback_rate_control: true聲音事件檢測
設定 min_segments: 1 可以攔住標註者提交一段什麼都沒標的錄音。只有在每段錄音都至少含一個事件時才用它:
annotation_schemes:
- name: "sound_events"
description: "Mark all sound events"
annotation_type: "audio_annotation"
labels:
- name: "speech"
color: "#3B82F6"
- name: "music"
color: "#10B981"
- name: "applause"
color: "#F59E0B"
- name: "laughter"
color: "#EC4899"
- name: "silence"
color: "#64748B"
min_segments: 1轉寫校對
把自由文本欄位和一個品質評分配在一起,就記錄下了轉寫為什麼沒被改動,輸出裡也就能把乾淨的區段和聽不清的區段區分開:
annotation_schemes:
- name: "transcription_review"
description: "Review and correct the transcription for each segment"
annotation_type: "audio_annotation"
mode: "questions"
segment_schemes:
- name: "transcript"
annotation_type: "text"
description: "Enter or correct the transcription"
- name: "quality"
annotation_type: "radio"
description: "Audio quality"
labels:
- "Clear"
- "Noisy"
- "Unintelligible"已經有轉寫文本了?
上面這些都是從一張空白波形開始的:標註者聽音訊、劃邊界、給聽到的內容打標籤。如果轉寫文本已經存在,無論來自 Whisper 還是下載的字幕,該走的是另一條路。Potato 能讀 21 種轉寫和字幕格式,把每一輪發言渲染成與音訊同步的對話氣泡,標註者於是給已有的區段打標籤,而不是重新劃一遍。
{"id": "int_001", "conversation": {"audio": "media/int_001.mp3",
"transcript": "media/int_001.srt"}}格式清單見轉寫格式,完整流程見標註 Whisper 轉寫。兩樣都需要時,波形切分和轉寫標註也可以放在同一個任務裡跑。
鍵盤快捷鍵
| 按鍵 | 操作 |
|---|---|
Space | 播放/暫停 |
← / → | 前後跳 5 秒 |
[ / ] | 設定區段起點/終點 |
Enter | 建立區段 |
Del | 刪除區段 |
+ / - | 放大/縮小 |
0 | 適應檢視 |
在 label 和 both 模式下,每個帶 key_value 的標籤還會佔一個自己的按鍵。
資料格式
輸入資料
資料檔案裡要寫上音訊檔案的路徑或 URL:
[
{
"id": "audio_001",
"audio_url": "https://example.com/audio/recording1.mp3"
},
{
"id": "audio_002",
"audio_url": "/data/audio/recording2.wav"
}
]把 text_key 指向存放音訊路徑的欄位,因為 Potato 交給標註元件的就是這個欄位:
item_properties:
id_key: id
text_key: audio_url輸出格式
{
"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"
}
]
}
}問題模式下,區段裡會帶上巢狀的回答:
{
"start": 0.0,
"end": 5.5,
"transcript": "Hello and welcome to the show.",
"quality": "Clear"
}支援的音訊格式
- MP3(推薦)
- WAV
- OGG
- M4A
實踐建議
- 預先快取波形 - 資料集較大時使用服務端快取
- 開啟播放控制 - 變速有助於精確切分
- 使用鍵盤快捷鍵 - 比點選快,標註者的視線也能一直留在波形上
- 明確邊界的定義 - 說清楚什麼算區段的起點和終點
- 選擇合適的模式 - 分類用 "label",細緻標註用 "questions"
- 限制區段數量 - 用
min_segments保證覆蓋