For the complete documentation index, see llms.txt. This page is also available as Markdown.

RTSP Simulator

Stream an uploaded video file as a looping RTSP source for testing inference pipelines without a camera.

RTSP Simulator is an edge container service that turns an uploaded video file into a live RTSP stream. Use it to build and test inference pipelines on a device before a physical camera is installed, or to replay a known clip against a Workflow.

You upload an .mp4 file through the web interface or the REST API, the service transcodes it to an RTSP-compatible format, and it publishes the result on a continuous loop until you stop it.

RTSP Simulator is available exclusively for Enterprise customers. Contact the Roboflow sales team to learn more.

Connection Details

Replace <device-ip> with the IP address shown on the device page in Deployment Manager.

Purpose
Address

RTSP stream

rtsp://<device-ip>:8554/stream

Web UI, REST API, and Swagger docs

http://<device-ip>:8080

Port
Protocol
Purpose

8080

HTTP

Web UI, REST API, Swagger docs at /docs

8554

RTSP (TCP)

Video stream output. UDP transport is disabled; clients that prefer UDP negotiate down to TCP-interleaved.

Multiple clients can read the stream at the same time.

Video Format

Only .mp4 files are accepted. Uploads are transcoded automatically so the stream works with any RTSP client:

  • Codec: H.264, Baseline profile

  • Pixel format: yuv420p

  • Audio: stripped, video only

  • Maximum file size: 5 GB by default

Using the Web Interface

Open http://<device-ip>:8080 in a browser.

1

Upload

Drag an .mp4 file onto the page. The file uploads and is converted to the streaming format.

2

Play

Select "Play" to start streaming. The video loops indefinitely and is published to the RTSP server.

3

Connect

Point your inference pipeline, a Deployment Manager stream, or any RTSP client at rtsp://<device-ip>:8554/stream.

4

Stop

Select "Stop" to end the stream and remove the converted files.

To use the simulated stream in a deployment, add it as a stream source on the device the same way you would a camera. See Add a Stream.

Using the CLI

For headless or SSH-only access, the rtsp-cli tool provides an interactive terminal interface on the device.

To import a video without the web UI, copy it into the input directory first, then launch the CLI and press I.

Key
Command
Description

I

Import

Select and convert a video from /data/input/

P

Play

Start RTSP streaming

S

Stop

Stop streaming and delete converted files

D

Delete

Delete video files

C

Config

Adjust stream settings (bitrate, buffer, delay)

R

Refresh

Refresh the status display

Q

Quit

Exit the CLI

Testing the Stream

Connect with any RTSP player to confirm the stream is live.

The stream is served over TCP only, so force TCP transport rather than letting ffplay try UDP first.

HTTP API

All endpoints return JSON. Interactive Swagger documentation is served at http://<device-ip>:8080/docs. See Services for the rules shared by all on-device service APIs.

Typical Flow

/stop also deletes both the original and converted files to free disk space, so a new upload is required before the next /play.

Upload

Only .mp4 is accepted, and an active stream is stopped before the upload begins. The optional settings part is a JSON string of conversion settings applied during transcoding. Because they are baked into the converted file, changing them later requires re-uploading.

Upload a video file

post

Uploads a video and converts it to the RTSP streaming format. Only .mp4 is accepted. An active stream is stopped before the upload begins.

The optional settings part is a JSON string of conversion settings, applied during transcoding. Because they are baked into the converted file, changing them later requires re-uploading.

Body
filestring · binaryRequired

Video file to upload. Must be .mp4.

settingsstringOptional

Optional JSON string holding an UploadSettings object. It is a string part rather than a nested object because the service parses it with json.loads before validating, so the UploadSettings schema below documents the shape rather than being referenced here.

Example: {"target_fps": 30, "crf_quality": 23, "max_width": 1920}
Responses
200

Upload and conversion succeeded

application/json
successbooleanRequired
messagestringRequired
post/upload
POST /upload HTTP/1.1
Host: device-ip:8080
Content-Type: multipart/form-data
Accept: */*
Content-Length: 93

{
  "file": "binary",
  "settings": "{\"target_fps\": 30, \"crf_quality\": 23, \"max_width\": 1920}"
}
{
  "success": true,
  "message": "Video uploaded successfully",
  "video": {
    "filename": "factory_line.mp4",
    "size": 125000000,
    "size_mb": 119.21,
    "extension": ".mp4"
  }
}

Streaming

Start streaming

post

Starts publishing the converted video to the RTSP server, looping until stopped. Uses the current stream settings.

Responses
200

Streaming started

application/json
successbooleanRequired
messagestringRequired
rtsp_urlstringRequired

RTSP stream URL as the service sees it, always naming localhost, on the port set by RTSP_PORT (8554 by default). Consumers off the device must substitute the device address; read rtsp_port from /info rather than assuming 8554.

post/play
POST /play HTTP/1.1
Host: device-ip:8080
Accept: */*
{
  "success": true,
  "message": "Streaming started",
  "rtsp_url": "rtsp://localhost:8554/stream"
}

Stop streaming and delete video files

post

Stops the stream and deletes both the original and converted files to free disk space. Uploading again is required before the next /play.

Responses
200

Streaming stopped and files deleted

application/json
successbooleanRequired
messagestringRequired
post/stop
POST /stop HTTP/1.1
Host: device-ip:8080
Accept: */*
{
  "success": true,
  "message": "text"
}

/delete removes the video files without requiring a stream to be running, stopping one first if it is.

Delete video files

post

Deletes the original and converted video files, stopping the stream first if it is running. Unlike /stop, this succeeds whether or not a stream is active.

Responses
200

Files deleted

application/json
successbooleanRequired
messagestringRequired
post/delete
POST /delete HTTP/1.1
Host: device-ip:8080
Accept: */*
{
  "success": true,
  "message": "text"
}

Status

streaming is true when components.mediamtx.healthy (the streaming server) and components.ffmpeg_process.running (the transcode and publish process) are both true. The components.stream entry does not gate it: components.stream.source_ready can be false briefly during startup while streaming already reads true, which is normal. The breakdown is the fastest way to localize a failed stream: check components to see which part is unhealthy before restarting anything.

Get streaming status

get

Returns whether the stream is live, plus the health of each component, which is the fastest way to localize a failure.

streaming is true when components.mediamtx.healthy and components.ffmpeg_process.running are both true; the components.stream entry does not gate it. components.stream.source_ready can be false briefly during startup, which is normal.

Responses
200

Current status

application/json
streamingbooleanRequired
rtsp_urlstring · nullableOptional

RTSP stream URL as the service sees it, always naming localhost, on the port set by RTSP_PORT (8554 by default). Null when not streaming. Consumers off the device must substitute the device address; read rtsp_port from /info rather than assuming 8554.

get/status
GET /status HTTP/1.1
Host: device-ip:8080
Accept: */*
200

Current status

{
  "streaming": true,
  "rtsp_url": "rtsp://localhost:8554/stream",
  "video": {
    "filename": "sample.mp4",
    "size": 1048576,
    "size_mb": 1,
    "extension": ".mp4"
  },
  "components": {
    "mediamtx": {
      "healthy": true,
      "error": null
    },
    "ffmpeg_process": {
      "exists": true,
      "pid": 1234,
      "running": true,
      "exit_code": null
    },
    "stream": {
      "api_available": true,
      "source_ready": true,
      "readers": 1,
      "error": null
    }
  }
}

/info reports the limits the service is running with, including free disk space and the maximum upload size, which is worth checking before pushing a large file.

Get system information

get

Returns disk space, the upload size limit, accepted extensions, and the RTSP port.

Responses
200

System information

application/json
max_file_sizeintegerRequired

Maximum upload size in bytes, set by MAX_FILE_SIZE

max_file_size_gbnumberRequired
allowed_extensionsstring[]Required

Accepted file extensions. Only .mp4 today.

rtsp_portintegerRequired

Port the RTSP stream is served on, set by RTSP_PORT

get/info
GET /info HTTP/1.1
Host: device-ip:8080
Accept: */*
200

System information

{
  "disk_space": {
    "total": 1,
    "used": 1,
    "free": 1,
    "free_gb": 1
  },
  "max_file_size": 1,
  "max_file_size_gb": 1,
  "allowed_extensions": [
    "text"
  ],
  "rtsp_port": 1
}

Stream Settings Endpoints

Playback settings differ from upload settings: they apply at streaming time and can be changed between sessions without re-uploading. An update takes effect on the next /play, not the stream currently running.

Get stream settings

get

Returns the current playback settings.

Responses
200

Current settings

application/json

Playback settings, changeable between streaming sessions without re-uploading.

max_bitrate_kbpsinteger · min: 100 · max: 100000Optional

Maximum bitrate in kbps

Default: 5000
buffer_size_kbinteger · min: 100 · max: 50000Optional

Buffer size in KB

Default: 3000
max_delay_msinteger · min: 50 · max: 5000Optional

Maximum delay in milliseconds

Default: 500
get/stream-settings
GET /stream-settings HTTP/1.1
Host: device-ip:8080
Accept: */*
200

Current settings

{
  "max_bitrate_kbps": 5000,
  "buffer_size_kb": 3000,
  "max_delay_ms": 500
}

Update stream settings

post

Persists new playback settings. They apply to the next streaming session, not the one currently running.

Body

Playback settings, changeable between streaming sessions without re-uploading.

max_bitrate_kbpsinteger · min: 100 · max: 100000Optional

Maximum bitrate in kbps

Default: 5000
buffer_size_kbinteger · min: 100 · max: 50000Optional

Buffer size in KB

Default: 3000
max_delay_msinteger · min: 50 · max: 5000Optional

Maximum delay in milliseconds

Default: 500
Responses
200

Settings saved

application/json
successbooleanRequired
messagestringRequired
post/stream-settings
POST /stream-settings HTTP/1.1
Host: device-ip:8080
Content-Type: application/json
Accept: */*
Content-Length: 66

{
  "max_bitrate_kbps": 5000,
  "buffer_size_kb": 3000,
  "max_delay_ms": 500
}
{
  "success": true,
  "message": "text"
}

Configuration

Environment Variables

Set these on the service in the device's Configuration tab. See Update Device Configuration.

Variable
Default
Description

MAX_FILE_SIZE

5368709120

Maximum upload size in bytes (5 GB)

RTSP_PORT

8554

RTSP server port

WEB_PORT

8080

Web UI and API port

LOG_LEVEL

INFO

Logging verbosity: DEBUG, INFO, WARNING, or ERROR

Upload Settings

These are applied during conversion, so changing them requires re-uploading the video.

Setting
Default
Description

target_fps

original

Target frame rate, 1 to 120. Omit to keep the original

crf_quality

23

Quality level, 0 to 51 (18 is high, 23 is medium, 28 is low)

max_width

original

Maximum width for downscaling, 320 to 7680. Omit to keep the original

Stream Settings

These are applied at playback and can be changed between streaming sessions from the CLI config menu or the /stream-settings endpoint.

Setting
Default
Description

max_bitrate_kbps

5000

Maximum bitrate in kbps, 100 to 100,000

buffer_size_kb

3000

Buffer size in KB, 100 to 50,000

max_delay_ms

500

Maximum delay in milliseconds, 50 to 5,000

Last updated

Was this helpful?