How to Use VapourSynth Filter in FFmpeg

This guide explains how to use FFmpeg's built-in vapoursynth video filter to process video files with VapourSynth scripts. You will learn the requirements needed for your FFmpeg build, how to handle input frames within a Python script using the native video_in object, and the exact command-line syntax to execute your scripts during encoding.

Prerequisites

To use the filter, your FFmpeg binary must be compiled with VapourSynth support. You can verify this by checking your build configuration:

ffmpeg -filters | grep vapoursynth

If the output lists vapoursynth, your installation is ready. If not, you must install or compile an FFmpeg build configured with the --enable-vapoursynth flag, alongside an installed VapourSynth environment and Python.

1. Writing the VapourSynth Script

When using the vapoursynth filter in an FFmpeg pipeline, FFmpeg exposes the input video stream to Python as a predefined variable named video_in.

Create a Python script named filter.vpy:

import vapoursynth as vs
core = vs.core

# video_in is automatically injected by FFmpeg's filter
clip = video_in

# Example: Apply a simple blur using the built-in box blur
clip = core.std.BoxBlur(clip)

# Set the final output for FFmpeg to retrieve
clip.set_output()

Do not load a source file using source filters (such as ffms2 or L-SMASH-Works) inside the script when processing an existing FFmpeg input; video_in handles frame delivery directly from FFmpeg.

2. Executing the Script via FFmpeg

To run the script on an input file, call the vapoursynth filter inside your -vf (video filter) argument and specify the script path with the file parameter:

ffmpeg -i input.mp4 -vf "vapoursynth=file='filter.vpy'" -c:v libx264 -crf 18 -c:a copy output.mp4

Filter Parameters

  • file: Specifies the path to the .vpy script file.
  • script: Allows passing raw VapourSynth code directly as an inline string instead of referencing an external file:
ffmpeg -i input.mp4 -vf "vapoursynth=script='import vapoursynth as vs; core = vs.core; clip = video_in; clip = core.std.Invert(clip); clip.set_output()'" -c:v libx264 output.mp4

3. Using VapourSynth as the Source Generator

You can also use the filter without an input video file by calling it through the lavfi virtual input device. In this scenario, your script generates or imports its own source (e.g., using core.std.BlankClip() or standard VapourSynth source plugins):

Create source.vpy:

import vapoursynth as vs
core = vs.core

# Generate a 10-second test pattern
clip = core.std.BlankClip(format=vs.YUV420P8, width=1920, height=1080, length=240, fpsnum=24, fpsden=1)
clip.set_output()

Run FFmpeg with lavfi:

ffmpeg -f lavfi -i "vapoursynth=file='source.vpy'" -c:v libx264 output.mp4