# How the Per-Segment Extraction Pipeline Avoids Double-Encoding in Video-Use

> Learn how the per-segment extraction pipeline in browser-use/video-use avoids double-encoding by generating each video segment once and losslessly concatenating them for efficient video processing.

- Repository: [Browser Use/video-use](https://github.com/browser-use/video-use)
- Tags: internals
- Published: 2026-07-09

---

**The per-segment extraction pipeline encodes each edit-decision-list (EDL) range as a separate MP4 file before losslessly concatenating them with `ffmpeg -c copy`, ensuring every video segment undergoes only one generation of compression instead of multiple re-encodes.**

The **per-segment extraction pipeline** is the core rendering architecture in the `browser-use/video-use` repository, designed to transform edit-decision-lists (EDLs) into final videos while preserving maximum quality. Unlike traditional single-pass filtergraphs that re-encode footage multiple times during processing, this workflow strategically isolates each segment to prevent generational quality loss.

## The Three-Stage Pipeline

The pipeline operates through distinct phases defined in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), each optimized to minimize quality degradation.

### Stage 1: Individual Segment Extraction

For every range specified in the EDL, the `extract_segment` function (lines 49–63 in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py)) performs a targeted extraction:

- **Direct seeking** using `ffmpeg -ss` jumps to the exact start timestamp without decoding preceding frames
- **Duration trimming** via `-t` captures only the specified length
- **Resolution scaling** applies portrait-aware transformations to match target dimensions
- **Colour grading** bakes the `grade_filter` (e.g., "warm_cinematic") directly into the encoded output
- **Audio fade-in/fade-out** applies 30 ms `afade` filters at both edges to prevent audible pops, as mandated by Rule 3 of the project specification

Each segment is encoded **once** using quality-appropriate CRF values: **CRF 20** for final renders, **CRF 22** for previews, and **CRF 28** for draft outputs.

### Stage 2: Lossless Concatenation

After all segments are extracted, the `concat_segments` function (lines 67–78 in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py)) generates a temporary concat demuxer list and executes:

```bash
ffmpeg -c copy -f concat -i segments.txt output.mp4

```

The **`-c copy`** flag instructs ffmpeg to copy the video and audio streams without re-encoding, preserving the exact binary quality of each extracted segment.

### Stage 3: Final Overlay Application

Overlays, subtitles, and graphics are applied **after** concatenation using copy-only operations where possible, avoiding any decode-encode cycles on the base video layers.

## Why Single-Pass Filtergraphs Cause Double-Encoding

Traditional video editing workflows often employ a single-pass filtergraph that processes the entire timeline at once. According to [`SKILL.md`](https://github.com/browser-use/video-use/blob/main/SKILL.md) (lines 23–26), this approach forces ffmpeg to:

1. Decode each input segment
2. Apply colour grades, overlays, and filters to the full timeline
3. **Re-encode the entire output** to a new compressed stream
4. Decode and re-encode again during final concatenation or overlay application

Each additional encode step introduces **generational loss** (particularly problematic with lossy codecs like H.264/H.265) and consumes unnecessary CPU cycles. The per-segment pipeline eliminates this by encoding each slice exactly once and maintaining **lossless concatenation** throughout assembly.

## Practical Implementation

### Command-Line Usage

Execute the full pipeline from the terminal using the render module:

```bash

# Standard quality render

python -m helpers.render edl.json -o final.mp4

# Fast 720p preview mode (CRF 22)

python -m helpers.render edl.json -o preview.mp4 --preview

# Ultrafast draft mode (CRF 28)

python -m helpers.render edl.json -o draft.mp4 --draft

```

These commands internally invoke `extract_all_segments` → `extract_segment` for each EDL range, followed by `concat_segments` for assembly.

### Programmatic API

Integrate the pipeline into Python applications:

```python
from pathlib import Path
from helpers.render import extract_all_segments, concat_segments

edl = {
    "grade": "warm_cinematic",
    "ranges": [
        {"source": "clip1", "start": 0.0, "end": 4.5},
        {"source": "clip2", "start": 10.0, "end": 15.2},
    ],
    "sources": {"clip1": "src/clip1.mov", "clip2": "src/clip2.mov"},
}

edit_dir = Path("/tmp/my_edit")

# Extract with colour grade and 30ms audio fades baked in

segments = extract_all_segments(edl, edit_dir, preview=False, draft=False)

# Join without re-encoding

output = edit_dir / "final.mp4"
concat_segments(segments, output, edit_dir)
print(f"Rendered to {output}")

```

The `extract_all_segments` call automatically applies colour grading and audio fades, while `concat_segments` guarantees a lossless join via stream copying.

## Key Source Files

- **[`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py)**: Implements `extract_segment`, `extract_all_segments`, and `concat_segments` — the core per-segment pipeline logic
- **[`SKILL.md`](https://github.com/browser-use/video-use/blob/main/SKILL.md)**: Documents architectural design rules explaining why per-segment extraction is preferred over single-pass filtergraphs
- **[`helpers/timeline_view.py`](https://github.com/browser-use/video-use/blob/main/helpers/timeline_view.py)**: Provides timeline visualization utilities for calculating segment offsets and subtitle timing

## Summary

- The **per-segment extraction pipeline** splits EDL ranges into individual MP4 files before final assembly
- **`ffmpeg -c copy`** concatenation preserves original encoding quality by avoiding re-encode steps
- Each segment undergoes **exactly one encode** with CRF values tuned to render mode (final/preview/draft)
- **30 ms audio fades** (`afade`) prevent pops at segment boundaries
- Overlays and subtitles are applied post-concatenation to prevent forcing additional encode cycles

## Frequently Asked Questions

### What is double-encoding and why is it harmful?

**Double-encoding** occurs when video data is decoded and re-encoded multiple times during production, compounding compression artifacts with each cycle. Since codecs like H.264 are lossy, every re-encode discards additional visual information, resulting in blocking, banding, and softness. The per-segment pipeline avoids this by ensuring each source range is compressed only once.

### How does the concat_segments function prevent quality loss?

The `concat_segments` function (lines 67–78 in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py)) uses ffmpeg's concat demuxer with the `-c copy` flag, which instructs the encoder to copy the existing video and audio bitstreams directly into the output container without decompressing and recompressing the frames. This **lossless concatenation** preserves the exact pixel data of each extracted segment.

### What CRF settings does the pipeline use for different render modes?

According to the implementation in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), the pipeline uses **CRF 20** for final high-quality renders, **CRF 22** for preview renders (faster encoding at 720p), and **CRF 28** for draft renders (maximum speed during editing). These constants ensure appropriate quality-to-performance ratios for each use case.

### Can I add overlays without triggering a re-encode?

Overlays are applied **after** the `concat_segments` step in the pipeline architecture. While complex compositing may require encoding, the design attempts to use copy-only operations where possible. For simple watermarking or subtitle burning, the system minimizes unnecessary encode cycles, though certain overlay types inherently require a final encode pass.