> For the complete documentation index, see [llms.txt](https://docs.roboflow.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.roboflow.com/workflows/deploy/video-processing.md).

# Video processing with Workflows

Choose managed Cloud Streaming for live cameras, or process webcams, camera feeds, and video files on a self-hosted Inference Server.

For managed live-camera processing, use [Cloud Streaming](https://docs.roboflow.com/deployment/roboflow-cloud/cloud-streaming). It connects camera sources to Workflow jobs on Roboflow-managed compute. Follow the [quickstart](https://docs.roboflow.com/deployment/roboflow-cloud/cloud-streaming/quickstart) to connect, preview, deploy, view results, and stop processing.

Use [Batch Processing](https://docs.roboflow.com/deployment/roboflow-cloud/batch-processing) for stored media that should finish as a finite job. A connector-local file in Cloud Streaming loops as a live test source instead.

## Self-hosted video

The Inference SDK WebRTC client below runs video through a Workflow on your own Inference Server. It keeps one session open while processing frames, supports stateful blocks such as trackers and counters, and avoids separate HTTP requests for each frame.

Start the [Inference Server](https://docs.roboflow.com/deployment/self-hosted/inference-server) before running the client. Use self-hosting when processing must stay on your hardware or network. See [Video Configuration](https://docs.roboflow.com/deployment/self-hosted/inference-server/configuration/video-configuration) for worker limits and server-side media references.

The older [Serverless Video Streaming API](https://docs.roboflow.com/deployment/roboflow-cloud/serverless-api/serverless-video-streaming-api) is deprecated. Existing legacy reference remains available, but it is not the managed-live path described by Cloud Streaming. Migration is not an API URL substitution.

## Install the SDK

```bash
pip install "inference-sdk[webrtc]"
```

## Stream a Workflow

This example captures video from a webcam and prints the `predictions` output from a saved Workflow:

```python
from inference_sdk import InferenceHTTPClient, InferenceConfiguration
from inference_sdk.webrtc import StreamConfig, WebcamSource

client = InferenceHTTPClient(
    api_url="http://localhost:9001",
    api_key="ROBOFLOW_API_KEY",
).configure(InferenceConfiguration(api_key_transport="header"))

session = client.webrtc.stream(
    source=WebcamSource(),
    workflow="workflow-id",
    workspace="workspace-name",
    config=StreamConfig(data_output=["predictions"]),
)

@session.on_data("predictions")
def handle_predictions(predictions, metadata):
    print(f"Frame {metadata.frame_id}: {predictions}")

session.run()
```

Replace `workflow-id`, `workspace-name`, and `ROBOFLOW_API_KEY` with your values. Point `api_url` at your self-hosted server.

The names in `data_output` must match outputs defined by your Workflow. To receive an image output as video, add it to `stream_output` and register an `on_frame` handler. See the [WebRTC Streaming reference](https://docs.roboflow.com/reference/inference/inference-sdk/webrtc#stream-a-workflow) for a complete example.

## Choose a video source

Change the `source` passed to `client.webrtc.stream()` based on where the video comes from:

<table data-search="false"><thead><tr><th>Source</th><th>Use it when</th></tr></thead><tbody><tr><td><code>WebcamSource()</code></td><td>The camera is connected to the client machine.</td></tr><tr><td><code>RTSPSource("rtsp://...")</code></td><td>The Inference Server can reach the RTSP camera.</td></tr><tr><td><code>LocalStreamSource("rtsp://...")</code></td><td>Only the client can reach the RTSP or RTMP stream.</td></tr><tr><td><code>VideoFileSource("video.mp4")</code></td><td>You want to process a stored video file.</td></tr><tr><td><code>ManualSource()</code></td><td>Your application provides individual frames.</td></tr></tbody></table>

For `RTSPSource`, the Inference Server must be able to reach the camera URL. Use `LocalStreamSource` when only the client can reach it. For managed Cloud Streaming, connect the camera through the Video Connector instead of exposing its RTSP port to the public internet.

See [WebRTC video sources](https://docs.roboflow.com/reference/inference/inference-sdk/webrtc#video-sources) for source configuration and [consuming results](https://docs.roboflow.com/reference/inference/inference-sdk/webrtc#consuming-results) for callbacks, iterators, and session cleanup.

## Stream one model

You do not need to build a Workflow when you only need one model. Pass `model_id` instead of `workflow` and `workspace`:

```python
session = client.webrtc.stream(
    source=WebcamSource(),
    model_id="rfdetr-nano",
)
```

See [Stream a model](https://docs.roboflow.com/reference/inference/inference-sdk/webrtc#stream-a-model) for prediction handling by task type.

## Next steps

* Configure frame and data outputs in the [WebRTC Streaming reference](https://docs.roboflow.com/reference/inference/inference-sdk/webrtc).
* Start and configure a [self-hosted Inference Server](https://docs.roboflow.com/deployment/self-hosted/inference-server).
* Connect a managed live camera with [Cloud Streaming](https://docs.roboflow.com/deployment/roboflow-cloud/cloud-streaming).
