Composing filters
Chaining one-input filters
output = source("input.mkv")
.std.resize(#{ width: 1280, height: 720 })
.std.crop(#{ left: 0, top: 0, width: 1280, height: 700 })
Combining multiple clips
y = source("input.mkv").std.split_plane(#{ plane: 0 })
u = source("input.mkv").std.split_plane(#{ plane: 1 })
v = source("input.mkv").std.split_plane(#{ plane: 2 })
output = std.merge_planes([y, u, v], #{ format: "yuv420p8" })
a = source("part-1.mkv")
b = source("part-2.mkv")
output = std.join([a, b])
left = source("left.mkv")
right = source("right.mkv")
output = std.stack_horizontal([left, right])
Multi-input filters use array input form. Every array entry must be a clip.
Filters define their own media-matching rules. For example, std.join([a, b])
requires fixed format, fixed resolution, finite frame count, and constant
positive frame rate on every input; matching format, resolution, and frame
rate across inputs; and allows different input frame counts.
Metadata-only multi-input filters also use array input form:
target = source("graded.mkv")
metadata_source = source("original.mkv")
output = std.copy_props([metadata_source, target])
Metadata-aware workflows
register_prop extends metadata schema at script time so metadata-validating filters can
plan against custom keys.
Register key before filter validates or writes plugin-defined metadata:
register_prop("acme/filter:enabled", "bool")
output = source("input.mkv")
.std.set_prop(#{ key: "acme/filter:enabled", value: true })
.std.require_prop(#{ key: "acme/filter:enabled", kind: "bool", value: true })
Use this when downstream filter needs custom metadata key with known type.
Reading metadata in scripts
prop retrieves a frame metadata value during script evaluation. This lets a script choose
graph structure or filter options from metadata on an already-built clip prefix.
register_prop("acme/filter:enabled", "bool")
clip = source("input.mkv")
.std.set_prop(#{ key: "acme/filter:enabled", value: true })
enabled = clip.prop("acme/filter:enabled")
output = clip
if enabled == true {
output = clip.std.resize(#{ width: 1280, height: 720 })
}
Use prop(clip, frame, key) when the value may differ by frame. Prop reads can index
sources and render the requested frame while the script is being evaluated, so prefer reading
only the metadata needed to choose the graph.