{"id":13508241,"url":"https://github.com/pikvm/ustreamer","last_synced_at":"2025-05-14T08:05:33.924Z","repository":{"id":37775920,"uuid":"148779989","full_name":"pikvm/ustreamer","owner":"pikvm","description":"µStreamer - Lightweight and fast MJPEG-HTTP streamer","archived":false,"fork":false,"pushed_at":"2025-03-27T02:38:33.000Z","size":5857,"stargazers_count":1813,"open_issues_count":14,"forks_count":253,"subscribers_count":46,"default_branch":"master","last_synced_at":"2025-04-11T02:51:48.032Z","etag":null,"topics":["broadcast","fps","hdmi","http","ipmi","jpeg","kvm","mjpeg","mjpeg-stream","mjpg","mjpg-stream","mjpg-streamer","omx","openmax","openmax-il","raspberry-pi","raspberrypi","stream","streaming","video-formats"],"latest_commit_sha":null,"homepage":"https://pikvm.org","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pikvm.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"patreon":"pikvm","custom":"https://paypal.me/pikvm"}},"created_at":"2018-09-14T11:33:51.000Z","updated_at":"2025-04-10T07:50:51.000Z","dependencies_parsed_at":"2023-10-12T10:17:30.332Z","dependency_job_id":"fbef21fe-1837-45d1-bf20-497d7cbdf40a","html_url":"https://github.com/pikvm/ustreamer","commit_stats":{"total_commits":1359,"total_committers":35,"mean_commits":38.82857142857143,"dds":"0.054451802796173676","last_synced_commit":"1f96925181de5467b49171ee97c07144ec7e1a60"},"previous_names":[],"tags_count":250,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikvm%2Fustreamer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikvm%2Fustreamer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikvm%2Fustreamer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pikvm%2Fustreamer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pikvm","download_url":"https://codeload.github.com/pikvm/ustreamer/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254101588,"owners_count":22014907,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["broadcast","fps","hdmi","http","ipmi","jpeg","kvm","mjpeg","mjpeg-stream","mjpg","mjpg-stream","mjpg-streamer","omx","openmax","openmax-il","raspberry-pi","raspberrypi","stream","streaming","video-formats"],"created_at":"2024-08-01T02:00:50.228Z","updated_at":"2025-05-14T08:05:28.914Z","avatar_url":"https://github.com/pikvm.png","language":"C","readme":"# µStreamer\n[![CI](https://github.com/pikvm/ustreamer/workflows/CI/badge.svg)](https://github.com/pikvm/ustreamer/actions?query=workflow%3ACI)\n[![Discord](https://img.shields.io/discord/580094191938437144?logo=discord)](https://discord.gg/bpmXfz5)\n\nµStreamer is a lightweight and very quick server to stream [MJPEG](https://en.wikipedia.org/wiki/Motion_JPEG) video from any V4L2 device to the net. All new browsers have native support of this video format, as well as most video players such as mplayer, VLC etc.\nµStreamer is a part of the [PiKVM](https://github.com/pikvm/pikvm) project designed to stream [VGA](https://www.amazon.com/dp/B0126O0RDC) and [HDMI](https://auvidea.com/b101-hdmi-to-csi-2-bridge-15-pin-fpc/) screencast hardware data with the highest resolution and FPS possible.\n\nµStreamer is very similar to [mjpg-streamer](https://github.com/jacksonliam/mjpg-streamer) with ```input_uvc.so``` and ```output_http.so``` plugins, however, there are some major differences. The key ones are:\n\n| **Feature** | **µStreamer** | **mjpg-streamer** |\n|----------|---------------|-------------------|\n| Multithreaded JPEG encoding | ✔ | ✘ |\n| Hardware image encoding\u003cbr\u003eon Raspberry Pi | ✔ | ✘ |\n| Behavior when the device\u003cbr\u003eis disconnected while streaming | ✔ Shows a black screen\u003cbr\u003ewith ```NO SIGNAL``` on it\u003cbr\u003euntil reconnected | ✘ Stops the streaming \u003csup\u003e1\u003c/sup\u003e |\n| [DV-timings](https://linuxtv.org/downloads/v4l-dvb-apis-new/userspace-api/v4l/dv-timings.html) support -\u003cbr\u003ethe ability to change resolution\u003cbr\u003eon the fly by source signal | ✔ | ☹ Partially yes \u003csup\u003e1\u003c/sup\u003e |\n| Option to skip frames when streaming\u003cbr\u003estatic images by HTTP to save the traffic | ✔ \u003csup\u003e2\u003c/sup\u003e | ✘ |\n| Streaming via UNIX domain socket | ✔ | ✘ |\n| Systemd socket activation | ✔ | ✘ |\n| Debug logs without recompiling,\u003cbr\u003eperformance statistics log,\u003cbr\u003eaccess to HTTP streaming parameters | ✔ | ✘ |\n| Option to serve files\u003cbr\u003ewith a built-in HTTP server | ✔ | ☹ Regular files only |\n| Signaling about the stream state\u003cbr\u003eon GPIO using [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) | ✔ | ✘ |\n| Access to webcam controls (focus, servos)\u003cbr\u003eand settings such as brightness via HTTP | ✘ | ✔ |\n| Compatibility with mjpg-streamer's API | ✔ | :) |\n\nFootnotes:\n  * ```1``` Long before µStreamer, I made a [patch](https://github.com/jacksonliam/mjpg-streamer/pull/164) to add DV-timings support to mjpg-streamer and to keep it from hanging up on device disconnection. Alas, the patch is far from perfect and I can't guarantee it will work every time - mjpg-streamer's source code is very complicated and its structure is hard to understand. With this in mind, along with needing multithreading and JPEG hardware acceleration in the future, I decided to make my own stream server from scratch instead of supporting legacy code.\n\n  * ```2``` This feature allows to cut down outgoing traffic several-fold when streaming HDMI, but it increases CPU usage a little bit. The idea is that HDMI is a fully digital interface and each captured frame can be identical to the previous one byte-wise. There's no need to stream the same image over the net several times a second. With the `--drop-same-frames=20` option enabled, µStreamer will drop all the matching frames (with a limit of 20 in a row). Each new frame is matched with the previous one first by length, then using ```memcmp()```.\n\n-----\n# TL;DR\nIf you're going to live-stream from your backyard webcam and need to control it, use mjpg-streamer. If you need a high-quality image with high FPS - µStreamer for the win.\n\n-----\n# Installation\n\n## Building\nYou need to download the µStreamer onto your system and build it from the sources.\n\n* AUR has a package for Arch Linux: https://aur.archlinux.org/packages/ustreamer.\n* Fedora: https://src.fedoraproject.org/rpms/ustreamer.\n* Ubuntu: https://packages.ubuntu.com/jammy/ustreamer.\n* Debian: https://packages.debian.org/sid/ustreamer\n* FreeBSD port: https://www.freshports.org/multimedia/ustreamer.\n\n### Preconditions\nYou'll need  ```make```, ```gcc```, ```pkg-config```, ```libevent``` with ```pthreads``` support, ```libjpeg9```/```libjpeg-turbo``` and ```libbsd``` (only for Linux).\n\n* Arch: `sudo pacman -S libevent libjpeg-turbo libutil-linux libbsd`.\n* Raspberry OS Bullseye: `sudo apt install libevent-dev libjpeg62-turbo libbsd-dev`. Add `libgpiod-dev` for `WITH_GPIO=1` and `libsystemd-dev` for `WITH_SYSTEMD=1` and `libasound2-dev libspeex-dev libspeexdsp-dev libopus-dev` for `WITH_JANUS=1`.\n* Raspberry OS Bookworm: same as previous but replace `libjpeg62-turbo` to `libjpeg62-turbo-dev`.\n* Debian/Ubuntu: `sudo apt install build-essential libevent-dev libjpeg-dev libbsd-dev`.\n* Alpine: `sudo apk add libevent-dev libbsd-dev libjpeg-turbo-dev musl-dev`. Build with `WITH_PTHREAD_NP=0`.\n\nTo enable GPIO support install [libgpiod](https://git.kernel.org/pub/scm/libs/libgpiod/libgpiod.git/about) and pass option ```WITH_GPIO=1```. If the compiler reports about a missing function ```pthread_get_name_np()``` (or similar), add option ```WITH_PTHREAD_NP=0``` (it's enabled by default). For the similar error with ```setproctitle()``` add option ```WITH_SETPROCTITLE=0```.\n\n### Make\nThe most convenient process is to clone the µStreamer Git repository onto your system. If you don't have Git installed and don't want to install it either, you can download and unzip the sources from GitHub using `wget https://github.com/pikvm/ustreamer/archive/refs/heads/master.zip`.\n\n```\n$ git clone --depth=1 https://github.com/pikvm/ustreamer\n$ cd ustreamer\n$ make\n$ ./ustreamer --help\n```\n\n## Update\nAssuming you have a µStreamer clone as discussed above you can update µStreamer as follows.\n\n```\n$ cd ustreamer\n$ git pull\n$ make clean\n$ make\n```\n\n-----\n# Usage\n**For M2M hardware encoding on Raspberry Pi, you need at least 5.15.32 kernel. OpenMAX and MMAL support on older kernels is deprecated and removed.**\n\nWithout arguments, ```ustreamer``` will try to open ```/dev/video0``` with 640x480 resolution and start streaming on  ```http://127.0.0.1:8080```. You can override this behavior using parameters ```--device```, ```--host``` and ```--port```. For example, to stream to the world, run:\n```\n# ./ustreamer --device=/dev/video1 --host=0.0.0.0 --port=80\n```\n\n:exclamation: Please note that since µStreamer v2.0 cross-domain requests were disabled by default for [security reasons](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS). To enable the old behavior, use the option `--allow-origin=\\*`.\n\nThe recommended way of running µStreamer with [TC358743-based capture device](https://www.raspberrypi.org/forums/viewtopic.php?f=38\u0026t=120702\u0026start=400#p1339178) on Raspberry Pi:\n```\n$ ./ustreamer \\\n    --format=uyvy \\ # Device input format\n    --encoder=m2m-image \\ # Hardware encoding on V4L2 M2M driver\n    --workers=3 \\ # Workers number\n    --persistent \\ # Suppress repetitive signal source errors (for example when HDMI cable was disconnected)\n    --dv-timings \\ # Use DV-timings\n    --drop-same-frames=30 # Save the traffic\n```\n\n:exclamation: Please note that to use `--drop-same-frames` for different browsers you need to use some specific URL `/stream` parameters (see URL `/` for details).\n\nYou can always view the full list of options with ```ustreamer --help```.\n\n-----\n# Docker (Raspberry Pi 4 HDMI)\n\n## Preparations\nAdd following lines to /boot/firmware/usercfg.txt:\n\n```\ngpu_mem=128\ndtoverlay=tc358743\n```\n\nCheck size of CMA:\n\n```\n$ dmesg | grep cma-reserved\n[    0.000000] Memory: 7700524K/8244224K available (11772K kernel code, 1278K rwdata, 4320K rodata, 4096K init, 1077K bss, 281556K reserved, 262144K cma-reserved)\n```\n\nIf it is smaller than 128M add following to /boot/firmware/cmdline.txt:\n\n```\ncma=128M\n```\n\nSave changes and reboot.\n\n## Launch\nStart container:\n\n```\n$ docker run --device /dev/video0:/dev/video0 -e EDID=1 -p 8080:8080 pikvm/ustreamer:latest\n```\n\nThen access the web interface at port 8080 (e.g. http://raspberrypi.local:8080).\n\n## Custom config\n```\n$ docker run --rm pikvm/ustreamer:latest \\\n    --format=uyvy \\\n    --workers=3 \\\n    --persistent \\\n    --dv-timings \\\n    --drop-same-frames=30\n```\n\n## EDID\nAdd `-e EDID=1` to set HDMI EDID before starting ustreamer. Use together with `-e EDID_HEX=xx` to specify custom EDID data.\n\n-----\n# Raspberry Pi Camera Example\n\nExample usage for the Raspberry Pi v3 camera (required `libcamerify` which is located in `libcamera-tools` and `libcamera-v4l2` (install both) on Raspbian):\n```\n$ sudo modprobe bcm2835-v4l2\n$ libcamerify ./ustreamer --host :: --encoder=m2m-image\n```\n\nFor v2 camera you can use the same trick with `libcamerify` but enable legacy camera mode in `raspi-config`.\n\nExample usage for the Raspberry Pi v1 camera:\n```\n$ sudo modprobe bcm2835-v4l2\n$ ./ustreamer --host :: -m jpeg --device-timeout=5 --buffers=3 -r 2592x1944\n```\n\n:exclamation: Please note that newer camera models have a different maximum resolution. You can see the supported resolutions at the [PiCamera documentation](https://picamera.readthedocs.io/en/release-1.13/fov.html#sensor-modes).\n\n:exclamation: If you get a poor framerate, it could be that the camera is switched to photo mode, which produces a low framerate (but a higher quality picture). This is because `bcm2835-v4l2` switches to photo mode at resolutions higher than `1280x720`. To work around this, pass the `max_video_width` and `max_video_height` module parameters like so:\n\n```\n$ modprobe bcm2835-v4l2 max_video_width=2592 max_video_height=1944\n```\n\n-----\n# Integrations\n\n## Janus\nµStreamer supports bandwidth-efficient streaming using [H.264 compression](https://en.wikipedia.org/wiki/Advanced_Video_Coding) and the Janus WebRTC server. See the [Janus integration guide](docs/h264.md) for full details.\n\n## Nginx\nWhen uStreamer is behind an Nginx proxy, its buffering behavior introduces latency into the video stream. It's possible to disable Nginx's buffering to eliminate the additional latency:\n\n```nginx\nlocation /stream {\n    postpone_output 0;\n    proxy_buffering off;\n    proxy_ignore_headers X-Accel-Buffering;\n    proxy_pass http://ustreamer;\n}\n```\n\n-----\n# Tips \u0026 tricks for v4l2\nv4l2 utilities provide the tools to manage USB webcam setting and information. Scripts can be use to make adjustments and run manually or with cron. Running in cron for example to change the exposure settings at certain times of day. The package is available in all Linux distributions and is usually called `v4l-utils`.\n\n* List of available video devices: `v4l2-ctl --list-devices`.\n* List available control settings: `v4l2-ctl -d /dev/video0 --list-ctrls`.\n* List available video formats: `v4l2-ctl -d /dev/video0 --list-formats-ext`.\n* Read the current setting: `v4l2-ctl -d /dev/video0 --get-ctrl=exposure_auto`.\n* Change the setting value: `v4l2-ctl -d /dev/video0 --set-ctrl=exposure_auto=1`.\n\n[Here](https://www.kurokesu.com/main/2016/01/16/manual-usb-camera-settings-in-linux/) you can find more examples. Documentation is available in [`man v4l2-ctl`](https://www.mankier.com/1/v4l2-ctl).\n\n-----\n# See also\n* [Running uStreamer via systemd service](https://github.com/pikvm/ustreamer/issues/16).\n\n-----\n# License\nCopyright (C) 2018-2024 by Maxim Devaev mdevaev@gmail.com\n\nThis program is free software: you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nthe Free Software Foundation, either version 3 of the License, or\n(at your option) any later version.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with this program.  If not, see https://www.gnu.org/licenses/.\n","funding_links":["https://patreon.com/pikvm","https://paypal.me/pikvm"],"categories":["C","Software","streaming"],"sub_categories":["Media Streaming - Multimedia Streaming"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikvm%2Fustreamer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpikvm%2Fustreamer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpikvm%2Fustreamer/lists"}