Open-source project
whitphx/streamlit-webrtc avatar
whitphx/streamlit-webrtc

streamlit-webrtc: real-time video and audio processing inside a Streamlit app

Real-time video and audio processing on Streamlit

1,707 stars217 forksPythonMIT

At a glance

What is it?
streamlit-webrtc puts a WebRTC session behind a single Streamlit call, so frame callbacks run in Python on the server while the browser handles capture and display. It fits prototypes and internal tools, not latency-critical production pipelines.
Who is it for?
Adopt streamlit-webrtc if you already have a Streamlit app and want camera or microphone input processed by Python without building a separate signalling service; the quick tutorial in the README is roughly ten lines. Do not adopt it if you need sub-frame latency, multi-party routing, or a media server, because the library streams between one browser and the Streamlit server process.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 19, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The gap streamlit-webrtc fills between Streamlit and the camera

Streamlit reruns the script top to bottom on every interaction, and its built-in media elements are one-shot: a file uploader or st.camera_input gives you a still, not a stream. Anything that needs a continuous feed, a per-frame transform, or a live audio loop does not fit that model. streamlit-webrtc adds a component that opens a real WebRTC session between the browser and the Streamlit server, then hands each frame to Python. The audience is people who already write Streamlit apps and want object detection, OpenCV filters, speech-to-text, or a small video chat without standing up separate signalling and media infrastructure. The README's example list is a fair summary of intent: object detection, an OpenCV filter, uni-directional streaming, audio processing, real-time speech-to-text, style transfer, and a video chat app described as about 100 lines of Python.

How webrtc_streamer moves frames from browser to callback

The public surface is one function, webrtc_streamer(), which renders the component and manages the session. The README states that unlike other Streamlit components it requires a key argument as a unique identifier. Media capture happens in the browser; the Python side receives frames as PyAV objects. You pass video_frame_callback for video and audio_frame_callback for audio, and each callback takes a frame and returns a frame. The README's example converts with frame.to_ndarray(format="bgr24"), edits the array, and returns av.VideoFrame.from_ndarray(flipped, format="bgr24"), which tells you the boundary clearly: numpy arrays inside, PyAV frames at the edges. Dependencies in pyproject.toml confirm the stack: aiortc for the WebRTC implementation, av for frame handling, aioice for ICE. The README also documents media_toggle_controls, which shows camera and microphone buttons beside Start/Stop; setting it to False hides them. Those buttons mute tracks rather than ending the session, so a disabled audio track sends silence and a disabled video track sends black frames, and no renegotiation happens.

Install streamlit-webrtc and run a first frame callback

The README gives a single install command. It pulls Streamlit, aiortc, av, aioice and packaging as dependencies, so expect a sizeable download on a clean environment.

bash
pip install -U streamlit-webrtc

A minimal app is three lines. The key must be a unique string; the README says to set an arbitrary one.

python
from streamlit_webrtc import webrtc_streamer

webrtc_streamer(key="sample")

Run it with Streamlit and open the printed local address, which the README gives as http://localhost:8501/. You should see the app view; clicking START begins streaming, and the browser asks for camera and microphone permission.

bash
streamlit run app.py

To process frames, define a callback and pass it as video_frame_callback. This example flips the image vertically, the same transform the README uses.

python
from streamlit_webrtc import webrtc_streamer
import av


def video_frame_callback(frame):
    img = frame.to_ndarray(format="bgr24")
    flipped = img[::-1, :, :]
    return av.VideoFrame.from_ndarray(flipped, format="bgr24")


webrtc_streamer(key="example", video_frame_callback=video_frame_callback)

The README also shows passing outer state into the callback, for instance a st.checkbox value read inside the function to toggle the flip. That works because the function closes over the variable. Reading values back out is the harder direction, and the README treats it as a separate topic with a warning about the forked thread.

The forked-thread callback and the state it will not share for you

The README is explicit that the callback executes in a forked thread running independently of the main script, and that pulling values from the callback into the outer scope needs workarounds. This is the design constraint most likely to bite. Streamlit's own execution model is a script rerun per interaction, and the media thread sits outside it, so anything you accumulate per frame has to be handed across deliberately. The README points at a limitations section for the details rather than promising a general solution. Treat the callback as a hot path: it runs per frame, on the server, while the WebRTC session is live. A heavy model inside it degrades the stream for every viewer of that session, and nothing in the library throttles frames for you. The README's own examples lean on lightweight operations (array slicing, OpenCV filters) with heavier work such as MediaPipe pose estimation shown in a separate demo repository.

One browser, one server process: where streamlit-webrtc stops

The architecture is browser to Streamlit server. There is no media server, no SFU, and no peer-to-peer mesh between users. The video chat example in the README is the honest boundary marker: it exists, it is short, and it is a demo of what the component can do rather than a conferencing platform. If you need many participants in one room, recording and replay, or stream routing independent of your Python process, this is the wrong layer. Server-side processing also means the Streamlit process carries the CPU cost of every active session, and Streamlit's deployment model is not built around long-lived per-user media threads. For a browser-side alternative the README names a sister project, streamlit-fesion, which runs video filters in the browser with Wasm; that moves the compute off the server but limits you to what can run in Wasm rather than arbitrary Python.

aiortc and PyAV are the alternatives, and they are a different job

The closest real alternative is using aiortc directly, the library streamlit-webrtc depends on. With aiortc you write the signalling exchange, the peer connection setup, and the media track plumbing yourself, typically inside an async web framework. The difference in approach is who owns the session lifecycle: aiortc gives you the primitives and no UI, while streamlit-webrtc owns the browser component, the signalling between that component and the Python process, and the callback dispatch, in exchange for keeping you inside Streamlit's execution model. If your app is already Streamlit, that trade is usually worth it. If you are building a standalone service with its own frontend, the component buys you little and the Streamlit runtime becomes overhead. The same reasoning applies to PyAV: it is the frame library here, not a competitor, and you will use its API either way.

Release cadence, licence, and what an upgrade costs

The repository is not archived and the last push was on 2026-09-14. Recent releases are v0.77.0 on 2026-08-07, v0.76.3 on 2026-08-04 and v0.76.2 on 2026-07-18, so the version line moves in small increments rather than large jumps. The project is still on 0.x, which is worth weighing before you pin it in a long-lived deployment. Dependencies are floored rather than capped in pyproject.toml, with comments explaining each floor: streamlit>=1.51.0 is described as the first Streamlit version requiring Python 3.10, aiortc>=1.14.0 is needed because earlier versions cap av below 15 and lack Python 3.14 wheels, and av>=15.1.0 is the first release with prebuilt cp314 wheels. Python 3.10 or newer is required. The licence is MIT, which is permissive and places few conditions on redistribution; the LICENSE file is the authoritative text and this is not legal advice. The Makefile shows the release path: bump-my-version with a tag, then git push and git push --tags, plus separate format targets for backend (ruff) and frontend (pnpm). Upgrading the Python package is a pip install away, but the component ships a prebuilt frontend bundle, so a version bump can change browser-side behaviour without any change in your own code.

Editorial conclusion

Adopt streamlit-webrtc if you already have a Streamlit app and want camera or microphone input processed by Python without building a separate signalling service; the quick tutorial in the README is roughly ten lines. Do not adopt it if you need sub-frame latency, multi-party routing, or a media server, because the library streams between one browser and the Streamlit server process. Verify first that your frame callback is fast enough to keep up, since the README warns that the callback runs in a forked thread and that reading values out of it needs care. Check the pinned floors in pyproject.toml (streamlit>=1.51.0, aiortc>=1.14.0, av>=15.1.0) against your environment before upgrading.

Frequently asked questions

What is Streamlit and what is it used for?

Streamlit is the web app framework streamlit-webrtc plugs into: the README runs the component with streamlit run app.py and serves it at http://localhost:8501/. streamlit-webrtc adds real-time video and audio streaming to apps built that way.

What is Streamlit and what can it do in Python?

In the context of this project, Streamlit renders the app and reruns the script on interaction, while streamlit-webrtc supplies the component that carries a live media session. The README shows Python callbacks receiving PyAV frames and returning edited frames.

Why do people use Streamlit?

The README's examples suggest the appeal is speed: a video chat app is described as about 100 lines of Python, and the quick tutorial reaches a working camera stream in three lines. streamlit-webrtc keeps that workflow while adding real-time input.

Is Streamlit safe and secure?

The README does not discuss security. What it does state is that the browser asks for camera and microphone permissions, and that media_toggle_controls can hide the camera and microphone toggle buttons.

What is streamlit-webrtc?

It is a Streamlit component for handling and transmitting real-time video and audio streams over the network, described in the README as real-time video and audio processing on Streamlit. It opens a WebRTC session and passes frames to Python callbacks as PyAV objects.

Official sources

  1. License: MIT
  2. Project website
  3. README
  4. Releases
  5. whitphx/streamlit-webrtc on GitHub
Community notes

Community notes