From d7ffb95374c822629f6faf886e3a06302f3db01a Mon Sep 17 00:00:00 2001 From: "Dylan M. Taylor" Date: Tue, 3 Nov 2026 14:42:25 +0000 Subject: [PATCH] fix(export): encode WebM audio packets in place instead of draining each from the front --- crates/export/src/webm.rs | 8 +++++--- crates/export/src/webm_av1.rs | 8 +++++--- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/crates/export/src/webm.rs b/crates/export/src/webm.rs index a12bd4e1a..976eaf6e0 100644 --- a/crates/export/src/webm.rs +++ b/crates/export/src/webm.rs @@ -244,12 +244,14 @@ pub(crate) async fn webm(job: &Cx<'_>, comp: &Comp, w: u32, h: u32, st: &mut Sta let pad = (fs - pcm_left.len() % fs) % fs + fs; pcm_left.extend(std::iter::repeat_n(0.0, pad)); } - while pcm_left.len() >= fs { - let pkt = enc.encode_float(&pcm_left[..fs]); - pcm_left.drain(..fs); + // Packets are read in place and the encoded samples dropped once: draining each packet + // from the front would shift the rest of the batch's audio every 20 ms. + for packet in pcm_left.chunks_exact(fs) { + let pkt = enc.encode_float(packet); frames.push(Frame { ms: packets as i64 * 20, track: 2, key: true, prev_ms: None, data: pkt, alpha: None }); packets += 1; } + pcm_left.drain(..pcm_left.len() / fs * fs); }; let batch = batch_size(); diff --git a/crates/export/src/webm_av1.rs b/crates/export/src/webm_av1.rs index ca06a3e51..6fc26ac85 100644 --- a/crates/export/src/webm_av1.rs +++ b/crates/export/src/webm_av1.rs @@ -124,12 +124,14 @@ pub(crate) async fn webm_av1(job: &Cx<'_>, comp: &Comp, w: u32, h: u32, st: &mut let pad = (fs - pcm_left.len() % fs) % fs + fs; pcm_left.extend(std::iter::repeat_n(0.0, pad)); } - while pcm_left.len() >= fs { - let pkt = enc.encode_float(&pcm_left[..fs]); - pcm_left.drain(..fs); + // Packets are read in place and the encoded samples dropped once: draining each packet + // from the front would shift the rest of the batch's audio every 20 ms. + for packet in pcm_left.chunks_exact(fs) { + let pkt = enc.encode_float(packet); blocks.push(Block { ms: packets as i64 * 20, track: 2, key: true, data: pkt }); packets += 1; } + pcm_left.drain(..pcm_left.len() / fs * fs); }; let batch = batch_size();