Skip to main content

What is a clip?

Once a model has recording enabled, your app can ask Reactor for two types of clip from a live session:
  • Snap clip: the last N seconds of the session.
  • Full recording: everything from the start of the session up to now.
Both return a Clip object you can hand to the SDK’s player to preview, or to its download helpers to save as a single MP4. The same object works either way.
Reactor does not host clips. The URL you receive from Reactor expires after 24 hours, so it is not suitable for sharing. If you want users to keep a clip, download it immediately and host the resulting MP4 yourself.
Reactor holds clips for 24 hours and then deletes them. None of this data is used for training.

Capturing a clip

Recording lives on the Reactor instance. In React, reach it via useReactor() inside a ReactorProvider.
requestClip / request_clip takes a duration in seconds and grabs the live session up to that point in the past. It is capped server-side at 5 minutes by default. requestRecording / request_recording takes no arguments and grabs the full session from the start of recording up to now. Both resolve with the same Clip object.
Both methods can only be called when the connection status is "ready". Otherwise they throw (JavaScript: a RecordingError with code DISCONNECTED; Python: an InvalidStateError) — and a request still in flight when the session disconnects raises DisconnectedError the same way.

Previewing a clip

Play a captured clip in place. In React, drop a ClipPlayer into your UI and pass the clip; it renders a native <video controls> element. Imperatively, assemble the clip into an MP4 with downloadClipAsFile() and point a <video> at the blob.
ClipPlayer does not require a ReactorProvider in the tree, so it keeps working after the session has ended.
ClipPlayer streams the clip as HTTP Live Streaming (HLS), a protocol that breaks video into small chunks served over HTTP. Safari plays it natively, while Chrome, Firefox, and Edge need hls.js installed as an optional peer dependency. The imperative downloadClipAsFile route above returns a plain MP4 and needs no extra dependency.
See ClipPlayer for the full prop list.

Downloading a clip

ClipDownloadButton renders a plain <button> that reflects download state and triggers a browser save dialog when clicked. Pass the same token you use to connect as getJwt so the component can authenticate the download.
React
For non-React apps, or when you need the assembled MP4 directly, call downloadClipAsFile() (JavaScript) or download_clip() (Python):
download_clip() streams interleaved MPEG-TS to path, not an MP4 like the JavaScript SDK’s downloadClipAsFile() assembles — playable as-is by most players (ffplay, VLC, mpv), but remux with ffmpeg -i highlight.ts -c copy highlight.mp4 first if you specifically need that container. Given a path it returns None and never holds more than one segment in memory — the one to use for request_recording(), which has no upper bound on length. Omit path and it returns the assembled bytes instead, holding the whole clip in memory to do it. Pass on_progress=lambda done, total: ... to track either one. See record.py for a full runnable version (python -m examples.record --clip 10 --download clip.ts).
Don’t need the Clip itself — its session_id, markers, or predicted_ready_at_ms — before downloading? reactor.download_clip(seconds, path) / reactor.download_recording(path) do the request and the download in one call. record.py --simple runs that side of the example: python -m examples.record --clip 10 --download clip.ts --simple.
Building your own download UI? The headless useClipDownload hook exposes the same state machine as ClipDownloadButton, so you can render a progress bar, a menu item, or anything else.

Putting it together

A small React app that displays a live model, captures a 10-second snap, and previews it alongside a download button.
React

Error handling

Any recording-specific failure raises a RecordingError. The React components surface it inline already, so you only need to catch it when you call requestClip or requestRecording directly.
The Python SDK does not have a distinct RecordingError type — a recording failure raises whichever ReactorError subclass matches its code (InvalidStateError, DisconnectedError, …), the same hierarchy every other SDK call uses. except ReactorError still catches all of them.
See RecordingError for the full list of codes (JavaScript SDK).