Update app.py
Browse files
app.py
CHANGED
|
@@ -248,9 +248,13 @@ def realign_word_timestamps(waveform_16k, words, whisper_start, whisper_end, cut
|
|
| 248 |
print(f" [align] skipped due to: {type(e).__name__}: {e}")
|
| 249 |
return words
|
| 250 |
|
| 251 |
-
|
| 252 |
def run_transcription(audio_path):
|
| 253 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 254 |
audio_path,
|
| 255 |
language="en",
|
| 256 |
word_timestamps=True,
|
|
@@ -261,6 +265,8 @@ def run_transcription(audio_path):
|
|
| 261 |
threshold=0.3,
|
| 262 |
),
|
| 263 |
)
|
|
|
|
|
|
|
| 264 |
|
| 265 |
|
| 266 |
def probe_speaker_count(audio_path, job_id=None):
|
|
@@ -305,6 +311,21 @@ def probe_speaker_count(audio_path, job_id=None):
|
|
| 305 |
|
| 306 |
return True
|
| 307 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 308 |
|
| 309 |
def run_diarization(audio_path, job_id=None):
|
| 310 |
if job_id is not None:
|
|
@@ -312,12 +333,15 @@ def run_diarization(audio_path, job_id=None):
|
|
| 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
|
| 316 |
-
|
|
|
|
|
|
|
| 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)
|
| 323 |
segments = []
|
|
@@ -407,13 +431,13 @@ def process_job(job_id):
|
|
| 407 |
enhanced_path = os.path.join(tmp_dir, "enhanced.wav")
|
| 408 |
save_audio(enhanced_path, enhanced_audio, df_state.sr())
|
| 409 |
audio_to_transcribe = enhanced_path
|
| 410 |
-
|
| 411 |
-
|
| 412 |
job_id, run_transcription, audio_to_transcribe,
|
| 413 |
status="transcribing", detail="مدل large-v3 در حال شنیدن صداست",
|
| 414 |
)
|
| 415 |
-
update_job(job_id, detail="تشخیص
|
| 416 |
-
|
| 417 |
align_waveform, sr = torchaudio.load(audio_to_transcribe)
|
| 418 |
if sr != 16000:
|
| 419 |
align_waveform = torchaudio.functional.resample(align_waveform, sr, 16000)
|
|
@@ -426,7 +450,6 @@ def process_job(job_id):
|
|
| 426 |
)
|
| 427 |
update_job(job_id, detail="گویندهها شناسایی شدند")
|
| 428 |
|
| 429 |
-
segments_raw_list = list(segments_raw)
|
| 430 |
segments = run_blocking_with_timeout(
|
| 431 |
job_id, run_alignment_pass, segments_raw_list, align_waveform, diarization,
|
| 432 |
status="aligning", detail=f"در حال هماهنگسازی زمانبندی {len(segments_raw_list)} جمله",
|
|
|
|
| 248 |
print(f" [align] skipped due to: {type(e).__name__}: {e}")
|
| 249 |
return words
|
| 250 |
|
|
|
|
| 251 |
def run_transcription(audio_path):
|
| 252 |
+
"""
|
| 253 |
+
نکتهی مهم: model.transcribe فوراً برنمیگرده - یه نتیجهی "تنبل" میده که کار
|
| 254 |
+
واقعیش رو دیر انجام میده. برای اینکه کل زمان واقعی پردازش زیر نظارت سقف زمانی و
|
| 255 |
+
پیامهای زنده باشه، همینجا مجبورش میکنیم کارش رو کامل انجام بده (list کردن).
|
| 256 |
+
"""
|
| 257 |
+
segments_raw, info = model.transcribe(
|
| 258 |
audio_path,
|
| 259 |
language="en",
|
| 260 |
word_timestamps=True,
|
|
|
|
| 265 |
threshold=0.3,
|
| 266 |
),
|
| 267 |
)
|
| 268 |
+
segments_list = list(segments_raw)
|
| 269 |
+
return segments_list, info
|
| 270 |
|
| 271 |
|
| 272 |
def probe_speaker_count(audio_path, job_id=None):
|
|
|
|
| 311 |
|
| 312 |
return True
|
| 313 |
|
| 314 |
+
class SingleSpeakerResult:
|
| 315 |
+
"""
|
| 316 |
+
یه نتیجهی «قلابی» که همون شکل خروجی diarize_pipeline رو تقلید میکنه (متد itertracks داره)
|
| 317 |
+
ولی هیچ پردازش واقعیای روی کل فایل انجام نداده - فقط میگه «همهجا همون یه گویندهست».
|
| 318 |
+
"""
|
| 319 |
+
def __init__(self, duration):
|
| 320 |
+
self.duration = duration
|
| 321 |
+
|
| 322 |
+
def itertracks(self, yield_label=False):
|
| 323 |
+
class FakeTurn:
|
| 324 |
+
def __init__(self, start, end):
|
| 325 |
+
self.start = start
|
| 326 |
+
self.end = end
|
| 327 |
+
yield FakeTurn(0, self.duration), None, "SPEAKER_00"
|
| 328 |
+
|
| 329 |
|
| 330 |
def run_diarization(audio_path, job_id=None):
|
| 331 |
if job_id is not None:
|
|
|
|
| 333 |
single_speaker = probe_speaker_count(audio_path, job_id)
|
| 334 |
|
| 335 |
if single_speaker:
|
| 336 |
+
print(" [speaker-probe] looks single-speaker across all 3 windows — skipping full diarization entirely")
|
| 337 |
+
info = torchaudio.info(audio_path)
|
| 338 |
+
duration = info.num_frames / info.sample_rate
|
| 339 |
+
return SingleSpeakerResult(duration)
|
| 340 |
|
| 341 |
print(" [speaker-probe] multiple speakers detected — running full search")
|
| 342 |
return diarize_pipeline(audio_path, max_speakers=8)
|
| 343 |
|
| 344 |
+
|
| 345 |
def run_alignment_pass(segments_raw, align_waveform, diarization):
|
| 346 |
turns = build_speaker_lookup(diarization)
|
| 347 |
segments = []
|
|
|
|
| 431 |
enhanced_path = os.path.join(tmp_dir, "enhanced.wav")
|
| 432 |
save_audio(enhanced_path, enhanced_audio, df_state.sr())
|
| 433 |
audio_to_transcribe = enhanced_path
|
| 434 |
+
|
| 435 |
+
segments_raw_list, info = run_blocking_with_timeout(
|
| 436 |
job_id, run_transcription, audio_to_transcribe,
|
| 437 |
status="transcribing", detail="مدل large-v3 در حال شنیدن صداست",
|
| 438 |
)
|
| 439 |
+
update_job(job_id, detail=f"{len(segments_raw_list)} جمله تشخیص داده شد")
|
| 440 |
+
|
| 441 |
align_waveform, sr = torchaudio.load(audio_to_transcribe)
|
| 442 |
if sr != 16000:
|
| 443 |
align_waveform = torchaudio.functional.resample(align_waveform, sr, 16000)
|
|
|
|
| 450 |
)
|
| 451 |
update_job(job_id, detail="گویندهها شناسایی شدند")
|
| 452 |
|
|
|
|
| 453 |
segments = run_blocking_with_timeout(
|
| 454 |
job_id, run_alignment_pass, segments_raw_list, align_waveform, diarization,
|
| 455 |
status="aligning", detail=f"در حال هماهنگسازی زمانبندی {len(segments_raw_list)} جمله",
|