DEV Community

Bastien Sulyan
Bastien Sulyan

Posted on Originally published at bsulyan.github.io

How to Clean Up Podcast and Remote Interview Audio Directly in the Browser

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:

  1. Stream extraction vs. transcoding: If your downstream DAW accepts .m4a, you only need to demux the moov and mdat atoms. 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.
  2. 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();
}
Enter fullscreen mode Exit fullscreen mode

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;
}
Enter fullscreen mode Exit fullscreen mode

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)