6262)
6363WHISPER_MODEL = os .path .join (
6464 os .path .dirname (os .path .dirname (os .path .abspath (__file__ ))),
65- "bin" , "models" , "ggml-large-v3-turbo-q5_0 .bin" ,
65+ "bin" , "models" , "ggml-large-v3.bin" ,
6666)
6767
6868WHISPER_THREADS = 8
@@ -256,16 +256,24 @@ def search_segment(t_norm: list, whisper_words: list, w_starts: list,
256256
257257
258258def _bootstrap_offset (whisper_words : list , transcript_segs : list ,
259- max_segs : int = 40 ) -> float | None :
259+ max_segs : int = 40 ,
260+ max_raw_t : float = 180.0 ) -> float | None :
260261 """
261262 Estimate the initial raw_time − transcript_time offset by finding the
262- first 4-word exact run shared between the transcript and whisper words.
263+ first 4-word exact run shared between the transcript (first max_segs
264+ segments) and the whisper output (first max_raw_t seconds only).
265+
266+ Constraining to the first max_raw_t seconds of whisper prevents a rare
267+ false match deep in the audio from producing a wildly wrong initial offset.
263268
264269 Returns offset (float) or None if nothing found.
265270 """
266271 w_norm = [((norm_words (w ["word" ]) or ["" ])[0 ]) for w in whisper_words ]
267272 w_starts = [w ["start" ] for w in whisper_words ]
268273
274+ # Only search within the first max_raw_t seconds of whisper output
275+ wi_limit = bisect .bisect_right (w_starts , max_raw_t )
276+
269277 for seg in transcript_segs [:max_segs ]:
270278 tn = norm_words (seg ["text" ])
271279 t_start = float (seg ["start" ])
@@ -274,12 +282,12 @@ def _bootstrap_offset(whisper_words: list, transcript_segs: list,
274282 continue
275283 for gi in range (len (tn ) - 3 ):
276284 gram = tn [gi :gi + 4 ]
277- for wi in range (len (w_norm ) - 3 ):
285+ for wi in range (min ( wi_limit , len (w_norm ) - 3 ) ):
278286 if w_norm [wi :wi + 4 ] == gram :
279- # gram starts at gi/len(tn) through the segment
280287 word_frac = gi / len (tn )
281288 approx_gram_t = t_start + word_frac * seg_dur
282- return w_starts [wi ] - approx_gram_t
289+ offset = w_starts [wi ] - approx_gram_t
290+ return offset
283291 return None
284292
285293
@@ -783,7 +791,8 @@ def parse_episode_filter(spec: str) -> set:
783791 return result
784792
785793
786- def process_episode (ep_num : int , transcript_path : str , mp3_path : str ):
794+ def process_episode (ep_num : int , transcript_path : str , mp3_path : str ,
795+ skip_step3 : bool = False ):
787796 print (f"\n { '═' * 60 } " , flush = True )
788797 print (f" Episode { ep_num } — { os .path .basename (mp3_path )} " , flush = True )
789798 print (f"{ '─' * 60 } " , flush = True )
@@ -810,8 +819,11 @@ def process_episode(ep_num: int, transcript_path: str, mp3_path: str):
810819 print_alignment_report (aligned , transcript_segs )
811820
812821 # ── Step 3 ────────────────────────────────────────────────────────────────
813- print (f"\n [Step 3] Rerun whisper on stripped audio + compare" , flush = True )
814- step3_rerun_compare (ep_num , mp3_path , aligned )
822+ if skip_step3 :
823+ print (f"\n [Step 3] skipped (--skip-step3)" , flush = True )
824+ else :
825+ print (f"\n [Step 3] Rerun whisper on stripped audio + compare" , flush = True )
826+ step3_rerun_compare (ep_num , mp3_path , aligned )
815827
816828
817829def main ():
@@ -821,6 +833,8 @@ def main():
821833 )
822834 parser .add_argument ("--episodes" , default = None ,
823835 help = 'e.g. "152" or "150-152" or "150,152"' )
836+ parser .add_argument ("--skip-step3" , action = "store_true" ,
837+ help = "skip the stripped-audio re-transcription step" )
824838 args = parser .parse_args ()
825839
826840 if not os .path .isfile (WHISPER_CLI ):
@@ -834,12 +848,14 @@ def main():
834848 if not episodes :
835849 sys .exit ("No matching episodes found." )
836850
837- print (f"Found { len (episodes )} episode(s). Running all 3 steps." )
851+ steps = "steps 1+2" if args .skip_step3 else "all 3 steps"
852+ print (f"Found { len (episodes )} episode(s). Running { steps } ." )
838853
839854 errors = 0
840855 for ep_num , transcript_path , mp3_path in episodes :
841856 try :
842- process_episode (ep_num , transcript_path , mp3_path )
857+ process_episode (ep_num , transcript_path , mp3_path ,
858+ skip_step3 = args .skip_step3 )
843859 except Exception as exc :
844860 import traceback
845861 print (f"\n ✗ ep{ ep_num } FAILED: { exc } " , flush = True )
0 commit comments