ALLARD Marc-Antoine commited on
Commit
de1009f
Β·
1 Parent(s): c19c343

Fix transcription auto-save and segmentation form reset

Browse files
Files changed (1) hide show
  1. app.py +60 -17
app.py CHANGED
@@ -96,7 +96,7 @@ def create_waveform_html(audio_data, segments=None):
96
  <div id="waveform" style="height: 200px; border: 1px solid #ddd;"></div>
97
  <div style="margin-top: 10px;">
98
  <button id="play-pause" style="margin-right: 5px; padding: 8px 15px; background: #00cc44; color: white; border: none; border-radius: 3px; cursor: pointer;">
99
- ⏯️ Play/Pause
100
  </button>
101
  <button id="add-region" style="margin-right: 5px; padding: 8px 15px; background: #0066cc; color: white; border: none; border-radius: 3px; cursor: pointer;">
102
  βž• Add Region
@@ -128,7 +128,9 @@ def create_waveform_html(audio_data, segments=None):
128
  responsive: true,
129
  plugins: [
130
  WaveSurfer.regions.create({{
131
- dragSelection: true,
 
 
132
  color: 'rgba(255, 75, 75, 0.3)'
133
  }})
134
  ]
@@ -161,6 +163,40 @@ def create_waveform_html(audio_data, segments=None):
161
  updateRegionsList();
162
  }});
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  // Add region function
165
  function addRegion(start, end, speaker_id) {{
166
  // Get or assign color for this speaker
@@ -205,7 +241,7 @@ def create_waveform_html(audio_data, segments=None):
205
  </div>
206
  <button onclick="removeRegion('${{region.id}}')"
207
  style="background: #cc0000; color: white; border: none; border-radius: 3px; padding: 5px 8px; cursor: pointer;">
208
- βœ•
209
  </button>
210
  </div>
211
  `;
@@ -430,49 +466,55 @@ def show_transcription_page():
430
  audio_html = create_audio_player_html(st.session_state.audio_file)
431
  st.components.v1.html(audio_html, height=120)
432
 
433
- # Transcription area
434
  st.subheader("Transcript")
 
 
 
 
 
435
  transcript = st.text_area(
436
  "Write your transcription here:",
437
  value=st.session_state.transcript,
438
  height=300,
439
- help="Check the guidelines below to help you transcribe accurately."
 
 
440
  )
441
- st.session_state.transcript = transcript
442
 
443
  # Guidelines reminder
444
  with st.expander("πŸ“‹ Transcription Guidelines"):
445
  st.markdown("""
446
  **Key Guidelines:**
447
- - Transcribe exactly what is said
448
- - Use standard punctuation and capitalization (tip: Get punctuation from natural pauses in dialogue)
449
- - Write numbers 1-10 as words, 11+ as digits
450
- - Ignore unclear speech or marked as [unclear] or [inaudible]
451
- - For multi-speaker: transcribe all audible speech without identifying speakers
452
  """)
453
 
454
  # Action buttons
455
  col1, col2, col3 = st.columns(3)
456
 
457
  with col1:
458
- if transcript.strip():
459
- download_link = get_download_link(transcript, "transcript.txt", "πŸ’Ύ Download Transcript")
460
  st.markdown(download_link, unsafe_allow_html=True)
461
  else:
462
  st.button("πŸ’Ύ Download Transcript", disabled=True)
463
 
464
  with col2:
465
- if st.session_state.annotation_type == "multi_speaker" and transcript.strip():
466
  if st.button("🎯 Continue to Segmentation β†’"):
467
  st.session_state.current_page = "segmentation"
468
  st.rerun()
469
 
470
  with col3:
471
- if st.session_state.annotation_type == "single_speaker" and transcript.strip():
472
  if st.button("βœ… Finish Annotation"):
473
  st.balloons()
474
  st.success("πŸŽ‰ Single speaker annotation completed!")
475
- download_link = get_download_link(transcript, "transcript.txt", "πŸ“₯ Download Final Transcript")
476
  st.markdown(download_link, unsafe_allow_html=True)
477
 
478
  def show_segmentation_page():
@@ -491,7 +533,7 @@ def show_segmentation_page():
491
 
492
  # Manual segment addition
493
  st.subheader("Manual Segment Addition")
494
- st.info("After having segmented the wav using our wav surfer, you can manually add segments here. Don't hesitate to replay and pause for the best results.")
495
  col1, col2, col3, col4 = st.columns(4)
496
 
497
  with col1:
@@ -632,3 +674,4 @@ def create_speaker_transcript(segments):
632
 
633
  if __name__ == "__main__":
634
  main()
 
 
96
  <div id="waveform" style="height: 200px; border: 1px solid #ddd;"></div>
97
  <div style="margin-top: 10px;">
98
  <button id="play-pause" style="margin-right: 5px; padding: 8px 15px; background: #00cc44; color: white; border: none; border-radius: 3px; cursor: pointer;">
99
+ ▢️ Play/Pause
100
  </button>
101
  <button id="add-region" style="margin-right: 5px; padding: 8px 15px; background: #0066cc; color: white; border: none; border-radius: 3px; cursor: pointer;">
102
  βž• Add Region
 
128
  responsive: true,
129
  plugins: [
130
  WaveSurfer.regions.create({{
131
+ dragSelection: {{
132
+ slop: 5
133
+ }},
134
  color: 'rgba(255, 75, 75, 0.3)'
135
  }})
136
  ]
 
163
  updateRegionsList();
164
  }});
165
 
166
+ // Handle region creation via drag selection
167
+ wavesurfer.on('region-created', function(region) {{
168
+ // Check if this is a new region (not from loading existing segments)
169
+ const existingRegion = regions.find(r => r.id === region.id);
170
+ if (!existingRegion) {{
171
+ // Prompt for speaker ID
172
+ const speakerId = prompt("Enter speaker ID (e.g., SPK001):", "SPK" + (Object.keys(speakerColors).length + 1).toString().padStart(3, '0'));
173
+
174
+ if (speakerId) {{
175
+ // Get or assign color for this speaker
176
+ if (!speakerColors[speakerId]) {{
177
+ speakerColors[speakerId] = getColorForSpeaker(speakerId);
178
+ }}
179
+
180
+ // Update region color
181
+ region.color = speakerColors[speakerId];
182
+ region.updateRender();
183
+
184
+ // Add to regions array
185
+ regions.push({{
186
+ id: region.id,
187
+ start: region.start,
188
+ end: region.end,
189
+ speaker_id: speakerId
190
+ }});
191
+
192
+ updateRegionsList();
193
+ }} else {{
194
+ // If user cancels, remove the region
195
+ region.remove();
196
+ }}
197
+ }}
198
+ }});
199
+
200
  // Add region function
201
  function addRegion(start, end, speaker_id) {{
202
  // Get or assign color for this speaker
 
241
  </div>
242
  <button onclick="removeRegion('${{region.id}}')"
243
  style="background: #cc0000; color: white; border: none; border-radius: 3px; padding: 5px 8px; cursor: pointer;">
244
+ ❌
245
  </button>
246
  </div>
247
  `;
 
466
  audio_html = create_audio_player_html(st.session_state.audio_file)
467
  st.components.v1.html(audio_html, height=120)
468
 
469
+ # Transcription area with callback for auto-saving
470
  st.subheader("Transcript")
471
+
472
+ def update_transcript():
473
+ """Callback function to update transcript in session state"""
474
+ st.session_state.transcript = st.session_state.transcript_input
475
+
476
  transcript = st.text_area(
477
  "Write your transcription here:",
478
  value=st.session_state.transcript,
479
  height=300,
480
+ help="Check the guidelines below to help you transcribe accurately.",
481
+ key="transcript_input",
482
+ on_change=update_transcript
483
  )
 
484
 
485
  # Guidelines reminder
486
  with st.expander("πŸ“‹ Transcription Guidelines"):
487
  st.markdown("""
488
  **Key Guidelines:**
489
+ - Transcribe EXACTLY what is said. No shortening or paraphrasing. (e.g saying "I do like" and "I'd like" are different)
490
+ - Use standard punctuation and capitalization (tip: Get punctuation from natural pauses in dialogue).
491
+ - Write numbers as digits.
492
+ - Ignore unclear speech or marked as [unclear] or [inaudible].
493
+ - For multi-speaker: transcribe all audible speech without identifying speakers.
494
  """)
495
 
496
  # Action buttons
497
  col1, col2, col3 = st.columns(3)
498
 
499
  with col1:
500
+ if st.session_state.transcript.strip():
501
+ download_link = get_download_link(st.session_state.transcript, "transcript.txt", "πŸ’Ύ Download Transcript")
502
  st.markdown(download_link, unsafe_allow_html=True)
503
  else:
504
  st.button("πŸ’Ύ Download Transcript", disabled=True)
505
 
506
  with col2:
507
+ if st.session_state.annotation_type == "multi_speaker" and st.session_state.transcript.strip():
508
  if st.button("🎯 Continue to Segmentation β†’"):
509
  st.session_state.current_page = "segmentation"
510
  st.rerun()
511
 
512
  with col3:
513
+ if st.session_state.annotation_type == "single_speaker" and st.session_state.transcript.strip():
514
  if st.button("βœ… Finish Annotation"):
515
  st.balloons()
516
  st.success("πŸŽ‰ Single speaker annotation completed!")
517
+ download_link = get_download_link(st.session_state.transcript, "transcript.txt", "πŸ“₯ Download Final Transcript")
518
  st.markdown(download_link, unsafe_allow_html=True)
519
 
520
  def show_segmentation_page():
 
533
 
534
  # Manual segment addition
535
  st.subheader("Manual Segment Addition")
536
+ st.info("After having segmented the wav using our wav surfer, you can manually add segments here. Don't hesitate to replay and pause.")
537
  col1, col2, col3, col4 = st.columns(4)
538
 
539
  with col1:
 
674
 
675
  if __name__ == "__main__":
676
  main()
677
+