AliJabbarpour commited on
Commit
e733570
·
verified ·
1 Parent(s): 29d2326

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -3
app.py CHANGED
@@ -263,9 +263,60 @@ def run_transcription(audio_path):
263
  )
264
 
265
 
266
- def run_diarization(audio_path):
267
- return diarize_pipeline(audio_path, max_speakers=8)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
269
 
270
  def run_alignment_pass(segments_raw, align_waveform, diarization):
271
  turns = build_speaker_lookup(diarization)
@@ -370,7 +421,7 @@ def process_job(job_id):
370
  align_waveform = align_waveform.mean(dim=0, keepdim=True)
371
 
372
  diarization = run_blocking_with_timeout(
373
- job_id, run_diarization, audio_to_transcribe,
374
  status="aligning", detail="در حال تشخیص گوینده‌ها",
375
  )
376
  update_job(job_id, detail="گوینده‌ها شناسایی شدند")
 
263
  )
264
 
265
 
266
+ def probe_speaker_count(audio_path, job_id=None):
267
+ """
268
+ قبل از اجرای تشخیص گوینده‌ی کامل (که سنگین و کنده)، یه آزمایش سریع انجام می‌ده:
269
+ از ۳ نقطه‌ی پخش‌شده در طول فایل (نه فقط اول)، هرکدوم یه تیکه‌ی ۲۰ ثانیه‌ای برمی‌داره
270
+ و روی همون تیکه‌های کوتاه تشخیص گوینده اجرا می‌کنه.
271
+ اگه هر سه فقط یه گوینده نشون بدن، برمی‌گردونه True (یعنی «به‌احتمال زیاد تک‌گوینده‌ست»)
272
+ وگرنه False (یعنی «باید تشخیص کامل روی کل فایل اجرا بشه»).
273
+ """
274
+ info = torchaudio.info(audio_path)
275
+ duration = info.num_frames / info.sample_rate
276
+ probe_len = 20.0
277
+
278
+ if duration <= probe_len * 3:
279
+ # فایل خیلی کوتاهه، آزمایش جداگانه فایده‌ای نداره - مستقیم برو سراغ تشخیص کامل
280
+ return False
281
+
282
+ fractions = (0.1, 0.5, 0.85)
283
+ waveform, sr = torchaudio.load(audio_path)
284
+
285
+ for frac in fractions:
286
+ center = duration * frac
287
+ start_sec = max(0, center - probe_len / 2)
288
+ end_sec = min(duration, start_sec + probe_len)
289
+ start_sample = int(start_sec * sr)
290
+ end_sample = int(end_sec * sr)
291
+ clip = waveform[:, start_sample:end_sample]
292
+
293
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as tmp:
294
+ torchaudio.save(tmp.name, clip, sr)
295
+ clip_path = tmp.name
296
 
297
+ try:
298
+ probe_result = diarize_pipeline(clip_path, max_speakers=8)
299
+ speakers_found = {speaker for _, _, speaker in probe_result.itertracks(yield_label=True)}
300
+ print(f" [speaker-probe] window at {frac:.0%} of file: {len(speakers_found)} speaker(s)")
301
+ if len(speakers_found) > 1:
302
+ return False
303
+ finally:
304
+ os.remove(clip_path)
305
+
306
+ return True
307
+
308
+
309
+ def run_diarization(audio_path, job_id=None):
310
+ if job_id is not None:
311
+ update_job(job_id, detail="بررسی سریع تعداد گوینده‌ها...")
312
+ single_speaker = probe_speaker_count(audio_path, job_id)
313
+
314
+ if single_speaker:
315
+ print(" [speaker-probe] looks single-speaker across all 3 windows — skipping full search")
316
+ return diarize_pipeline(audio_path, num_speakers=1)
317
+
318
+ print(" [speaker-probe] multiple speakers detected — running full search")
319
+ return diarize_pipeline(audio_path, max_speakers=8)
320
 
321
  def run_alignment_pass(segments_raw, align_waveform, diarization):
322
  turns = build_speaker_lookup(diarization)
 
421
  align_waveform = align_waveform.mean(dim=0, keepdim=True)
422
 
423
  diarization = run_blocking_with_timeout(
424
+ job_id, run_diarization, audio_to_transcribe, job_id,
425
  status="aligning", detail="در حال تشخیص گوینده‌ها",
426
  )
427
  update_job(job_id, detail="گوینده‌ها شناسایی شدند")