Fullfører oppgave 17.3: Fade/silence-logikk
Tre fikser i audio.rs: 1. Fade-out start clampes til 0 i stedet for å hoppes over når effective_duration < fade_duration. Tidligere ble faden stille droppet — nå starter den alltid fra minst 0. 2. Adaptiv silence-margin: margin (200ms) begrenses til maks halve regionens varighet. Korte stillhetsregioner (<400ms) fikk tidligere hele marginen spist opp og ble aldri kuttet. 3. Ny validate_fade_durations() gir feilmelding når fade-varighet overstiger lydens totale varighet. Kalles fra process_audio etter at vi kjenner faktisk varighet. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4ea0229935
commit
1d1a316a1c
2 changed files with 45 additions and 8 deletions
|
|
@ -387,6 +387,41 @@ pub fn validate_operations(ops: &[EdlOperation]) -> Result<(), String> {
|
|||
}
|
||||
}
|
||||
|
||||
/// Valider fade-varigheter mot faktisk lydvarighet.
|
||||
/// Kalles fra process_audio etter at vi kjenner varigheten.
|
||||
pub fn validate_fade_durations(ops: &[EdlOperation], duration_ms: i64) -> Result<(), String> {
|
||||
let mut errors: Vec<String> = Vec::new();
|
||||
|
||||
for (i, op) in ops.iter().enumerate() {
|
||||
let idx = i + 1;
|
||||
match op {
|
||||
EdlOperation::FadeIn { duration_ms: fade_ms } => {
|
||||
if *fade_ms as i64 > duration_ms {
|
||||
errors.push(format!(
|
||||
"Operasjon {idx} (fade_in): varighet ({fade_ms} ms) \
|
||||
overstiger lydens varighet ({duration_ms} ms)"
|
||||
));
|
||||
}
|
||||
}
|
||||
EdlOperation::FadeOut { duration_ms: fade_ms } => {
|
||||
if *fade_ms as i64 > duration_ms {
|
||||
errors.push(format!(
|
||||
"Operasjon {idx} (fade_out): varighet ({fade_ms} ms) \
|
||||
overstiger lydens varighet ({duration_ms} ms)"
|
||||
));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if errors.is_empty() {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(format!("Ugyldig fade-varighet:\n- {}", errors.join("\n- ")))
|
||||
}
|
||||
}
|
||||
|
||||
// ─── EDL → FFmpeg filtergraf ──────────────────────────────────────
|
||||
|
||||
/// Bygg ffmpeg-filtergraf fra EDL-operasjoner.
|
||||
|
|
@ -509,10 +544,8 @@ pub fn build_filter_chain(
|
|||
}
|
||||
EdlOperation::FadeOut { duration_ms: dur } => {
|
||||
let d = *dur as f64 / 1000.0;
|
||||
let start = (effective_duration_ms as f64 / 1000.0) - d;
|
||||
if start > 0.0 {
|
||||
filters.push(format!("afade=t=out:st={start:.3}:d={d:.3}"));
|
||||
}
|
||||
let start = ((effective_duration_ms as f64 / 1000.0) - d).max(0.0);
|
||||
filters.push(format!("afade=t=out:st={start:.3}:d={d:.3}"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
|
@ -540,6 +573,9 @@ pub async fn process_audio(
|
|||
// Hent info for fade-out beregning
|
||||
let info = get_audio_info(cas, &edl.source_hash).await?;
|
||||
|
||||
// Valider fade-varigheter mot faktisk lydvarighet
|
||||
validate_fade_durations(&edl.operations, info.duration_ms)?;
|
||||
|
||||
// Sjekk om vi trenger to-pass loudnorm
|
||||
let has_normalize = edl.operations.iter().any(|op| matches!(op, EdlOperation::Normalize { .. }));
|
||||
|
||||
|
|
@ -703,8 +739,10 @@ async fn resolve_silence_cuts(
|
|||
{
|
||||
let regions = detect_silence(cas, &edl.source_hash, *threshold_db, *min_duration_ms).await?;
|
||||
for region in regions {
|
||||
// Behold 200ms stillhet på hver side for naturlig lyd
|
||||
let margin_ms = 200;
|
||||
// Behold 200ms stillhet på hver side for naturlig lyd,
|
||||
// men aldri mer enn halve regionens varighet
|
||||
let region_duration = region.end_ms - region.start_ms;
|
||||
let margin_ms = 200i64.min(region_duration / 2);
|
||||
let start = region.start_ms + margin_ms;
|
||||
let end = region.end_ms - margin_ms;
|
||||
if end > start {
|
||||
|
|
|
|||
3
tasks.md
3
tasks.md
|
|
@ -191,8 +191,7 @@ Ref: Kodegjennomgang av `b4c4bb8` (Lydstudio: lydredigering via FFmpeg).
|
|||
|
||||
- [x] 17.1 Responsivt studio-layout: `/studio/[id]` sidebar stacker under waveform på mobil. Verktøypanel som modal/sheet på små skjermer. Ref: feedback om at alt UI skal være responsivt uten unntak.
|
||||
- [x] 17.2 FFmpeg-parametervalidering: valider at alle numeriske verdier (threshold, gain, ratio, frekvenser) er innenfor sikre grenser i `audio.rs` før de interpoleres i filterstrenger. Avvis ugyldige verdier med feilmelding.
|
||||
- [~] 17.3 Fade/silence-logikk: fiks negativ fade-out start (clamp til 0), og adaptiv silence-margin (margin skal ikke overstige halve regionens varighet). Gi feilmelding ved ugyldige fade-varigheter.
|
||||
> Påbegynt: 2026-03-18T05:44
|
||||
- [x] 17.3 Fade/silence-logikk: fiks negativ fade-out start (clamp til 0), og adaptiv silence-margin (margin skal ikke overstige halve regionens varighet). Gi feilmelding ved ugyldige fade-varigheter.
|
||||
- [ ] 17.4 Frontend input-begrensninger: legg til `min`/`max` på alle tallfelter i OperationPanel (silenceThreshold, fadeMs, normTarget, compRatio). Hindre ugyldig input.
|
||||
- [ ] 17.5 Job-polling opprydding: rydd opp interval/timeout ved navigering bort fra studio-siden. Vis feilmelding etter N mislykkede polling-forsøk. Wrap metadata JSON.parse i try/catch.
|
||||
- [ ] 17.6 Temp-fil opprydding: legg til periodisk jobb i maskinrommet som sletter gamle temp-filer i CAS tmp-katalog. Bruk `/tmp` eller sett TTL.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue