# video-use 12 Hard Production Rules: The Complete Technical Reference

> Explore the 12 hard production rules for video-use. Ensure flawless video output and prevent build failures with this essential technical reference. Understand vital constraints for reliable media.

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

---

**video-use enforces 12 non-negotiable hard production rules that prevent silent failures, broken output, and mis-aligned media by aborting the build whenever any constraint is violated.**

The `browser-use/video-use` repository guarantees production-correctness through a rigorous set of video-use hard production rules documented in [`SKILL.md`](https://github.com/browser-use/video-use/blob/main/SKILL.md) and enforced across [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py), and [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py). These constraints prevent double-encoding, audio pops, and subtitle desync while ensuring deterministic, cacheable results across the automated video editing pipeline.

## Rendering Pipeline Rules

The first five hard rules govern FFmpeg filter chains, lossless processing, and timeline synchronization to ensure pixel-perfect output.

### Rule 1: Subtitles Applied Last in Filter Chain

Subtitles must be applied **last** in the FFmpeg filter chain, after every overlay. According to [`SKILL.md`](https://github.com/browser-use/video-use/blob/main/SKILL.md), this guarantees captions remain visible above graphics and animations.

In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), the implementation builds the overlay chain first, then appends the subtitle filter:

```python

# … after all overlay filters have been built …

subtitle_filter = f"subtitles={master_srt_path}:force_style='...'"
cmd = [
    "ffmpeg", "-y", "-i", segment_path,
    "-filter_complex", f"{overlay_chain},{subtitle_filter}",
    "-c:a", "copy", output_path,
]

```

### Rule 2: Lossless Per-Segment Extract and Concat

Per-segment extraction must use **lossless `-c copy`**, followed by concatenation via the demuxer, rather than a single-pass filtergraph. This avoids double-encoding each segment, preserving quality and reducing render time.

The [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) implementation extracts segments with:

```python
subprocess.run(["ffmpeg", "-i", src, "-ss", start, "-to", end,
                "-c", "copy", segment_file])

```

Then concatenates via:

```python
with open("list.txt", "w") as f:
    for seg in segment_files:
        f.write(f"file '{seg}'\n")
subprocess.run(["ffmpeg", "-f", "concat", "-safe", "0",
                "-i", "list.txt", "-c", "copy", final_output])

```

### Rule 3: 30ms Audio Fades at Segment Boundaries

Every segment boundary requires **30ms audio fades** to eliminate audible pops during cuts. The fade parameters are `afade=t=in:st=0:d=0.03` for fade-in and `afade=t=out:st={dur-0.03}:d=0.03` for fade-out.

In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py):

```python
fade_in = "afade=t=in:st=0:d=0.03"
fade_out = f"afade=t=out:st={duration-0.03}:d=0.03"
audio_filter = f"{fade_in},{fade_out}"

```

### Rule 4: Overlay Timing with setpts Normalization

Overlays must use `setpts=PTS-STARTPTS+T/TB` to shift the overlay’s frame 0 to its window start. This prevents animation frames from appearing before their intended time.

As implemented in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py):

```python
overlay_filter = "[1]setpts=PTS-STARTPTS+{offset}/TB[ov]"
cmd = ["ffmpeg", "-i", video, "-i", overlay,
       "-filter_complex", f"{overlay_filter};[0][ov]overlay"]

```

### Rule 5: Master SRT Output-Timeline Offsets

The master SRT must use **output-timeline offsets** calculated as `output_time = word.start - segment_start + segment_offset`. This keeps subtitles synchronized after segment concatenation.

The [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py) function adjusts timestamps before feeding to FFmpeg:

```python
def shift_srt(word_start, seg_start, seg_offset):
    return word_start - seg_start + seg_offset

```

## Audio Integrity and Transcription Rules

Rules 6 through 9 ensure cut precision, transcript accuracy, and deterministic caching.

### Rule 6: Word-Boundary Snap for Cuts

Never cut inside a word. Every cut edge must snap to a word boundary from the Scribe transcript. This guarantees intelligible speech and prevents clipping words.

In [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py):

```python
cut_time = round_nearest_word_boundary(requested_cut)

```

### Rule 7: 30-200ms Padding on Cut Edges

Pad every cut edge by **30–200ms** to absorb Scribe timestamp drift (typically 50–100ms). This safety margin ensures cuts land on clean audio.

The padding logic in [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) applies:

```python
pad = max(0.03, min(0.2, estimated_drift))
final_start = cut_time - pad
final_end = cut_time + pad

```

### Rule 8: Word-Level Verbatim ASR Only

Use **word-level verbatim ASR** exclusively. Never use SRT/phrase mode or normalized fillers, as these discard sub-second timing data required for precise cuts.

This constraint is enforced in [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py) when calling the Scribe API, ensuring the JSON output contains per-word timestamps.

### Rule 9: Transcript Caching Per Source

Cache transcripts per source file and never re-transcribe unless the source file itself changes. This saves API quota and guarantees deterministic results.

In [`helpers/transcribe.py`](https://github.com/browser-use/video-use/blob/main/helpers/transcribe.py):

```python
cache_path = f"{cache_dir}/{source_path.stem}.json"
if cache_path.exists() and not source_path.stat().st_mtime > cache_path.stat().st_mtime:
    load_from_cache(cache_path)
else:
    scribe_call(...)

```

## Workflow Architecture Rules

The final three rules govern parallelization, user confirmation, and directory isolation.

### Rule 10: Parallel Animation Sub-Agents

Run animations via **parallel sub-agents**, never sequentially. This bounds wall-clock time to the duration of the slowest animation rather than the sum of all animations.

In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py):

```python
for slot in slots:
    agents.append(Agent(tool="Animation", params=slot))
await asyncio.gather(*[a.run() for a in agents])

```

### Rule 11: Strategy Confirmation Before Execution

Never touch the cut until the user approves a plain-English plan. This prevents unintended edits and ensures the LLM’s reasoning is reviewed before execution.

This rule is enforced by the conversational workflow defined in [`SKILL.md`](https://github.com/browser-use/video-use/blob/main/SKILL.md), which requires explicit user confirmation before proceeding to the render phase.

### Rule 12: Isolated Output Directory Structure

All session outputs must live in `<videos_dir>/edit/`. Never write inside the `video-use/` project directory. This keeps the skill’s source clean and isolates user data.

In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py):

```python
output_dir = Path(edit_dir) / "edit"
output_path = output_dir / "final.mp4"
output_dir.mkdir(parents=True, exist_ok=True)

```

## Summary

The video-use 12 hard production rules create a bulletproof pipeline that guarantees production-correctness:

- **Subtitles and overlays** are sequenced correctly with proper timeline offsets to prevent visual obstruction and desync
- **Lossless extraction** and **word-boundary cuts** with **30ms fades** preserve audio-visual quality and intelligibility
- **Word-level ASR** and **deterministic caching** ensure precise timing and API efficiency
- **Parallel execution** and **user confirmation** optimize performance while preventing unintended edits
- **Directory isolation** maintains clean separation between application code and user assets

## Frequently Asked Questions

### What happens if a video-use hard production rule is violated?

The build aborts immediately and the self-evaluation step flags the specific error. No preview is shown to the user until all 12 rules pass verification, ensuring only production-correct videos reach the final output stage.

### Why does video-use require 30ms audio fades instead of crossfades?

The 30ms fade duration specifically targets the elimination of audible pops at segment boundaries without introducing the latency or computational overhead of crossfades. As implemented in [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), these fades use the `afade` filter with precise start and duration parameters.

### How does video-use ensure subtitles remain visible above overlays?

Rule 1 mandates that subtitles are applied **last** in the FFmpeg filter chain. In [`helpers/render.py`](https://github.com/browser-use/video-use/blob/main/helpers/render.py), the `subtitles` filter is appended after the `overlay_chain` in the `-filter_complex` argument, ensuring graphics never obscure captions.

### Can the 30-200ms padding values be adjusted for different transcription engines?

While the [`helpers/grade.py`](https://github.com/browser-use/video-use/blob/main/helpers/grade.py) implementation uses `max(0.03, min(0.2, estimated_drift))` to bound padding between 30ms and 200ms, these values are optimized for Scribe's observed 50-100ms drift. Adjusting these constants would require modifying the source code and validating against the new ASR service's timing characteristics.