Clips
A clip is a bounded time range from a live stream or DVR recording, materialized as an independently playable HLS asset. Clips share their source stream’s playback infrastructure — the same player, the same access policy — but get their own playback ID so you can share, embed, or reference them without exposing the parent stream.
For always-on streams, clips are the lightweight publishing layer on top of the 24/7 DVR archive: keep the full timeline for compliance or replay, then carve out the moments worth sharing.
Creating a clip
Section titled “Creating a clip”Clips are created against a live or recently-completed stream. You provide a time range (typically expressed as startMs / endMs epoch ms) and a name. FrameWorks decides where the bytes come from based on where your range falls:
- Inside the live shm window (last ~120s before now) → pulled from the live stream
- Past shm but inside the rolling DVR window → pulled from the recording origin’s DVR segments
- Inside a finalized chapter (
state ∈ {FINALIZED, FROZEN, RECLAIMED}) → pulled from the canonical chapter.mkv
Cross-source ranges (spanning the shm boundary, or spanning two different chapters) are rejected — split the request into two clips on the same streamId.
mutation CreateClip { createClip( input: { streamId: "<stream global id>" name: "Highlight reel" startMs: 1700000000000 endMs: 1700000060000 } ) { __typename ... on Clip { id clipId name playbackId startMs endMs createdAt } ... on ValidationError { field message } }}The returned playbackId is what you hand to the player or pass to resolveViewerEndpoint. Clip materialization runs asynchronously — the resource exists immediately but the playable manifest may take a few seconds to appear depending on segment availability.
Lifecycle subscription
Section titled “Lifecycle subscription”Subscribe to liveClipLifecycle for real-time creation / readiness / failure events on clips you own:
subscription { liveClipLifecycle { clipId status error }}Listing clips
Section titled “Listing clips”Clips paginate via the standard Relay-style clipsConnection. Filter by streamId to scope to a single source stream, or omit it to list all clips for the tenant.
query MyClips { clipsConnection(page: { first: 20 }) { edges { node { id clipId name playbackId startMs endMs createdAt expiresAt } } pageInfo { hasNextPage endCursor } totalCount }}Use clip(id: ID!) to fetch a single clip by global ID.
Playing back a clip
Section titled “Playing back a clip”Clips share the playback resolution path with streams and VOD assets. Hand the clip’s playbackId to the Player SDK or call resolveViewerEndpoint directly:
query ResolveClip { resolveViewerEndpoint(input: { playbackId: "<clip playback id>" }) { __typename ... on PlaybackEndpoint { hlsUrl lowLatencyHlsUrl protocol } }}Access policy attached to the parent stream (public / JWT / webhook — see playback-access-control) carries through to clips by default.
Deleting a clip
Section titled “Deleting a clip”mutation { deleteClip(id: "<clip global id>") { __typename ... on DeleteClipResult { deleted } ... on ValidationError { field message } }}Deletion is immediate and irreversible. The clip’s segments are removed from storage; the Clip row stays in your account briefly for audit before being garbage-collected.
Agents (MCP)
Section titled “Agents (MCP)”Agents manage clips through the MCP server using create_clip and delete_clip tools. See agents/mcp for the tool catalog.
Related
Section titled “Related”- Recordings, Clips & VOD — DVR and VOD context
- Playback access control — how clip access policy works
- Storage & retention — retention behavior across DVR / clip / VOD