Skip to content
Merged
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 persists after the composition ends.
---

# Recordings

_Understanding how Fishjam captures composed streams as files_

A **recording** captures the media published by one of a [composition](./compositions)'s outputs and stores it as an MP4 file. A composition is a live process: it produces media while it runs and leaves nothing behind once it is deleted. A recording is the persistent artifact of that process. It remains available after the composition, the room, and the livestream it was created from are gone, and it is stored in Fishjam until you delete it.

```text
composition ──output──▶ livestream / RTMP ──▶ [viewers]
Comment thread
czerwiukk marked this conversation as resolved.
└──recording──▶ MP4 ──▶ [download]
```

## Recorders and outputs

A composition produces media through its outputs, and outputs are the unit that is recorded. To create a recording, you specify a composition and one of its registered outputs, and Fishjam attaches a recorder to that output. The recorder captures the output as it is published: the same layout and resolution, including every scene update, encoded separately from the live stream. There is no separate recording scene. If the recorded file should differ from the live stream, register a dedicated output with its own scene and record that output instead.

Besides composition URL and output ID, the recording API accepts a single option, `scaleRatio`, which sets the recording resolution as a fraction or multiple of the output's resolution. For example, `0.5` stores the recording at half the output resolution.

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

## Composition API and Server API

Compositions are managed through the [Composition API](./../api/reference#compositions), while recordings are created and managed through the [Fishjam Server API](./../api/reference#server), either directly or with the JS and Python server SDKs. This split reflects ownership: a composition is a running session that you configure, whereas a recording is a resource of your Fishjam app, stored alongside your rooms and livestreams and managed with the same management token. You do not interact with the composition to record it; the Server API controls the capture inside the composition on your behalf.

## Lifecycle

A recording has four statuses:

| Status | Meaning |
| ----------- | ------------------------------------------------------- |
| `active` | The output is being captured. |
| `finished` | Capture has ended and the file is being prepared. |
| `available` | The MP4 is ready and `files` contains the download URL. |
| `failed` | An error occurred and no file will be produced. |

Capture starts as soon as the recording is created. It ends when you stop the recording explicitly, or automatically when the recorded output ends or the composition is deleted, so deleting a composition also finalizes its recordings. Finalization is asynchronous: the recording remains `active` until capture has ended, then transitions 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 a recording is `available`, its `files` field lists the media files in playback order as direct HTTPS URLs that you can download or serve to your users. The recording and its files persist until you delete the recording. Deleting the recording is the only way to remove them, and a recording cannot be deleted while it is `active`.

## Metadata

A recording carries optional free-form `metadata`, set at creation and returned with every read. Because recordings accumulate over time, metadata also serves as the primary way to locate them: listing recordings supports filtering by metadata pairs, for example to retrieve every recording 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