Fix first word being cut at clip start ('Žena' problem)
Real-world failure: 'Ansambel Saša Avsenika - ŽENA ME TEPE'
- Refren starts with 'Žena me tepe' at 78.0s
- Scribe's segment boundary: word 'Žena' was end of previous segment (73.9-78.2s)
while new segment 'tepe, mi prazni žepe' started at 78.3s
- Claude picked clip start = 78.3s (segment boundary)
- Fade-in 0.4s on vocal start = inaudible 'Že-'
- User hears: '...na me tepe' (cut)
Three-part fix:
1. PROMPT: instruct Claude to start clip ~0.3s BEFORE first chorus word
(not exactly at it). Concrete example with timing math.
2. POST-LLM EXTENSION: scan corrected_segments for boundary cases:
- If clip start falls MID-segment → extend back to segment start - 0.2s
- If a previous segment ended within 0.5s of clip start → check if its
last word might actually be the first chorus word, extend back to it
- Uses word-level timestamps when available (Scribe provides these)
3. FADE-IN: was 0.4s when starting on vocal — too long, audibly cuts first
word. Reduced to 0.05s (just click prevention, not audible). Still 0.2s
for instrumental intros where fade is musically appropriate.
Now 'Žena' will be heard fully — clip starts at ~77.5-77.7s, word starts
at 78.0s, plenty of buffer.
This commit is contained in:
parent
1cc8e8be35
commit
a5097c5acc
@ -742,9 +742,12 @@ def detect_audio_fade(clip_range, transcript, video_duration=None):
|
||||
if video_duration is not None:
|
||||
extended_end = min(extended_end, video_duration)
|
||||
|
||||
fade_in = 0.4 if starts_in_vocal else 0.2
|
||||
# Fade-in: če clip začne MED vokalom, fade-in mora biti zelo kratek
|
||||
# da ne odreže prve besede. Pri vokalnem začetku samo 0.05s "smooth click prevention",
|
||||
# ne pravi audible fade. Pri instrumentalnem intro lahko 0.2-0.3s.
|
||||
fade_in = 0.05 if starts_in_vocal else 0.2
|
||||
# Krajši fade out (0.5s) ker zdaj clip konča po koncu vokala
|
||||
fade_out = 0.5 if ends_in_vocal else 0.3
|
||||
fade_out = 0.3 if ends_in_vocal else 0.4
|
||||
|
||||
return {
|
||||
"fade_in": fade_in,
|
||||
@ -838,7 +841,8 @@ PROSIM:
|
||||
## ⚠️ ABSOLUTNO PRAVILO: clip se ZAČNE na PRVI BESEDI prvega refrena
|
||||
- **NE** vključuj kateri koli verz, pre-chorus, build-up, ali intro
|
||||
- **NE** začni "tik pred" refrenom
|
||||
- **Začetek = točno tam, kjer prva vrstica refrena prvič začne**
|
||||
- **Začetek = ~0.3s PRED prvo besedo refrena** (npr. če prva beseda refrena "Žena" začne pri 78.0s, izberi start = 77.7s)
|
||||
- **Razlog**: 0.3s buffer da ne odrežeš prve besede zaradi audio fade-in efekta
|
||||
|
||||
## Identifikacija refrena (univerzalno čez jezike):
|
||||
- Najdi del, ki se v pesmi **ponavlja vsaj 2-krat** (običajno 3-4x)
|
||||
@ -1350,6 +1354,57 @@ def main():
|
||||
duration # ne čez celoten audio
|
||||
)
|
||||
|
||||
# ── EXTEND clip START nazaj če Claude začne sredi besede/segmenta ──
|
||||
# Refren se pogosto začne na isti besedi kot v transkriptu, ampak Scribe
|
||||
# lahko zazna mejo med segmenti **PO** prvi besedi refrena (npr.
|
||||
# "Žena me tepe" — beseda "Žena" v prejšnjem segmentu pri 78.0s,
|
||||
# nov segment začne pri 78.3s s "tepe"). To pomeni Claude reže
|
||||
# PRED besedo "Žena" → odrezana.
|
||||
#
|
||||
# Strategija: če clip start pade SREDI segmenta (ne tik na začetku),
|
||||
# razširi nazaj na začetek tega segmenta + 0.2s buffer.
|
||||
current_start = clip_range["start"]
|
||||
for seg in corrected_segs:
|
||||
seg_start = float(seg.get("start", 0))
|
||||
seg_end = float(seg.get("end", 0))
|
||||
# Segment ki se prekriva s clip start (start je MED njim)
|
||||
if seg_start < current_start < seg_end:
|
||||
# Razširi nazaj — vendar samo če je segment kratek (<3s) in
|
||||
# se "naslanja" na clip (zadnja beseda lahko vodi v refren)
|
||||
if (seg_end - seg_start) < 3.0:
|
||||
new_start = max(0, seg_start - 0.2) # 0.2s buffer pred prvo besedo
|
||||
if new_start < current_start:
|
||||
print(f" 🎵 Razširim clip začetek {current_start:.1f}s → {new_start:.1f}s "
|
||||
f"(prva beseda refrena je v prejšnjem segmentu)", file=sys.stderr)
|
||||
current_start = new_start
|
||||
break
|
||||
# Segment ki se konča TOČNO ali tik pred clip start (lahko zadnja
|
||||
# beseda refrena = "Žena" se konča na 78.2 ko clip začne 78.3)
|
||||
elif current_start - 0.5 <= seg_end <= current_start + 0.1:
|
||||
# Preveri ali zadnja beseda v segmentu morda **začne refren**
|
||||
seg_text = seg.get("text", "").strip()
|
||||
# Če segment kaže novo frazo (z veliko začetnico po pavzi) ali
|
||||
# vsebuje znake interpunkcije, morda zadnja beseda res začne refren
|
||||
if seg_text and (seg_end - seg_start) < 4.0:
|
||||
# Razširi nazaj na začetek POSLEDJE besede tega segmenta
|
||||
words = seg.get("words", [])
|
||||
if words:
|
||||
last_word = words[-1]
|
||||
new_start = max(0, float(last_word.get("start", seg_start)) - 0.15)
|
||||
else:
|
||||
# Brez word-level: vzemi 0.5s nazaj
|
||||
new_start = max(0, current_start - 0.5)
|
||||
if new_start < current_start:
|
||||
print(f" 🎵 Razširim clip začetek {current_start:.1f}s → {new_start:.1f}s "
|
||||
f"(zadnja beseda prejšnjega segmenta morda začne refren)", file=sys.stderr)
|
||||
current_start = new_start
|
||||
break
|
||||
|
||||
if current_start < clip_range["start"]:
|
||||
clip_range["start"] = round(current_start, 2)
|
||||
clip_range["duration"] = round(clip_range["end"] - current_start, 2)
|
||||
clip_range["reason"] += f" (start extended back)"
|
||||
|
||||
# Najdi vse segmente ki se začnejo PO trenutnem clip end
|
||||
for seg in corrected_segs:
|
||||
seg_start = float(seg.get("start", 0))
|
||||
|
||||
Loading…
Reference in New Issue
Block a user