First CI run confirmed winvm-builder is a self-hosted act_runner labeled "windows-latest" but not the GitHub-hosted windows-latest image -- cmake isn't on PATH there (unlike the Linux/macOS runners, which do have working system/brew package managers). Use lukka/get-cmake to fetch a pinned cmake+ninja without needing admin/choco. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
obs-streamer-tools-plugin
Native OBS Studio source plugin that will pull streamer-tools camera feeds
directly from LiveKit over WebRTC (via LiveKit's livekit-ffi), replacing
the current SRT/RTSP-via-VLC-or-Media-Source path for directors. Full
design: docs/superpowers/specs/2026-09-06-obs-camera-plugin-design.md in
the streamer-tools repo (as of this writing, that doc lives on the
worktree-obs-plugin-server-api branch there, not yet merged to main).
Status: scaffolding only
This repository does not talk to LiveKit or streamer-tools yet. This
first pass exists to prove the CMake toolchain, the core-library/OBS-adapter
split, and the three-platform Gitea Actions CI pipeline all actually work,
so the next phase (real livekit-ffi integration) can be planned against
verified facts instead of assumptions. See the design doc's "Components"
and "CI / build pipeline" sections for the target architecture this scaffold
is standing up.
Layout
core/ - core library (C++17, no OBS dependency, headless-testable)
include/stplugin/
core.h C++ API (ConnectionConfig, core_version())
core_c.h C ABI wrapper the OBS adapter calls into
src/core.cpp
tests/ dependency-free CTest unit tests
obs-adapter/ - thin OBS glue (C, adapted from obsproject/obs-plugintemplate)
src/plugin-main.c obs_module_load/unload + a stub source registration
src/plugin-support.{h,c.in}
data/locale/en-US.ini
.gitea/workflows/build.yml - 3-platform CI matrix (see below)
Everything in core/ is real, working, unit-tested code -- it just doesn't
do anything useful yet (a version string, a config struct with non-empty
validation). Everything in obs-adapter/ is real OBS module code -- it
registers an actual obs_source_info and builds as a real, dynamically
loadable OBS module (see "Verified" below) -- but the source is a stub:
create/destroy allocate/free a dummy blob, there is no properties UI,
and no frames are ever pushed. That's the boundary this task was scoped to.
What's real vs. deliberately deferred
Deferred, per the task that produced this scaffold (out of scope for this pass, in scope for the next one):
- No
livekit-ffilinkage of any kind. - No streamer-tools API client (auth, slot-listing, token minting).
- No properties UI (server URL / room slug / read key / camera dropdown).
- No frame output (
obs_source_output_video/_audio). - No packaging/release step (the design doc's "on a version tag" job).
Toolchain notes (verified on this machine: Ubuntu 24.04 / Linux)
- CMake 3.28.3, Ninja 1.11.1, GCC 13.3.0 -- all installed via
apt-get install cmake ninja-build. Top-levelCMakeLists.txtrequires CMake >= 3.16 (deliberately lower than the official obsproject/obs-plugintemplate's3.28...3.30floor -- see below). - OBS plugin template used as reference: obsproject/obs-plugintemplate,
commit
3e7d7ac3b5342cd7d9b88890b9c70b472d1520fc(2025-12-09, "Fix typo of Visual Studio in README"), fetched fresh from GitHub.src/plugin-main.c,src/plugin-support.{h,c.in}, and the emptydata/locale/en-US.iniinobs-adapter/are adapted directly from it. - Deliberate deviation from the template's own build system: the
official template's
CMakeLists.txtchains intocmake/common/bootstrap.cmake, which in turn readsbuildspec.jsonand downloads full OBS source archives (pinned to OBS 31.1.1) plus prebuilt dependency bundles for macOS and Windows. That machinery is real, actively maintained, and probably the right long-term answer for cross-platform reproducible builds -- but it's heavy (multi-hundred-MB downloads, a wholecmake/{macos,windows,common}support tree, Qt6, code-signing hooks) and out of scope to stand up and debug in one pass. This scaffold instead uses a much simpler hand-written top-levelCMakeLists.txtthat callsfind_package(libobs)directly. - On Linux, this actually works far better than expected: Ubuntu ships
a real
libobs-devpackage (30.0.2+dfsg-3build1on 24.04, i.e. not the 31.1.1 the template's buildspec.json pins -- worth reconciling before the next phase if API surface matters) with genuine CMake package config files (/usr/lib/x86_64-linux-gnu/cmake/libobs/libobsConfig.cmake,libobsTargets.cmake) that export anOBS::libobsimported target -- the exact target name the official template expects.find_package(libobs QUIET)finds it with zero extra plumbing. This means the OBS adapter in this repo links against real OBS headers and a reallibobs.so, not a stub -- confirmed bylddshowinglibobs.so.0andnm -Dshowing realobs_module_*exports (see "Verified" below). Install viaapt-get install libobs-dev(pulls in Qt6 as a dependency chain, ~seconds on a fast mirror). - macOS/Windows have no equivalent system package (there's no Homebrew
formula or winget package that ships
libobsConfig.cmakethe way Ubuntu'slibobs-devdoes). For those platforms the choices are: (a) adopt the template's full buildspec-driven source/prebuilt-deps download, or (b) find/produce a lighter prebuilt SDK bundle. This is now a concrete, scoped decision for the next phase, not a guess -- the CI workflow in this repo currently takes option (c) for this pass only: skip building the OBS adapter on macOS/Windows and build+test just the core library, via the samefind_package(libobs QUIET)fallback the top-levelCMakeLists.txtalready has for exactly this situation. ENABLE_QT/ENABLE_FRONTEND_APItemplate options were not carried over -- this scaffold's properties-UI-free stub doesn't need Qt yet; the real adapter will need to revisit this once the properties UI (server URL / room slug / read key / camera dropdown) is built.
What actually builds, and how it was verified
$ cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release
-- libobs found (/usr/lib/x86_64-linux-gnu/cmake/libobs) -- building OBS adapter module
-- Configuring done
-- Generating done
$ cmake --build build
[1/7] Building C object obs-adapter/CMakeFiles/streamer-tools-camera.dir/plugin-support.c.o
[2/7] Building C object obs-adapter/CMakeFiles/streamer-tools-camera.dir/src/plugin-main.c.o
[3/7] Building CXX object core/CMakeFiles/stplugin_core.dir/src/core.cpp.o
[4/7] Linking CXX static library core/libstplugin_core.a
[5/7] Building CXX object core/tests/CMakeFiles/stplugin_core_tests.dir/test_core.cpp.o
[6/7] Linking CXX shared module obs-adapter/streamer-tools-camera.so
[7/7] Linking CXX executable core/tests/stplugin_core_tests
$ ctest --test-dir build --output-on-failure
1/1 Test #1: stplugin_core_tests .............. Passed 0.00 sec
100% tests passed, 0 tests failed out of 1
$ ldd build/obs-adapter/streamer-tools-camera.so | grep obs
libobs.so.0 => /lib/x86_64-linux-gnu/libobs.so.0 (...)
$ nm -D build/obs-adapter/streamer-tools-camera.so | grep obs_module
0000000000001430 T obs_module_free_locale
0000000000001450 T obs_module_load
...
0000000000001490 T obs_module_unload
This is a genuine, dynamically-linked OBS module -- not the "standalone shared library without linking OBS" fallback the scaffolding task's scope explicitly allowed as an acceptable compromise. That fallback path is still exercised (and needed) on macOS/Windows CI for now; see above.
CI
.gitea/workflows/build.yml runs on every push/PR, matrixed across the
three runners confirmed available to this repo by living under the
CyberCoveLLC org (see the design doc's "CI / build pipeline" section):
| Job | runs-on |
Runner |
|---|---|---|
linux |
ubuntu-latest |
gitea-runner.internal.cloud-hosting.io (Global) or localhost.localdomain (org-scoped; note: now online with ubuntu-latest/ubuntu-24.04/ubuntu-22.04 labels -- the design doc recorded it as offline, that's since changed) |
macos |
macos-latest |
home-mac (Global) |
windows |
windows-latest |
winvm-builder (org-scoped to CyberCoveLLC) |
The Linux job installs libobs-dev and builds the real OBS adapter module
plus the core library, then runs ctest. The macOS/Windows jobs build and
test only the core library for now (see toolchain notes above for why).
No packaging/release step yet -- out of scope for this pass.