# How to Prevent Audio Pops at Cut Boundaries in Video Editing

> Prevent jarring audio pops at video cut boundaries. Learn how sudden PCM sample jumps cause pops and easily eliminate them with FFmpeg's afade filter for smooth transitions.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: how-to-guide
- Published: 2026-06-29

---

**Audio pops occur at cut boundaries when PCM samples jump abruptly between non-zero values without zero-crossing, and you eliminate them by applying short 30ms fade-ins and fade-outs to every video segment using FFmpeg's afade filter.**

When concatenating video segments during post-processing, abrupt discontinuities in the audio waveform create sharp edges that the human ear perceives as clicks or pops. The `browser-use/video-use` repository solves this problem by implementing automated micro-fades during the extraction phase, ensuring smooth audio transitions without perceptible volume drops.

## What Causes Audio Pops at Cut Boundaries?

Audio pops arise from **waveform discontinuities** at the exact frame where one clip ends and another begins. Pulse-code modulation (PCM) samples at cut points are rarely at zero-crossing; instead, the waveform jumps instantaneously from one amplitude value to another. This sharp transition contains high-frequency energy that manifests as an audible click.

The severity depends on the amplitude difference between the final sample of the first clip and the initial sample of the second clip. Without processing, these artifacts persist through final encoding and delivery.

## The 30ms Fade Strategy in video-use

The repository prevents audio pops at cut boundaries by baking **30-millisecond fades** into every extracted segment. This duration is long enough to smooth discontinuities yet short enough to remain imperceptible as a deliberate fade effect.

According to the source code in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) (lines 149-190), the implementation constructs an FFmpeg audio filter that applies fade-in at the start and fade-out at the end of each segment.

### Calculating Fade Parameters

The fade logic handles edge cases where segments might be shorter than the fade duration:

```python

# helpers/render.py – fade calculation (Rule 3)

fade_out_start = max(0.0, duration - 0.03)
af = f"afade=t=in:st=0:d=0.03,afade=t=out:st={fade_out_start:.3f}:d=0.03"

```

The `max(0.0, duration - 0.03)` calculation ensures the fade-out begins 30ms before the clip ends, but never starts before time zero, preventing filter errors on extremely short segments.

### Applying Filters During Segment Extraction

The `extract_segment` function (lines 190-207 in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py)) passes the constructed filter to FFmpeg via the `-af` option:

```python
cmd = [
    "ffmpeg", "-y",
    "-ss", f"{seg_start:.3f}",
    "-i", str(source),
    "-t", f"{duration:.3f}",
    "-vf", vf,
    "-af", af,               # ← 30ms fades applied here

    "-c:v", "libx264", "-preset", preset, "-crf", crf,
    "-pix_fmt", "yuv420p", "-r", "24",
    "-c:a", "aac", "-b:a", "192k", "-ar", "48000",
    "-movflags", "+faststart",
    str(out_path),
]

```

Because each segment ends with a fade-out to silence and the subsequent segment begins with a fade-in from silence, the concatenated result contains continuous waveform transitions.

## Implementation Examples

### Raw FFmpeg Command

To apply this technique manually without the Python wrapper:

```bash
ffmpeg -i input.mp4 -ss 12.345 -t 3.210 \
       -af "afade=t=in:st=0:d=0.03,afade=t=out:st=3.177:d=0.03" \
       -c:v copy -c:a aac -b:a 192k output_clip.mp4

```

Note that `st=3.177` equals `3.210 - 0.033`, accounting for the 30ms fade duration.

### Python Integration

Using the repository's `extract_segment` function automatically applies the fade filters:

```python
from pathlib import Path
from helpers.render import extract_segment

source = Path("interview_footage.mp4")
start_time = 45.5
duration = 8.0

extract_segment(
    source=source,
    seg_start=start_time,
    duration=duration,
    grade_filter="",           # no color grading

    out_path=Path("segment_with_fades.mp4")
)

```

This processes the clip with fades baked into the output, ready for seamless concatenation.

## Handling Edge Cases

The implementation guards against three specific failure modes:

- **Segments shorter than 30ms**: The `max()` function clamps the fade-out start to zero, preventing negative timestamps in the FFmpeg filtergraph.
- **Inconsistent segment lengths**: Every segment processed through `extract_segment` receives identical fade treatment, ensuring uniform audio levels across the timeline.
- **Codec compatibility**: Because `afade` operates on decoded PCM samples before re-encoding, the technique works with AAC, MP3, FLAC, or any FFmpeg-supported audio codec.

## Summary

- Audio pops at cut boundaries result from abrupt PCM sample jumps when waveforms do not cross zero between segments.
- The `video-use` repository eliminates these artifacts by applying 30ms fade-ins and fade-outs to every extracted segment.
- The [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) module automatically calculates fade parameters to prevent exceeding segment durations.
- FFmpeg's `afade` filter processes transitions during extraction, baking smooth audio directly into output files.

## Frequently Asked Questions

### Why 30 milliseconds specifically for audio fades?

This duration balances artifact elimination with perceptual transparency. Thirty milliseconds is long enough to smooth the discontinuity that causes audio pops at cut boundaries, yet short enough that listeners perceive the audio as cutting cleanly rather than fading audibly.

### Can this method cause gaps or overlaps when concatenating segments?

No. Each segment ends with a fade-out to digital silence (zero amplitude) and begins with a fade-in from silence. When concatenated, the transition moves from zero to zero, creating a continuous waveform without gaps or overlaps between clips.

### What happens if a video segment is shorter than 30ms?

The code prevents filter errors by calculating `fade_out_start = max(0.0, duration - 0.03)`. For segments shorter than 30ms, this clamps the fade-out start time to zero, causing FFmpeg to shorten the fade proportionally rather than throwing an error or requesting negative timestamps.

### Does this approach work with lossless audio codecs like FLAC?

Yes. The `afade` filter operates on raw PCM samples before the final encode stage, making it codec-agnostic. Whether encoding to AAC at 192kbps or FLAC for archive purposes, the fade processing occurs at the sample level, ensuring pops are eliminated regardless of the output format.