Skip to content

Video

Plinken supports video tracks for scoring to picture, a GPU-accelerated compositor for building visual scenes, live camera input, ISF shader effects, and multi-protocol live streaming.

Video file / Camera / Generator
VideoDecoder (per-backend)
Preview Cache (720p NV12 ring buffer)
GPU Pipeline (wgpu)
DAG Renderer → Output (IOSurface / CVPixelBuffer)
PlatformBackendNotes
macOSAVFoundationNative, hardware-accelerated, zero-copy
Cross-platformFFmpegRequires ffmpeg feature flag
WindowsMedia FoundationPlanned
LinuxGStreamerPlanned

The Video module (video) manages playback state. The decoder and frame cache are owned by the Video Panel for thread safety.

ParameterTypeDescription
visibleboolVideo panel visibility
fullscreenboolFullscreen playback mode
studio_modeboolStudio Mode — dual preview/program view
broadcastingboolWhether the broadcast stream is active
video_pathstringPath to the currently loaded video file
current_frameintCurrent frame number (read-only, derived from transport)

Once a video is loaded, the module exposes:

PropertyTypeDescription
Dimensions(u32, u32)Width × height in pixels
Frame ratef64Frames per second
Total framesu64Total frame count
Durationf64Duration in seconds
Command IDNameDescription
video:toggle-visibleShow VideoToggle the video panel
video:toggle-fullscreenToggle FullscreenEnter/exit fullscreen video playback
video:toggle-broadcastToggle BroadcastStart/stop live streaming output
video:loadLoad VideoOpen a video file for playback
video:frame-forwardFrame ForwardStep one frame forward
video:frame-backFrame BackStep one frame back
video:capture-frameCapture FrameSave current frame as PNG
video:extract-maskExtract MaskRun Vision segmentation on current frame
-- Toggle video panel
pl.cmd("video:toggle-visible")
-- Load a video file
pl.cmd("video:load", { path = "/path/to/video.mp4" })
-- Step through frames
pl.cmd("video:frame-forward")
pl.cmd("video:frame-back")
-- Capture the current frame as PNG
pl.cmd("video:capture-frame", {
output_path = "/tmp/frame.png",
mode = "final" -- "preview" or "final"
})
-- Start broadcasting
pl.cmd("video:toggle-broadcast")
-- Read video state
local visible = plinken.get("video", "visible")
local frame = plinken.get("video", "current_frame")

Video playback is synced to the audio transport. The current frame is calculated from the audio sample position:

frame = floor(sample_position / sample_rate × frame_rate)

This ensures frame-accurate lip-sync and hit-point alignment when scoring to picture.

The preview cache stores decoded frames at 720p NV12 in a ring buffer for low-latency playback without keyframe seeking. The background decoder pre-decodes frames ahead of the playhead for smooth scrubbing.

SettingValue
Preview resolution1280 × 720
FormatNV12 (YCbCr 4:2:0)
StrategyRing buffer with background decode

Capture the current compositor frame as a PNG image. Two quality modes:

ModeDescription
previewScreen-resolution capture (fast, used during playback)
finalFull-resolution render (slow, used when stopped)

The Extract Mask command uses Apple Vision framework to detect subjects in the current frame. Detected subjects can be used to create mask layers for compositing.

ShortcutAction
/ Frame back / forward (when video panel focused)
Cmd+LGo Live (start streaming)
Shift+LToggle Studio Mode