> ## Documentation Index
> Fetch the complete documentation index at: https://rendi.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Dynamic Files

> Flexible handling of compressed folders, sequence patterns, and multi-output commands.

Rendi supports FFmpeg commands that work with **dynamic inputs and outputs** - cases where the number of files isn't known ahead of time or is determined by the command itself.

### Supported Dynamic Patterns

| Pattern        | Type         | Description                                                   |
| -------------- | ------------ | ------------------------------------------------------------- |
| `%0d` / `%03d` | Input/Output | Sequence patterns for numbered files (e.g., `frame_%03d.png`) |
| `tee`          | Output       | Write to multiple outputs simultaneously                      |
| `segment`      | Output       | Split output into multiple segment files                      |
| `image2`       | Input        | Read image sequences with glob patterns                       |
| `concat`       | Input        | Concatenate multiple files from a list                        |
| `HLS/DASH`     | Input/Output | Streaming manifests with multiple segments                    |

To use these patterns with Rendi, you'll typically need **compressed folders** for input or the **OUTPUT\_FOLDER** flag for output.

***

## Dynamic Inputs

Rendi supports using a **compressed .zip folder** as an FFmpeg input source. This enables commands that require multiple input files, such as image sequences (`%0d` patterns), HLS playlists, or concat demuxer lists.

Use the field `input_compressed_folder` to supply a URL pointing to a `.zip` file. Rendi automatically downloads and **decompresses** the archive before running your FFmpeg command.

> **Important:** Command run time includes the time required to decompress the `.zip` file.

### Using custom fonts

To use custom fonts or auxiliary files (e.g., subtitles, watermarks), bundle everything together in a `.zip` and use `input_compressed_folder`.

> **Important:** When using `input_compressed_folder`, **all** input files must be inside the ZIP — do not use the `input_files` field alongside it.

For example, to add subtitles with a custom font to a video, create a ZIP containing:

* `sample_popeye_meets_sinbad.mp4` - your video file
* `sample_popeye_meets_sinbad.srt` - your subtitle file
* `Poppins-Regular.ttf` - a font that supports your target script

```bash theme={null}
curl --location 'https://api.rendi.dev/v1/run-ffmpeg-command' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data '{
  "input_compressed_folder": "https://storage.rendi.dev/sample/popeye_meets_sinbad_custom_font.zip",
  "output_files": {
    "out_1": "sample_popeye_meets_sinbad_subtitled.mp4"
  },
  "ffmpeg_command": "-i sample_popeye_meets_sinbad.mp4 -vf \"subtitles=sample_popeye_meets_sinbad.srt:fontsdir=.:force_style='\''FontName=Poppins,FontSize=24,PrimaryColour=&HFFFFFF,OutlineColour=&H4066B66B,Outline=1,BorderStyle=3'\''\" -c:v libx264 -c:a copy {{out_1}}"
}'
```

The FFmpeg command uses:

* `-i sample_popeye_meets_sinbad.mp4` - Reads the video file from the decompressed ZIP
* `subtitles=sample_popeye_meets_sinbad.srt` - References the subtitle file from the same decompressed ZIP
* `fontsdir=.` - Tells FFmpeg to look for fonts in the current (decompressed) directory
* `force_style='FontName=Poppins,...'` - Applies the custom font and styling. Use the font's **FontName** (found by opening the font file), not the filename

This approach works for any use case where FFmpeg needs to reference auxiliary files like fonts, text files, subtitle files, or watermark images — bundle everything into a single ZIP.

> **Tip:** For text overlays with custom fonts, use `drawtext=fontfile=MyFont.ttf:text='Hello':fontcolor=white:fontsize=60`. See the [FFmpeg Cheatsheet](https://github.com/rendi-api/ffmpeg-cheatsheet?tab=readme-ov-file#overlay-text-on-video) for more details.

### Using HLS recording as input stored in a ZIP folder

This example demonstrates processing an HLS recording stored in a ZIP archive. The sample ZIP at [playlist\_sample.zip](https://storage.rendi.dev/sample/playlist_sample.zip) contains:

* `playlist.m3u8` - the HLS playlist file
* `output0.ts`, `output1.ts`, `output2.ts` - the video segments

```bash theme={null}
curl --location 'https://api.rendi.dev/v1/run-ffmpeg-command' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data '{
  "input_compressed_folder": "https://storage.rendi.dev/sample/playlist_sample.zip",
  "output_files": {
    "out_1": "recording.mp4"
  },
  "ffmpeg_command": "-i playlist.m3u8 -c:v libx264 -crf 23 -c:a aac -b:a 128k {{out_1}}",
  "vcpu_count": 8
}'
```

The FFmpeg command reads the HLS playlist, re-encodes the video to H.264 (CRF 23 for balanced quality/size) and audio to AAC, then outputs a single MP4 file.

> **Tip:** For faster processing without re-encoding, use `-c copy -bsf:a aac_adtstoasc` instead.

### Using indexed image frames to create a video

This example demonstrates creating a video from a sequence of numbered image frames stored in a ZIP archive. The ZIP should contain files like `frame_001.png`, `frame_002.png`, etc.

```bash theme={null}
curl --location 'https://api.rendi.dev/v1/run-ffmpeg-command' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data '{
  "input_compressed_folder": "https://storage.rendi.dev/sample/big_buck_bunny_720p_5sec_30fps_frames.zip",
  "output_files": {
    "out_1": "video.mp4"
  },
  "ffmpeg_command": "-framerate 30 -i frame_%03d.png -c:v libx264 -pix_fmt yuv420p {{out_1}}",
  "vcpu_count": 8
}'
```

The FFmpeg command uses:

* `-framerate 30` - Sets the input frame rate to 30 FPS
* `-i frame_%03d.png` - Reads sequentially numbered frames (frame\_001.png, frame\_002.png, ...)
* `-c:v libx264` - Encodes output as H.264 video
* `-pix_fmt yuv420p` - Ensures compatibility with most video players

> **Tip:** Adjust the pattern to match your file naming (e.g., `img_%04d.jpg` for img\_0001.jpg, img\_0002.jpg, etc.).

## Dynamic Outputs

Rendi also supports **compressed output folders**. To enable this, set the `output_files` field to the special flag:

```
OUTPUT_FOLDER
```

When this flag is used, Rendi creates a `.zip` archive containing **only the output files** produced by your FFmpeg command.

> **Important:** Command runtime includes the time required to compress the output folder.

### Extracting frames from an input video and storing them in a zip

This example extracts individual frames from a video and packages them into a ZIP archive. The output can be used as input for the "Using indexed image frames to create a video" example above.

```bash theme={null}
curl --location 'https://api.rendi.dev/v1/run-ffmpeg-command' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data '{
  "input_files": {
    "in_1": "https://storage.rendi.dev/sample/big_buck_bunny_720p_5sec.mp4"
  },
  "output_files": "OUTPUT_FOLDER",
  "ffmpeg_command": "-i {{in_1}} -vf fps=30 frame_%03d.png"
}'
```

The FFmpeg command uses:

* `-i {{in_1}}` - Reads the input video file
* `-vf fps=30` - Extracts frames at 30 frames per second
* `frame_%03d.png` - Outputs frames as `frame_001.png`, `frame_002.png`, etc.

The resulting ZIP contains all extracted frames, ready to be used with `input_compressed_folder` for video reconstruction or other processing.

> **Tip:** Adjust the `fps` value to control frame extraction density. Use `fps=1` for 1 frame per second, or omit `-vf fps=30` entirely to extract every frame at the video's native framerate.

### Generating an HLS output folder and storing it as a ZIP

```bash theme={null}
curl --location 'https://api.rendi.dev/v1/run-ffmpeg-command' \
--header 'X-API-KEY: <api-key>' \
--header 'Content-Type: application/json; charset=utf-8' \
--data '{
    "input_files": {
        "in_1": "https://storage.rendi.dev/sample/sample.avi"
    },
    "output_files": "OUTPUT_FOLDER",
    "ffmpeg_command": "-i {{in_1}} -t 25 -c:v h264 -c:a aac -b:v 2000k -b:a 128k -hls_time 5 -hls_list_size 0 -f hls playlist.m3u8"
}'
```

## Response Format for Compressed Output Folders

In addition to the usual fields, the response includes extra metadata describing the generated `.zip` archive:

```json theme={null}
{
  "command_id": "41938bd7-3550-46d8-87c3-9d0b3200e7fb",
  "status": "SUCCESS",
  "command_type": "FFMPEG_COMMAND",
  "total_processing_seconds": 31.964526,
  "ffmpeg_command_run_seconds": 3.218038558959961,
  "vcpu_count": 8,
  "output_files": {
    "OUTPUT_FOLDER": {
      "file_id": "8d9ebcfb-f560-4858-af5c-bd5bf426d874",
      "storage_url": "https://storage.rendi.dev/files/.../41938bd7-3550-46d8-87c3-9d0b3200e7fb.zip",
      "status": "STORED",
      "rendi_store_type": "OUTPUT",
      "is_deleted": false,
      "size_mbytes": 6.900238990783691,
      "file_type": "zip",
      "file_format": "zip",
      "file_count": 6,
      "size_compressed_mbytes": 5.120238990783691
    }
  }
}
```

### Field Descriptions

* **file\_count** - Number of files contained inside the output `.zip` folder.
* **size\_mbytes** - Total size (MB) of all files *before* compression.
* **size\_compressed\_mbytes** - Final compressed `.zip` size stored in Rendi.
* **file\_format** - Always `zip`.
* **storage\_url** - The download URL of the compressed output folder.

> The compressed output file name is: **`<command_id>.zip`**

***

## Processing & Storage Quota

1. **Processing quota for inputs** is calculated based on the size of the files **after decompression**.
2. **Processing quota for OUTPUT\_FOLDER** uses the size of files **before compression**.
3. **Storage usage** is based on the size of the **compressed .zip file**.
