- C 64.9%
- CMake 29.2%
- Shell 5.9%
The GPLv2 LICENSE file already ships; make the license explicit per file. or-later matches the existing notice in plugin-support.h and OBS itself; GPL is required by linking libobs. |
||
|---|---|---|
| build-aux | ||
| cmake | ||
| data/locale | ||
| src | ||
| vendor | ||
| .clang-format | ||
| .gersemirc | ||
| .gitignore | ||
| build-plugin.sh | ||
| build.sh | ||
| buildspec.json | ||
| CMakeLists.txt | ||
| CMakePresets.json | ||
| LICENSE | ||
| publish.sh | ||
| README.md | ||
OBS SLM Source
An OBS Studio plugin that receives live video and audio from a SLAY Media (SLM) sender and injects them into OBS as low-latency input sources.
What it does
The plugin registers two OBS source types:
- SLM Source (
slay_media_source) — receives video and audio - SLM Audio Source (
slay_media_audio_source) — audio only
Senders are discovered automatically via multicast (239.255.77.43:9878). Once a sender is found, the plugin connects and begins receiving frames. If the sender is on the same machine, it uses a shared memory ring buffer for zero-copy, sub-millisecond delivery. UDP is used otherwise.
Known senders
| Sender | Transport | Video codec |
|---|---|---|
| slay-cart — SLAY Media player | SHM (local) / UDP | Raw NV12, H.264, H.265 |
| slay-camera — Android camera app | UDP | H.265 (H.264 fallback) |
Protocol
SLM is a custom binary UDP protocol (magic SLM\x01, version 3). The handshake sequence:
- Sender broadcasts
ANNOUNCEon multicast - Plugin replies with
HELLO(unicast to sender'sctrl_port) - Sender sends
CAPS(resolution, FPS, pixel format, codec, audio params) - Sender streams video chunks and audio frames
Video frames are split into 1400-byte UDP chunks and reassembled. Audio fits in a single datagram. Optional LZ4 compression is supported for raw NV12 video.
Supported video codecs:
| Codec | Notes |
|---|---|
| Raw NV12 | Original SLM mode; optional LZ4 per-frame compression |
| H.264 (Annex B) | Software decoded via libavcodec |
| H.265 / HEVC (Annex B) | Software decoded via libavcodec |
H.264/H.265 frames arrive as complete Annex B access units, one per logical video frame (reassembled from chunks). The decoder is initialised on CAPS and replaced if the codec changes mid-stream. IDR frames carry inline SPS/PPS so the decoder can recover after packet loss.
Supported audio format: float32 PCM, mono or stereo, 48 kHz
Transport
| Transport | Platforms | Notes |
|---|---|---|
| Shared Memory | Linux, Windows | Zero-copy; used when sender and receiver are on the same machine |
| UDP | All | Used for remote senders; always the fallback if SHM becomes stale |
The plugin tries SHM first and monitors the sender's heartbeat. If the heartbeat goes stale (no update for 5 seconds), it falls back to UDP automatically.
On Linux, SHM uses POSIX shared memory (shm_open) and named semaphores. On Windows, it uses Named File Mappings (page-file-backed CreateFileMapping) and Win32 named semaphores — the shared data layout is identical on both platforms.
Source settings
| Setting | Default | Description |
|---|---|---|
| Sender name | (empty) | Filter by sender name. Empty accepts any sender. Dropdown auto-populates from discovery. |
| Port | 0 (auto) | UDP port to listen on. 0 lets the OS pick a free port. |
| Force UDP | off | Skip SHM and use UDP only. Enable this for remote senders on another machine. |
Building
Windows
Requires Visual Studio 2022 and CMake 3.30+.
cmake --preset windows-x64
cmake --build --preset windows-x64
Install target places the plugin at %ALLUSERSPROFILE%\obs-studio\plugins\obs-slm-source\bin\64bit\obs-slm-source.dll.
Linux (Ubuntu 24.04)
Requires CMake 3.28+, ninja-build, pkg-config, and build-essential.
cmake --preset ubuntu-x86_64
cmake --build --preset ubuntu-x86_64
Platform notes
- Windows uses Winsock2; Linux/macOS use POSIX sockets.
- SHM works on both Linux and Windows. The
Force UDPsetting disables SHM on all platforms. - Multicast requires sender and receiver to be on the same subnet (or multicast routing to be configured for remote senders).
Planned
- Tally signal (#21): OBS detects when a source enters or leaves the Program/Preview slots and unicasts
PKT_TALLYback to the sender so remote operators know they are live. - Operator messaging (#21): A text field in the source properties lets the studio operator send a short message to the connected sender (e.g. "zoom in"), displayed as an overlay on the remote device.
- Dynamic bitrate feedback (#10): Loss-rate reporting from receiver to sender to allow encoder step-down on degraded links.