NickVerri commited on
Commit
f5f4019
·
verified ·
1 Parent(s): 5bc44c9

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +32 -23
app.py CHANGED
@@ -79,7 +79,6 @@ except Exception as e:
79
  if not hasattr(np, 'NaN'):
80
  np.NaN = np.nan
81
 
82
- # Import whisperx AFTER patching
83
  import whisperx
84
 
85
  # --- Configuration & Tokens ---
@@ -210,7 +209,6 @@ uploaded_file = st.file_uploader("Upload Video/Audio Clip", type=["mp4", "m4a",
210
 
211
  if uploaded_file:
212
  # --- Auto-Reset Logic for New Files ---
213
- # If the user uploads a new file, we must clear the old transcript from memory
214
  if "last_processed_file" not in st.session_state or st.session_state.last_processed_file != uploaded_file.name:
215
  if "transcript" in st.session_state:
216
  del st.session_state.transcript
@@ -221,55 +219,62 @@ if uploaded_file:
221
  if not ACTIVE_HF_TOKEN or "PASTE_YOUR_HF_TOKEN" in ACTIVE_HF_TOKEN:
222
  st.error("Please provide a valid Hugging Face Token in the Sidebar/Secrets.")
223
  else:
224
- status_container = st.empty()
225
- with status_container.container():
226
- st.info("🤖 **Junior Editor is starting...**")
 
 
 
 
227
  progress_bar = st.progress(0)
228
 
229
  try:
230
- # Save File
 
231
  with open("temp_input", "wb") as f:
232
  f.write(uploaded_file.getbuffer())
233
 
234
- st.write("🎵 **Phase 1/4: Extracting Audio...**")
235
- progress_bar.progress(10)
236
  subprocess.run([
237
  "ffmpeg", "-i", "temp_input",
238
  "-vn", "-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1",
239
  "temp_audio.wav", "-y"
240
  ])
 
241
 
 
242
  device = "cuda" if torch.cuda.is_available() else "cpu"
243
  if device == "cpu":
244
  st.warning("⚠️ No GPU detected. This will be slow.")
245
 
246
- # 1. Transcribe
247
- st.write(f"📝 **Phase 2/4: Transcribing (Whisper {model_size})...**")
248
- progress_bar.progress(30)
249
 
250
  compute_type = "float16" if device == "cuda" else "int8"
251
  model = whisperx.load_model(model_size, device, compute_type=compute_type)
252
  audio = whisperx.load_audio("temp_audio.wav")
 
 
 
253
  result = model.transcribe(audio, batch_size=16, language=target_language)
254
 
255
- # Cleanup
256
  del model
257
  gc.collect()
258
  torch.cuda.empty_cache()
 
259
 
260
- # 2. Align
261
- st.write("⏱️ **Phase 3/4: Aligning Text...**")
262
- progress_bar.progress(60)
263
  model_a, metadata = whisperx.load_align_model(language_code=result["language"], device=device)
264
  result = whisperx.align(result["segments"], model_a, metadata, audio, device, return_char_alignments=False)
265
 
266
  del model_a
267
  gc.collect()
268
  torch.cuda.empty_cache()
 
269
 
270
- # 3. Diarize
271
- st.write("🗣️ **Phase 4/4: Identifying Speakers...**")
272
- progress_bar.progress(80)
273
  diarize_model = whisperx.DiarizationPipeline(use_auth_token=ACTIVE_HF_TOKEN, device=device)
274
 
275
  diarize_kwargs = {}
@@ -278,8 +283,8 @@ if uploaded_file:
278
 
279
  diarize_segments = diarize_model(audio, **diarize_kwargs)
280
 
281
- # 4. Final Merge
282
- st.write("🔗 **Finalizing...**")
283
  final_result = whisperx.assign_word_speakers(diarize_segments, result)
284
 
285
  processed_segments = []
@@ -292,16 +297,20 @@ if uploaded_file:
292
  })
293
 
294
  st.session_state.transcript = processed_segments
 
 
 
 
 
295
  progress_bar.progress(100)
296
- st.success(f"Done! Processed {len(processed_segments)} segments.")
297
 
298
  except Exception as e:
299
- st.error(f"Error during processing: {e}")
300
  if os.path.exists("temp_input"): os.remove("temp_input")
301
  if os.path.exists("temp_audio.wav"): os.remove("temp_audio.wav")
302
  st.stop()
303
 
304
- # --- Display Results if Transcript Exists ---
305
  if "transcript" in st.session_state:
306
  st.divider()
307
  with st.expander("Transcript Preview", expanded=True):
 
79
  if not hasattr(np, 'NaN'):
80
  np.NaN = np.nan
81
 
 
82
  import whisperx
83
 
84
  # --- Configuration & Tokens ---
 
209
 
210
  if uploaded_file:
211
  # --- Auto-Reset Logic for New Files ---
 
212
  if "last_processed_file" not in st.session_state or st.session_state.last_processed_file != uploaded_file.name:
213
  if "transcript" in st.session_state:
214
  del st.session_state.transcript
 
219
  if not ACTIVE_HF_TOKEN or "PASTE_YOUR_HF_TOKEN" in ACTIVE_HF_TOKEN:
220
  st.error("Please provide a valid Hugging Face Token in the Sidebar/Secrets.")
221
  else:
222
+ # Create a dedicated container for the progress UI so it stays at the top
223
+ progress_container = st.container()
224
+ with progress_container:
225
+ st.info("🤖 **Junior Editor is processing your file...**")
226
+
227
+ # Create the visual elements
228
+ status_text = st.empty()
229
  progress_bar = st.progress(0)
230
 
231
  try:
232
+ # Phase 1: Save File & Extract Audio
233
+ status_text.markdown("**Phase 1/4: Extracting Audio...**")
234
  with open("temp_input", "wb") as f:
235
  f.write(uploaded_file.getbuffer())
236
 
 
 
237
  subprocess.run([
238
  "ffmpeg", "-i", "temp_input",
239
  "-vn", "-acodec", "pcm_s16le", "-ar", "16000", "-ac", "1",
240
  "temp_audio.wav", "-y"
241
  ])
242
+ progress_bar.progress(25)
243
 
244
+ # Setup Device
245
  device = "cuda" if torch.cuda.is_available() else "cpu"
246
  if device == "cpu":
247
  st.warning("⚠️ No GPU detected. This will be slow.")
248
 
249
+ # Phase 2: Transcribe
250
+ status_text.markdown(f"**Phase 2/4: Transcribing (Whisper {model_size})... This is the longest step.**")
 
251
 
252
  compute_type = "float16" if device == "cuda" else "int8"
253
  model = whisperx.load_model(model_size, device, compute_type=compute_type)
254
  audio = whisperx.load_audio("temp_audio.wav")
255
+
256
+ # This step takes the most time. It will sit at 25% until complete.
257
+ # This is safer than chunking manually which can cause transcription errors.
258
  result = model.transcribe(audio, batch_size=16, language=target_language)
259
 
260
+ # Cleanup VRAM
261
  del model
262
  gc.collect()
263
  torch.cuda.empty_cache()
264
+ progress_bar.progress(50)
265
 
266
+ # Phase 3: Align
267
+ status_text.markdown("**Phase 3/4: Aligning Text...**")
 
268
  model_a, metadata = whisperx.load_align_model(language_code=result["language"], device=device)
269
  result = whisperx.align(result["segments"], model_a, metadata, audio, device, return_char_alignments=False)
270
 
271
  del model_a
272
  gc.collect()
273
  torch.cuda.empty_cache()
274
+ progress_bar.progress(75)
275
 
276
+ # Phase 4: Diarize
277
+ status_text.markdown("**Phase 4/4: Identifying Speakers...**")
 
278
  diarize_model = whisperx.DiarizationPipeline(use_auth_token=ACTIVE_HF_TOKEN, device=device)
279
 
280
  diarize_kwargs = {}
 
283
 
284
  diarize_segments = diarize_model(audio, **diarize_kwargs)
285
 
286
+ # Final Merge
287
+ status_text.markdown("**Finalizing...**")
288
  final_result = whisperx.assign_word_speakers(diarize_segments, result)
289
 
290
  processed_segments = []
 
297
  })
298
 
299
  st.session_state.transcript = processed_segments
300
+
301
+ # --- CLEANUP ON SUCCESS ---
302
+ if os.path.exists("temp_input"): os.remove("temp_input")
303
+ if os.path.exists("temp_audio.wav"): os.remove("temp_audio.wav")
304
+
305
  progress_bar.progress(100)
306
+ status_text.success(f"Done! Processed {len(processed_segments)} segments.")
307
 
308
  except Exception as e:
309
+ status_text.error(f"Error during processing: {e}")
310
  if os.path.exists("temp_input"): os.remove("temp_input")
311
  if os.path.exists("temp_audio.wav"): os.remove("temp_audio.wav")
312
  st.stop()
313
 
 
314
  if "transcript" in st.session_state:
315
  st.divider()
316
  with st.expander("Transcript Preview", expanded=True):