Remote interviews recorded over WebRTC, Zoom, or Riverside frequently suffer from three compounding acoustic problems: low-frequency HVAC rumble below 80 Hz, broadband room reverberation mixed into the vocal band, and uneven dialogue pacing between speakers. Moving raw multi-gigabyte video recordings through cloud upload queues to fix these issues introduces latency and exposes unreleased recordings to third-party storage buckets.
This guide walks through a deterministic, client-side signal processing workflow to demux video containers, isolate vocal stems, and adjust playback cadence directly in browser memory.
1. Demuxing Video Containers Without Re-Encoding Loss
Many remote recording platforms export multi-track or composite .mp4 and .mkv files where the audio stream is already encoded as AAC (mp4a.40.2) or Opus at 48 kHz. Uploading a 1.5 GB .mp4 file to a remote server just to strip the video track wastes bandwidth.
When preparing an interview for editing or ASR transcription, the first step is extracting the audio stream locally:
-
Stream extraction vs. transcoding: If your downstream DAW accepts
.m4a, you only need to demux themoovandmdatatoms. If your podcast host or transcription pipeline requires constant-bitrate MP3 (libmp3lame), transcoding at 192 kbps stereo (or 96 kbps mono for single-voice speech) reduces file size by over 85% compared to the source video container. - Sample rate consistency: Keep speech tracks at 48,000 Hz or 44,100 Hz. Avoid arbitrary resampling steps between 44.1 kHz and 48 kHz, which introduce aliasing artifacts near the upper sibilance band (6 kHz to 9 kHz).
You can perform this extraction locally in WebAssembly using the Sunasty MP4 to MP3 Converter, which reads the container directly from the local File handle without transmitting media bytes over the network.
2. High-Pass Filtering and Vocal Stem Isolation
Once you have the raw audio buffer, speech intelligibility depends on separating direct vocal energy (fundamental frequencies between 85 Hz and 255 Hz, plus formants up to 4 kHz) from stationary background noise and bleed.
Filtering Sub-Vocal Rumble with Web Audio BiquadFilterNode
Before applying any spectral separation, a second-order Butterworth high-pass filter at 80 Hz ($Q = 0.7071$) removes microphone stand vibrations, plosives, and air-conditioning hum without thinning out chest resonance:
async function applyHighPassFilter(audioBuffer, cutoffHz = 80) {
const offlineCtx = new OfflineAudioContext(
audioBuffer.numberOfChannels,
audioBuffer.length,
audioBuffer.sampleRate
);
const source = offlineCtx.createBufferSource();
source.buffer = audioBuffer;
const highPass = offlineCtx.createBiquadFilter();
highPass.type = 'highpass';
highPass.frequency.setValueAtTime(cutoffHz, 0);
highPass.Q.setValueAtTime(Math.SQRT1_2, 0);
source.connect(highPass);
highPass.connect(offlineCtx.destination);
source.start(0);
return offlineCtx.startRendering();
}
Spectral Vocal Isolation
When a remote guest records in an untreated room with background music, fan noise, or crosstalk, standard gate plugins often clip word tails (creating choppy decay). Time-frequency masking via Short-Time Fourier Transform (STFT) separates the harmonic vocal stem from the non-vocal residual accompaniment.
For tracks with noticeable background bleed or ambient beds, running the recording through the client-side Sunasty Vocal Remover isolates the center-channel vocal stem from the ambient bed entirely on-device. A complete breakdown of EQ cut points, de-essing thresholds, and LUFS loudness targets (-16 LUFS for stereo podcasts, -19 LUFS for mono) is documented in our technical reference on cleaning audio for podcasts.
3. Time-Stretching and Cadence Adjustment Without Pitch Distortion
During editorial review or pre-transcription auditing, producers often need to tighten slow delivery (for example, speeding a segment up to 1.10x or 1.15x) or slow down dense technical terminology (0.85x) to verify phonetic accuracy.
Naive resampling changes playback duration by altering the sample clock, which shifts pitch proportionally ($\Delta f = f_0 \cdot r$, producing the classic chipmunk effect). Phase vocoder and WSOLA (Waveform Similarity Overlap-Add) algorithms decouple tempo from pitch by slicing the time-domain signal into overlapping Hann-windowed frames (typically 20 ms to 30 ms for speech) and realigning phase coherence at the target synthesis hop size:
function createHannWindow(frameSize) {
const win = new Float32Array(frameSize);
for (let n = 0; n < frameSize; n++) {
win[n] = 0.5 * (1 - Math.cos((2 * Math.PI * n) / (frameSize - 1)));
}
return win;
}
For speech signals, WSOLA preserves transient crispness on consonants (p, t, k) better than large-window FFT phase vocoders, which can introduce phase smearing ("phasiness") around sibilants. To adjust track tempo with pitch lock enabled and export the resulting waveform directly in the browser, use the Sunasty Audio Speed & Pitch Changer.
Summary Checklist for Browser-Based Podcast Post-Production
| Stage | Target Parameter | Purpose |
|---|---|---|
| Container Demux | 48 kHz PCM / 192 kbps MP3 | Strip video track without cloud upload |
| High-Pass Filter | 80 Hz, $Q = 0.707$ | Eliminate plosives and HVAC rumble |
| Stem Isolation | STFT vocal stem extraction | Suppress ambient bleed and background beds |
| Tempo Normalization | 1.05x–1.15x WSOLA pitch-locked | Tighten pacing without formant shift |
| Loudness Target | -16 LUFS integrated, -1.0 dBTP | Consistent playback across podcast directories |
Top comments (0)