How to Implement Custom Color Grading Filters with grade.py in video-use

The grade.py module in browser-use/video-use generates ffmpeg filter strings through built-in presets, automatic per-clip analysis, or raw filter inputs that you can extend by modifying the PRESETS dictionary or passing custom ffmpeg expressions.

The browser-use/video-use toolkit provides a flexible color grading system centered in helpers/grade.py. Whether you need subtle corrections or dramatic cinematic looks, this module allows you to implement custom color grading filters using three distinct approaches that integrate seamlessly with the rendering pipeline.

Understanding the Color Grading Architecture

The grade.py module serves as the central authority for generating ffmpeg-compatible filter strings. It offers three primary input methods: built-in presets defined in the PRESETS dictionary (lines 38-63), automatic per-clip analysis via auto_grade_for_clip (lines 78-154), and raw ffmpeg filter strings passed directly through CLI or EDL configurations.

When processing video segments, helpers/render.py calls resolve_grade_filter (lines 66-84) to determine which grading strategy to apply. This function distinguishes between preset names, the literal "auto" string for automatic grading, and verbatim ffmpeg expressions before passing the resolved filter to extract_segment (lines 79-86) for final application.

Method 1: Extending Built-In Presets

The simplest way to implement custom color grading filters is by extending the PRESETS dictionary in helpers/grade.py. This dictionary maps user-friendly names to valid ffmpeg filter expressions, making them accessible via CLI --preset flags or EDL grade fields.

To add a custom preset, locate the PRESETS definition around line 38 and append your filter chain:


# helpers/grade.py – add after the existing PRESETS block

PRESETS["my_cinematic"] = (
    "eq=contrast=1.15:brightness=-0.03:saturation=0.90,"
    "curves=master='0/0 0.25/0.22 0.75/0.78 1/1'"
)

The get_preset function (lines 66-73) retrieves these values by key, allowing immediate usage:

python helpers/grade.py input.mp4 -o out.mp4 --preset my_cinematic

Method 2: Automatic Per-Clip Analysis

For dynamic color correction that adapts to individual clip characteristics, use the automatic grading mode. When resolve_grade_filter encounters the string "auto", it returns the sentinel __AUTO__, triggering auto_grade_for_clip (lines 78-154) during segment processing.

This function samples frames using _sample_frame_stats (lines 84-124) to compute brightness, contrast, and saturation statistics, then generates a subtle "clean-up" filter tailored to each specific clip. Enable this mode in an EDL by setting "grade": "auto":

{
  "grade": "auto",
  "ranges": [
    {"source": "clip1", "start": 0.0, "end": 5.0}
  ],
  "sources": {"clip1": "videos/clip1.mp4"}
}

Method 3: Passing Raw FFmpeg Filter Strings

When presets lack the specificity you need, pass raw ffmpeg filter strings directly via the --filter CLI flag or the EDL grade field. This bypasses resolve_grade_filter entirely, applying your expression unchanged to the video filter chain.

python helpers/grade.py input.mp4 -o out.mp4 --filter 'eq=contrast=1.12:gamma=0.95:saturation=1.02'

In EDL configurations, any grade value that isn't "auto" and doesn't match a preset key is treated as a literal filter string.

Integrating Custom Filters into the Render Pipeline

Understanding how grade.py interfaces with helpers/render.py ensures your custom filters apply correctly during final output. The extract_all_segments function (lines 23-31) orchestrates the rendering process, calling extract_segment for each EDL range.

During extraction, resolve_grade_filter (lines 66-84) determines the appropriate filter string for each segment. If you've added a custom preset to grade.py, this function automatically recognizes it through get_preset. The resolved filter string then gets appended to the video-filter chain in extract_segment (lines 79-86), ensuring every clip receives its specified color grade.

Programmatic Implementation Examples

For Python-based workflows, import the grading functions directly to apply filters programmatically:

from pathlib import Path
from helpers.grade import get_preset, apply_grade

inp = Path("raw.mov")
out = Path("final.mov")
filter_str = get_preset("high_contrast")          # ← retrieve preset

apply_grade(inp, out, filter_str)                # ← runs ffmpeg with the filter

To implement a high-contrast preset in the source code:


# helpers/grade.py – add after the existing PRESETS block

PRESETS["high_contrast"] = "eq=contrast=1.20:saturation=1.05"

Apply it via CLI:

python helpers/grade.py source.mov -o graded.mov --preset high_contrast

Summary

  • Built-in presets offer reusable ffmpeg filter chains stored in the PRESETS dictionary (lines 38-63) of helpers/grade.py.
  • Automatic grading analyzes per-clip statistics via _sample_frame_stats (lines 84-124) and auto_grade_for_clip (lines 78-154) when EDL specifies "grade": "auto".
  • Raw filter strings bypass preset resolution entirely, allowing direct ffmpeg expressions through CLI --filter or EDL grade fields.
  • The render pipeline in helpers/render.py automatically resolves and applies grades through resolve_grade_filter (lines 66-84) during extract_segment (lines 79-86).

Frequently Asked Questions

How do I add a new color grading preset to grade.py?

Open helpers/grade.py and locate the PRESETS dictionary around line 38. Add a new key-value pair where the key is your preset name and the value is a valid ffmpeg filter string. For example: PRESETS["vintage"] = "eq=contrast=1.1:saturation=0.8,curves=r='0/0 0.5/0.4 1/0.9'". The preset becomes immediately available via --preset vintage or "grade": "vintage" in EDL files.

What is the difference between preset and auto grading modes?

Preset mode applies static ffmpeg filter strings defined in the PRESETS dictionary consistently across all clips. Auto grading dynamically analyzes each clip's brightness, contrast, and saturation statistics through auto_grade_for_clip and generates a unique filter chain per segment. Use presets for uniform stylistic looks and auto mode for technical correction that adapts to varying source footage.

Can I use multiple filters in a single custom preset?

Yes. The PRESETS dictionary values accept full ffmpeg filtergraph expressions. Chain multiple filters using commas: "eq=contrast=1.15,curves=master='0/0 0.25/0.22 0.75/0.78 1/1',hue=s=0.9". Ensure proper quoting when filters contain spaces or special characters.

Where does the render pipeline apply the grade filter during video processing?

The resolve_grade_filter function in helpers/render.py (lines 66-84) determines the appropriate filter string, which then gets appended to the ffmpeg command in extract_segment (lines 79-86) during the segment extraction phase. This occurs within the extract_all_segments loop (lines 23-31), ensuring each EDL range receives its specified color grade before final composition.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →