µStreamer
Released under GPL-3.0, µStreamer provides lightweight and very quick server to stream MJPEG video from any V4L2 device to the net on self-hosted...
Open-source V4L2 video streaming, honestly reviewed. No marketing fluff, just what you get when you run it on actual hardware.
TL;DR
- What it is: A lightweight, multithreaded MJPEG-HTTP server that streams video from any V4L2 device — webcams, HDMI capture cards, VGA adapters — over a plain HTTP endpoint [README].
- Who it’s for: Raspberry Pi tinkerers, 3D printer operators (Klipper/Mainsail setups), PiKVM users, and anyone who needs a no-nonsense webcam-to-browser stream without spinning up a full media server [3][README].
- Cost: $0. GPL-3.0. No SaaS tier, no cloud option, no license fee. Run it on whatever hardware you already have [README][4].
- Key strength: Genuinely fast multithreaded JPEG encoding with hardware acceleration on Raspberry Pi — the main reason to pick it over the older mjpg-streamer [README][3].
- Key weakness: MJPEG only. No H.264, no WebRTC, no adaptive bitrate. At high resolutions and framerates it burns significant bandwidth because it’s sending a continuous stream of full JPEG frames [3]. No webcam control (focus, servos, brightness) via HTTP — that’s mjpg-streamer’s turf [README].
What is µStreamer
µStreamer is a single-purpose C server. You point it at a /dev/videoN device, give it a host and port, and it serves a continuous MJPEG stream that any browser or media player (VLC, mplayer) can consume natively without plugins [5][README].
The project was written by Maxim Devaev as part of the PiKVM ecosystem — hardware-over-IP devices that stream VGA or HDMI output from servers and desktops to a browser. PiKVM needed to squeeze the highest resolution and FPS possible out of V4L2 capture hardware on a Raspberry Pi, and mjpg-streamer — the incumbent — had problems: single-threaded encoding, no hardware acceleration, broken behavior when the capture device disconnected mid-stream, and fragile DV-timings handling for dynamic resolution changes [README].
So Devaev wrote µStreamer from scratch rather than patching legacy code. It sits at 1,958 GitHub stars as of this writing — a niche number that accurately reflects its audience [merged profile]. This is not a tool for streaming your movie library to the living room. It is a tool for getting a webcam’s output onto a local network endpoint with minimum overhead.
The closest analog is mjpg-streamer, which has been the default V4L2 MJPEG server for years. µStreamer beats it on almost every technical dimension but one: mjpg-streamer exposes webcam controls (focus, servos, brightness) over HTTP, and µStreamer does not [README]. If you need to remotely adjust camera settings, mjpg-streamer wins on that single point.
Why people choose it
The use case split is pretty clear from the documentation and ecosystem coverage.
PiKVM. µStreamer is the native streaming engine for PiKVM, a popular open-source KVM-over-IP project. If you’re running PiKVM to remotely manage a server or home lab machine, µStreamer is already running under the hood — you didn’t choose it, it came with the hardware [README].
3D printing (Klipper + Mainsail/Crowsnest). This is the second major ecosystem. Crowsnest, the camera management layer for Klipper-based 3D printers, supports three backends — µStreamer, camera-streamer, and spyglass — and recommends µStreamer as the default for USB cameras and as the fallback for Raspberry Pi 5 devices where hardware encoding isn’t available [3]. The Crowsnest docs describe it as “the default and most widely supported mode” [3]. If you’re running Mainsail or Fluidd with a webcam pointed at your print bed, you’re likely looking at µStreamer output.
The specific reason people pick it over mjpg-streamer comes down to three things per the README comparison table [README]:
- Multithreaded JPEG encoding — mjpg-streamer is single-threaded, which shows at higher resolutions
- Hardware encoding on Raspberry Pi using the V4L2 M2M interface (GPU-accelerated encoding without ffmpeg)
- Graceful device disconnection — mjpg-streamer stops streaming entirely if the device unplugs; µStreamer shows a black “NO LIVE VIDEO” screen and resumes when the device reconnects
The specific reason people pick camera-streamer over µStreamer is WebRTC. On Raspberry Pi 4 hardware with compatible capture cards, camera-streamer can output H.264 via WebRTC, which is dramatically lower bandwidth than MJPEG [3]. The Crowsnest docs are explicit: if you have a Pi 4 with a USB camera, camera-streamer with WebRTC will use less bandwidth at the same quality and framerate. µStreamer’s MJPEG is universally compatible but not efficient [3].
The MJPEG bandwidth problem is real and worth understanding before you deploy. MJPEG transmits every frame as a complete JPEG — there’s no inter-frame compression, no delta encoding. A 1080p stream at 30fps is a lot of data. µStreamer has a --drop-same-frames=N option that skips frames when the image hasn’t changed (useful for HDMI capture of a static desktop), which can cut traffic significantly for that specific use case, but doesn’t help for live motion [README][5].
Features
Based on the README and man page [README][5]:
Core capture:
- V4L2 device support — any webcam, capture card, or virtual device the kernel sees [5]
- Input formats: YUYV, YVYU, UYVY, YUV420, YVU420, RGB565, RGB24, GREY, MJPEG, JPEG [5]
- Configurable resolution, FPS, buffer count, and worker thread count [5]
- DV-timings support for automatic resolution changes when the source signal changes (useful for HDMI capture) [README]
- Persistent mode: suppresses repetitive device errors rather than crashing [README][5]
Encoding:
- Software JPEG encoding (default, CPU-based) [5]
- Hardware encoding via V4L2 M2M interface — GPU-accelerated on Raspberry Pi [README][5]
- Direct passthrough of pre-encoded MJPEG from camera hardware [5]
- Configurable JPEG quality 1–100 [5]
- Drop-same-frames option to skip identical consecutive frames and save bandwidth [README]
Transport:
- HTTP server with MJPEG stream endpoint [README]
- UNIX domain socket support [README]
- Systemd socket activation [README]
- REST API and snapshot endpoint [merged profile]
- Built-in static file serving [README]
Integration:
- GPIO signaling via libgpiod (signal stream state on GPIO pins) [README]
- mjpg-streamer API compatibility [README]
- Optional Janus WebRTC gateway integration (
WITH_JANUS=1build flag) — not WebRTC out of the box, requires a separate Janus server [README] - Performance statistics log and debug logging without recompiling [README]
What it does not do:
- H.264, H.265, VP8, VP9, AV1 — MJPEG only natively [3]
- WebRTC without the Janus sidecar [README]
- Webcam control (focus, brightness, servo) via HTTP [README]
- HLS, DASH, or any adaptive streaming
- Audio
Pricing: SaaS vs self-hosted math
There is no SaaS tier, no managed cloud, no commercial license. µStreamer is GPL-3.0, which means the source is free and self-hosting is the only option [README][4].
Cost to run:
- On a Raspberry Pi you already own: effectively $0 in additional hardware costs
- On a dedicated VPS: you wouldn’t typically run µStreamer on a cloud VPS — it requires physical V4L2 devices, and most VPSes don’t have USB passthrough or capture hardware. This is a physical hardware tool.
- Raspberry Pi 4 (2GB): ~$35–45 one-time, handles µStreamer without breaking a sweat
- Raspberry Pi Zero 2 W: ~$15, usable for lower-resolution streams
Versus commercial alternatives: If you need managed webcam streaming with a SaaS interface, the market is fragmented. Services like Ivideon or Camio charge $3–10/camera/month. For a single-camera home lab or printer setup, that’s $36–120/year for functionality µStreamer provides for free on hardware you already own.
The more relevant comparison is time cost. µStreamer saves you zero dollars if you can’t get it running. It saves you real money if the alternative is a monthly SaaS subscription for camera monitoring.
Deployment reality check
Available in package repositories for most Linux distros — Arch (AUR), Fedora, Ubuntu (jammy), Debian, Alpine, OpenWRT, and FreeBSD [README]. On Raspberry Pi OS, it’s sudo apt install ustreamer plus a handful of dev libraries if you’re building from source.
From apt (simplest path):
sudo apt install ustreamer
ustreamer --device=/dev/video0 --host=0.0.0.0 --port=8080
That’s it. Point your browser at http://<device-ip>:8080/stream and you have MJPEG [5].
Hardware encoding (Raspberry Pi): Requires libevent, libjpeg-turbo, and libbsd. For GPIO support, add libgpiod. For systemd integration, libsystemd. For Janus/WebRTC, add libasound2-dev, libspeex-dev, libspeexdsp-dev, libopus-dev — this last set is a meaningful extra step [README].
The recommended command for TC358743 HDMI capture on a Pi:
ustreamer \
--format=uyvy \
--encoder=m2m-image \
--workers=3 \
--persistent \
--dv-timings \
--drop-same-frames=30
This is from the README and gives you hardware-encoded output with graceful HDMI disconnect handling [README][5].
What can go wrong:
- Cross-domain requests are disabled by default since v2.0 — if you’re embedding the stream in a web app on a different origin, add
--allow-origin=*[5]. Easy to miss, annoying to debug. - MJPEG bandwidth at 1080p/30fps on a slow network will overwhelm the connection. Drop-same-frames helps for static content; for live motion you’re sending full frames every tick.
- The Janus WebRTC path is not documented as extensively as the base MJPEG setup. If you need WebRTC without a Janus server, camera-streamer is a more direct path on supported Pi hardware [3].
- Alpine Linux requires building with
WITH_PTHREAD_NP=0— the flag isn’t obvious [README]. - Docker support is listed as a canonical feature [merged profile] but the README focuses on source builds. Docker images exist in the community but aren’t first-party.
For a technical user on Raspberry Pi OS: 5–15 minutes to a working stream via apt. From source with hardware encoding flags: 30–60 minutes including dependency install. For a non-technical user, realistically this isn’t the tool — there’s no web UI for configuration and the setup is terminal-only.
Pros and Cons
Pros
- Low overhead. Genuinely lightweight — fits on a Raspberry Pi Zero without significant resource pressure for low-to-medium resolution streams [README][3].
- Multithreaded encoding. mjpg-streamer can’t do this. At high resolutions with multiple worker threads, µStreamer maintains better FPS under load [README].
- Hardware acceleration on Raspberry Pi. V4L2 M2M interface offloads JPEG encoding to the GPU. Measurably lower CPU usage for HDMI capture workflows [README][5].
- Graceful disconnect handling. Shows a “NO LIVE VIDEO” placeholder instead of dying when the device unplugs [README]. Matters a lot in 3D printing where you might unplug and replug a camera.
- DV-timings support. Automatic resolution changes when the HDMI source switches modes — essential for KVM use [README].
- Package manager installs. Available in Arch AUR, Fedora, Ubuntu, Debian, Alpine, FreeBSD, OpenWRT [README]. No source build required for basic use.
- Broad ecosystem adoption. Default backend in Crowsnest (the standard camera manager for Klipper 3D printing) [3]. Well-tested in production in that ecosystem.
- mjpg-streamer API compatible. If you have existing tooling or documentation written for mjpg-streamer, µStreamer speaks the same API [README].
- UNIX socket + systemd socket activation. Integrates cleanly into systemd service configurations [README].
Cons
- MJPEG only. No H.264, no WebRTC without the Janus sidecar. High bandwidth cost at high resolutions [3]. On a bandwidth-constrained connection, this is a real problem.
- No webcam control via HTTP. Can’t adjust focus, brightness, or servo position through the streaming interface — mjpg-streamer beats it here [README].
- No audio. Purely video. If you need audio alongside video, you’re compositing a separate stream.
- Terminal-only setup. No web UI, no GUI configuration. Every setting is a command-line flag [5]. Not approachable for non-technical users.
- WebRTC requires Janus. Getting H.264/WebRTC output requires running a separate Janus WebRTC gateway — a non-trivial operational dependency [README].
- Niche use case. This is a V4L2-to-MJPEG pipe. If you’re trying to stream a media library, transcode video, or do anything beyond “webcam to browser endpoint,” this is the wrong tool.
- 1,958 GitHub stars. Not a red flag by itself — the tool is specialized — but it means a smaller community than alternatives for non-PiKVM use cases. Questions outside the PiKVM Discord may go unanswered [README].
- GPL-3.0, not MIT or Apache. If you’re embedding this in a commercial product, the copyleft terms matter. mjpg-streamer and some alternatives use less restrictive licenses.
Who should use this / who shouldn’t
Use µStreamer if:
- You’re running a Klipper 3D printer with Mainsail or Fluidd — Crowsnest will likely handle the setup for you, with µStreamer as the default backend [3].
- You’re running PiKVM or a similar KVM-over-IP setup — it’s already there [README].
- You need a simple webcam HTTP endpoint on a Raspberry Pi or other Linux SBC and don’t need audio, H.264, or camera controls.
- You’re replacing a broken mjpg-streamer setup and want better performance on the same hardware.
- You’re on a Raspberry Pi 5, where camera-streamer’s hardware encoder isn’t available — the Crowsnest docs explicitly recommend µStreamer for Pi 5 USB cameras [3].
Skip it (use camera-streamer instead) if:
- You have a Raspberry Pi 4 (not 5) and want H.264 WebRTC output — lower bandwidth at the same quality [3].
- You need remote webcam control (focus, zoom, brightness) via HTTP.
Skip it (use MediaMTX instead) if:
- You need a full media router: RTSP, RTMP, HLS, SRT, WebRTC all at once [4]. MediaMTX handles any-to-any protocol conversion with 18,485 stars and MIT license [4].
Skip it entirely if:
- You’re not dealing with V4L2 devices. If the camera isn’t showing up as
/dev/videoNon Linux, µStreamer can’t see it. - You need a non-technical user to configure and maintain it. The CLI-only setup is a hard stop.
- Audio is required alongside video.
- You’re on macOS or Windows — V4L2 is Linux-only.
Alternatives worth considering
- mjpg-streamer — the predecessor. Still relevant if you need HTTP webcam controls (brightness, focus, servos). Weaker on performance and reliability. Single-threaded, no hardware encoding, less graceful on device disconnect [README].
- camera-streamer (ayufan) — supports WebRTC + H.264 hardware encoding on Raspberry Pi 4 via the GPU. Significantly lower bandwidth than MJPEG. Recommended by Crowsnest for Pi 4 USB cameras [3]. Doesn’t support Pi 5 hardware encoding.
- MediaMTX — MIT-licensed, Go-based, handles RTSP/RTMP/HLS/SRT/WebRTC/MJPEG. Zero-dependency binary. 18,485 stars [4]. More complex but covers all protocols. If you’re unsure what transport you need, MediaMTX is the safer bet.
- spyglass (mainsail-crew) — purpose-built for Raspberry Pi cameras (not USB webcams) in the Klipper ecosystem. Hardware-accelerated MJPEG and H.264. Maintained by the Mainsail team. Only works on Pi SBCs with Pi cameras [3].
- Jellyfin — wrong category, but if someone suggested µStreamer for media library streaming, Jellyfin is what they actually want [4].
- go2rtc — increasingly popular WebRTC/RTSP/MJPEG bridge. Worth evaluating for home automation camera feeds.
For 3D printer setups specifically: start with what Crowsnest recommends for your hardware (the flowchart in their docs is useful) [3]. For general V4L2-to-browser streaming: µStreamer vs MediaMTX depending on whether you need MJPEG-only simplicity or multi-protocol flexibility.
Bottom line
µStreamer is the right tool for a narrow job, and it does that job well. If you have a V4L2 device on Linux — a USB webcam, an HDMI capture card, a VGA adapter — and you want a fast, low-overhead MJPEG HTTP stream that any browser can consume, µStreamer is the most technically sound option in that category. The multithreaded encoding and hardware acceleration on Raspberry Pi are real advantages over mjpg-streamer, and the graceful disconnect handling matters in practice for 3D printer and KVM use cases. What it isn’t: a general media server, a WebRTC solution without extra infrastructure, or anything a non-technical user can configure unaided. The bandwidth cost of MJPEG at high resolutions is a genuine constraint — if your use case has tight bandwidth limits and you have Pi 4 hardware, camera-streamer with WebRTC is worth evaluating first. But for Pi 5, Klipper, PiKVM, or any setup where simplicity and compatibility matter more than bandwidth efficiency, µStreamer earns its place as the default.
If the setup is the blocker, that’s exactly what unsubbed.co’s parent studio upready.dev deploys for clients. One-time fee, done, you own the infrastructure.
Sources
- Ethan Sholly, Self-Host Weekly (19 December 2025) — “Self-Host Weekly (19 December 2025)”. selfh.st. https://selfh.st/weekly/2025-12-19/
- NixOS Manual — “Appendix B. Release Notes”. nixos.org. https://nixos.org/manual/nixos/stable/release-notes
- Mainsail/Crowsnest Documentation — “Streaming Backends for Webcam Services - Crowsnest”. docs.mainsail.xyz. https://docs.mainsail.xyz/crowsnest/faq/backends/
- awesome-selfhosted — “Media Streaming - Multimedia Streaming”. awesome-selfhosted.net. https://awesome-selfhosted.net/tags/media-streaming---multimedia-streaming.html
- ManKier — “ustreamer(1) man page”. mankier.com. https://www.mankier.com/1/ustreamer
Primary sources:
- GitHub repository and README: https://github.com/pikvm/ustreamer (1,958 stars, GPL-3.0)
- PiKVM project: https://github.com/pikvm/pikvm
Features
Integrations & APIs
- REST API
Category
Related Media & Streaming Tools
View all 334 →Immich
95KHigh-performance self-hosted photo and video management — automatic backup, ML-powered search, and a Google Photos-like experience on your own server.
Jellyfin
49KThe volunteer-built media solution that puts you in control of your media. Stream movies, shows, music, and photos to any device from your own server.
PhotoPrism
39KAI-Powered Photos App for the Decentralized Web. Tag and find pictures automatically without getting in your way.
Cobalt
39KSave what you love without ads, tracking, paywalls or other nonsense. Just paste the link and you're ready to rock.
qBittorrent
36KAn open-source software alternative to uTorrent. Feature-rich and runs on all major platforms.
SRS
29KSimple, high efficiency, realtime video server. Supports RTMP, WebRTC, HLS, HTTP-FLV, SRT, MPEG-DASH and GB28181.