Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/api/reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ See also: [What is the Sandbox API?](../explanation/sandbox-api-concept)

## Server

Fishjam Server provides a REST API for managing rooms and peers, and
Fishjam Server provides a REST API for managing rooms, peers, and [recordings](../how-to/compositions/record-a-composition), and
[Protobufs](https://protobuf.dev) for
receiving structured live updates from the server.
The notifications can be configured using Webhook or Websocket.
Expand Down
6 changes: 6 additions & 0 deletions docs/explanation/compositions.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Compositions are built on [Smelter](https://smelter.dev), the source-available r
- **Multi-party layouts**: arrange the cameras of a conference or livestream into grids, side-by-sides, or picture-in-picture.
- **Branded streams**: overlay logos, captions, lower-thirds, and backgrounds on top of live video.
- **Cross-protocol bridging**: take WebRTC inputs and republish the composed result over RTMP, for example broadcasting a conference to YouTube or Twitch, or the other way round.
- **Recordings**: capture the composed stream as an MP4 file to store, replay, or serve on demand.

## Core concepts

Expand Down Expand Up @@ -46,6 +47,10 @@ curl -X DELETE "$COMPOSITION_URL/api/composition/$COMPOSITION" \
-H "Authorization: Bearer $TOKEN"
```

## Recordings

A **recording** saves what one of a composition's outputs publishes into an MP4 file that stays around after the composition is gone. Recordings are a resource of their own, managed through the [Fishjam Server API](./../api/reference#server) rather than the Composition API: [Recordings](./recordings) explains how they work, and [Record a composition](./../how-to/compositions/record-a-composition) walks through making one.

## Scenes

Every video output carries a **scene**: a tree of components that describes how inputs, text, and images are arranged into the composed frame. Audio outputs carry an **audio scene** that describes which inputs are mixed together.
Expand Down Expand Up @@ -109,4 +114,5 @@ Either you push those updates yourself, or you hand the job to a **template**: a
- [Compositions tutorial](./../tutorials/compositions): create your first composition end to end.
- [Write and deploy a template](./../how-to/compositions/write-and-deploy-a-template): build a React layout with the composition SDK.
- [Compose a Fishjam room](./../how-to/compositions/compose-a-fishjam-room): turn a room's peers into one composed stream.
- [Record a composition](./../how-to/compositions/record-a-composition): save an output as an MP4.
- [Composition API](./../api/reference#compositions): the full REST surface.
57 changes: 57 additions & 0 deletions docs/explanation/recordings.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
---
type: explanation
title: Recordings
sidebar_position: 4.6
description: Understand recordings, the Fishjam resource that captures a composition's output into an MP4 file that outlives the session it came from.
---

# Recordings

_Understanding how Fishjam turns live composed streams into files_

A **recording** captures what one of a [composition](./compositions)'s outputs publishes and turns it into an MP4 file. A composition is a live process: it produces media while it runs and leaves nothing behind when it is deleted. A recording is its durable counterpart, the file that remains. It outlives the composition, the room, and the livestream it came from, and it stays in Fishjam until you delete it.

```text
composition ──output──▶ livestream / RTMP ──▶ [viewers]
└──recording──▶ MP4 ──▶ [download]
```

## A recorder attached to an output

A composition produces media through its outputs, so outputs are also the thing you record. When you create a recording, you name a composition and one of its registered outputs, and Fishjam attaches a recorder to that output. From that moment the recorder captures exactly what the output plays out: the same layout, the same encoding, and every scene update along the way. There is no separate recording scene; if the file should look different from the live stream, register a dedicated output with its own scene and record that one instead.

The one knob on the recorder itself is `scaleRatio`, which records at a fraction (or multiple) of the output's resolution, for example `0.5` to store an archive copy at half size.

An output carries at most one recording at a time. To record the same output again, wait until the current recording is no longer `active`.

## Two APIs, one feature

Compositions live on the [Composition API](./../api/reference#compositions), but recordings are created and managed through the [Fishjam Server API](./../api/reference#server), directly or with the JS and Python server SDKs. The split follows ownership: a composition is a running session you configure, while a recording is a resource of your Fishjam app, stored alongside your rooms and livestreams and managed with the same management token. You never talk to the composition to record it; the Server API drives the capture inside the composition for you.

## Lifecycle

A recording moves through four statuses:

| Status | Meaning |
| ----------- | -------------------------------------------------------- |
| `active` | Capturing the output right now. |
| `finished` | Capture has ended; the file is being prepared. |
| `available` | The MP4 is ready; `files` holds the download URL. |
| `failed` | Something went wrong along the way; no file will appear. |

Capture starts the moment the recording is created. It ends when you stop the recording explicitly, or on its own when the recorded output ends or the composition is deleted, so tearing a session down finalizes its recordings too. Finalization is asynchronous: the recording stays `active` until the capture wraps up, then moves through `finished` to `available` once the file is ready.

Every status change emits a `RecordingStatusChanged` [server notification](./../api/reference#protobufs) over your configured webhook or a websocket, so you can react to a file becoming available without polling.

Once `available`, the recording's `files` list its media in playback order as direct HTTPS URLs you can download or hand straight to your users. The recording and its files persist until you delete the recording; deleting is the only way they go away, and an `active` recording cannot be deleted.

## Metadata

A recording carries optional free-form `metadata` that you set at creation and get back with every read. Because recordings accumulate as sessions come and go, metadata is also the handle for finding them later: listing recordings can filter by metadata pairs, for example everything recorded for a given show or customer.

## Where to go next

- [Record a composition](./../how-to/compositions/record-a-composition): start, stop, and download a recording step by step.
- [Compositions](./compositions): the sessions that recordings capture.
- [Server REST API](/api/rest): the complete request and response schemas.
2 changes: 1 addition & 1 deletion docs/how-to/compositions/compose-a-fishjam-room.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ curl -X POST "$COMPOSITION_URL/api/composition/$COMPOSITION/start" \
-H "Authorization: Bearer $TOKEN"
```

Viewers can now watch the composed grid through the livestream's WHEP endpoint.
Viewers can now watch the composed grid through the livestream's WHEP endpoint. To also keep an MP4 of the composed stream, [record the output](./record-a-composition).

## Step 6: Clean up

Expand Down
1 change: 1 addition & 0 deletions docs/how-to/compositions/inputs-and-outputs.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ Other output operations:
- **Update the scene** live with `POST …/output/{output_id}/update` (see [Update a scene](#update-a-scene) below).
- **Force a keyframe** with `POST …/output/{output_id}/request_keyframe`, useful when a new subscriber joins.
- **Unregister** with `POST …/output/{output_id}/unregister`.
- **Record** any output into an MP4 through the Fishjam Server API (see [Record a composition](./record-a-composition)).

## Update a scene

Expand Down
Loading
Loading