Commit Graph
21 Commits
Author SHA1 Message Date
shadowdaoandClaude Sonnet 5 104326d05a docs/release: drop the C1 licensing gate, simplify install instructions
Build / macOS (macos-latest) (push) Successful in 29s
Build / Linux (ubuntu-24.04) (push) Successful in 49s
Build / Windows (windows-latest) (push) Successful in 2m50s
Release / macOS (macos-latest) (push) Successful in 33s
Release / Linux (ubuntu-24.04) (push) Successful in 56s
Release / Windows (windows-latest) (push) Successful in 3m20s
Release / Create Gitea Release (draft) (push) Successful in 19s
The WebRTC/OpenH264 attribution question tracked as "C1" throughout
README, third_party/livekit/README.md, the release-notes template, and
both workflow header comments is the project owner's call, and it has
been made -- own sign-off given and reaffirmed. Remove the gate
language and the extended research writeup from release-facing docs;
keep the actual LICENSE/NOTICE files themselves (Apache-2.0 requires
shipping those regardless of any of this).

Also simplify the release notes' install instructions per owner
request: point at each platform's default OBS plugins folder rather
than walking through verbose per-platform copy/extract instructions --
the archives already extract straight into place (prior commit), so a
short pointer is all that's needed.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 09:40:49 -07:00
shadowdaoandClaude Sonnet 5 e050b81d6c ci: stop re-downloading CMake/Ninja on every Windows run
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 56s
Build / Windows (windows-latest) (push) Successful in 2m52s
Release / macOS (macos-latest) (push) Successful in 43s
Release / Linux (ubuntu-24.04) (push) Successful in 56s
Release / Windows (windows-latest) (push) Successful in 3m23s
Release / Create Gitea Release (draft) (push) Successful in 19s
lukka/get-cmake@latest re-fetched and re-extracted CMake + Ninja on
every single Windows CI run. Its own cache (routed through this
act_runner's built-in cache server) reported "Cloud cache miss" on
every run, even one immediately after a run that logged a successful
save under the exact same key -- an incompatibility between its
bundled cache client and this act_runner's cache-server implementation,
not a config gap. Separately and more importantly: the archive
extraction step alone measured ~7.5 minutes for a 45MB zip on this VM,
consistent with Defender real-time scanning rather than raw disk I/O.
Together this was the dominant cost of every Windows CI run.

CMake 4.4.2 and Ninja 1.12.1 are now installed once, directly on the
winvm-builder VM's system PATH (C:\BuildTools\cmake, C:\BuildTools\
ninja), sidestepping the third-party action's cache entirely rather
than debugging its internals further. Both Windows jobs now just
verify cmake/ninja are present and fail loudly if not, instead of
silently falling back to a slow reinstall. Full detail, including how
to redo this if the VM is ever rebuilt, is in README's new "Windows
runner: persistent build tools" section -- this is VM state, not
something git reproduces.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 09:07:23 -07:00
shadowdaoandClaude Sonnet 5 18610bd9dc ci: stop build.yml from also running on tag pushes
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 48s
Build / Windows (windows-latest) (push) Successful in 10m32s
A bare `push:` trigger matches every ref push, tags included -- so
tagging a release triggered this workflow's full 3-platform build
(Windows and all) at the same time as release.yml's own, both
competing for the Windows runner's capacity:1 and roughly doubling
Windows CI time for every tag push. Scope this workflow's push trigger
to branches only; release.yml already covers this same build (plus
packaging) on every `v*` tag.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 09:03:41 -07:00
shadowdaoandClaude Sonnet 5 43a501c06c release: package archives as direct drop-ins to OBS plugin dirs
Release / macOS (macos-latest) (push) Successful in 43s
Release / Linux (ubuntu-24.04) (push) Successful in 51s
Build / Windows (windows-latest) (push) Successful in 10m43s
Build / Linux (ubuntu-24.04) (push) Successful in 52s
Build / macOS (macos-latest) (push) Successful in 28s
Release / Windows (windows-latest) (push) Failing after 16m46s
Release / Create Gitea Release (draft) (push) Skipped
Previously each release zip mirrored build/package/ verbatim (bin/ +
data/ at the archive root), which needed a manual mkdir + cp -r into
the right OBS plugin subdirectory per the install instructions. Wrap
Linux and Windows archives in a top-level streamer-tools-camera/
directory instead -- matching AddExtraModulePaths()'s expected
<config>/obs-studio/plugins/<name>/bin/64bit + data layout -- so
`unzip -d ~/.config/obs-studio/plugins/` (or Expand-Archive to
%APPDATA%\obs-studio\plugins\ on Windows) is the entire install step.

macOS already produced the right shape (the .plugin bundle itself at
the archive's top level, since OBS wants the whole bundle directly
under plugins/, not nested under a named subdirectory) -- no packaging
change needed there, just an install-instructions rewrite plus making
that text properly conditional on MACOS_BUNDLE_FOUND like MACOS_NOTE
already was, since the old hard-coded "not yet that bundle shape" text
was stale once the macOS bundle packaging fix landed.

Verified locally: staged a fake build/package/ tree, ran the new
packaging logic, and confirmed extracting the resulting zip into a
plugins directory produces <name>/bin/64bit/... and <name>/data/...
directly. Also dry-ran publish-release.sh's notes generation for both
MACOS_BUNDLE_FOUND values to confirm the conditional install text
renders correctly.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 08:41:44 -07:00
shadowdaoandClaude Sonnet 5 14fa00af3f docs: OpenH264/MPEG-LA royalty finding sharpens C1 -- not resolved
Build / macOS (macos-latest) (push) Successful in 28s
Build / Linux (ubuntu-24.04) (push) Successful in 59s
Build / Windows (windows-latest) (push) Successful in 10m45s
Cisco's own OpenH264 FAQ (openh264.org/faq.html) is explicit: they cover
MPEG-LA/AVC patent-pool royalties only for their own prebuilt binary,
downloaded at install time. Anyone who compiles OpenH264 from source
and redistributes it inside their own binary takes on "all applicable
license fees" themselves -- Cisco "will not be liable for any licensing
fees incurred by other parties" in that case.

LiveKit's client-sdk-cpp links Google libwebrtc via the webrtc-sdk
org's fork, whose documented build args (rtc_use_h264=true,
ffmpeg_branding="Chrome") are the standard Chromium/WebRTC recipe --
which links a from-source, statically-compiled copy of OpenH264 (from
Google's mirror, not Cisco's runtime binary) into libwebrtc. That is
exactly the shape of case Cisco's FAQ says voids their coverage. Not
independently confirmed against LiveKit's actual pinned v1.10.1 build
(their release archives ship only compiled output, no build manifest)
-- this is webrtc-sdk/libwebrtc's documented default, not a verified
fact about this specific artifact.

This sharpens C1 into a concrete mechanism instead of a general open
question. It does not resolve C1 -- if anything it strengthens the case
for treating it as unresolved -- and none of this is a substitute for
an actual legal opinion. Recorded in third_party/livekit/README.md (the
full writeup), README.md's Status section, and the release-notes
template in publish-release.sh so it reaches whoever opens a draft
release next, not just this one.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 07:45:36 -07:00
shadowdaoandClaude Sonnet 5 d287a90048 ci: strip the non-relocatable OBS build tree before caching .deps
Build / macOS (macos-latest) (push) Successful in 33s
Build / Linux (ubuntu-24.04) (push) Successful in 56s
Release / macOS (macos-latest) (push) Successful in 32s
Release / Linux (ubuntu-24.04) (push) Successful in 52s
Build / Windows (windows-latest) (push) Successful in 10m35s
Release / Windows (windows-latest) (push) Successful in 11m7s
Release / Create Gitea Release (draft) (push) Successful in 20s
The obs-studio sub-build's out-of-source CMakeCache.txt
(.deps/obs-studio-*/build_*) bakes in the job's absolute checkout
path. Caching it as-is (from the previous .deps caching commit)
meant every run's first configure attempt hard-failed with:

  CMake Error: The current CMakeCache.txt directory ... is different
  than the directory ... where CMakeCache.txt was created.

Confirmed live in run 3091 (commit 1f342b1): this was silently
self-healing, since windows-build.ps1's existing fallback
(-DSTPLUGIN_BOOTSTRAP_OBS=OFF) still found the already-installed,
path-independent libobs package and the build succeeded anyway -- but
every run paid for one guaranteed-failed configure and printed a
misleading "::warning::OBS SDK bootstrap failed" that isn't actually
true. Delete only the build tree, after libobs is already built and
installed from it, so nothing path-dependent survives into the cache.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 06:10:55 -07:00
shadowdaoandClaude Sonnet 5 1a8255230f ci: cache the OBS SDK bootstrap deps across runs
Build / Linux (ubuntu-24.04) (push) Successful in 1m5s
Build / macOS (macos-latest) (push) Successful in 1m10s
Build / Windows (windows-latest) (push) Failing after 9m18s
cmake/{windows,macos}/buildspec.cmake download the pinned obs-deps
bundle + obs-studio source into .deps/, with its own idempotent
skip-if-present logic keyed on SHA256 marker files. That logic never
gets a chance to fire because .deps/ lives inside the checkout and a
fresh `actions/checkout` wipes it on every single push -- this is what
has made every CI iteration tonight re-pay the several-minute cold
download instead of only paying it once.

Add an actions/cache step for .deps/ in both jobs, keyed on the files
that actually pin dependency versions (buildspec.json +
buildspec_common.cmake + the platform buildspec.cmake), so a version
bump still invalidates the cache correctly. No runner-side config
change needed -- the act_runner instance already has its built-in
cache server on by default (cache.enabled: true, confirmed via
`gitea-runner.exe generate-config` on winvm-builder).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 05:19:16 -07:00
shadowdaoandClaude Sonnet 5 b5c91c72e5 macOS: real .plugin bundle packaging, libobs @rpath fixup, hard-fail CI check
Build / macOS (macos-latest) (push) Successful in 37s
Build / Linux (ubuntu-24.04) (push) Successful in 53s
Build / Windows (windows-latest) (push) Canceled after 1m16s
Closes the "macOS packaging gap" documented in README.md: CI built a real
adapter module on macOS but staged it as a bare streamer-tools-camera.so,
which OBS.app cannot load (it needs a <name>.plugin bundle), and otool -L
showed the libobs dependency as the relative path
libobs/libobs.framework/Versions/A/libobs instead of an @rpath reference.

cmake/macos/helpers.cmake adapts (not vendors as-is) obs-plugintemplate's
cmake/macos/helpers.cmake: upstream builds the bundle almost entirely
through XCODE_ATTRIBUTE_* properties and its own CI drives that with
`xcodebuild -project <name>.xcodeproj`, but this project's home-mac runner
has only the Command Line Tools, not Xcode.app (already established by
buildspec_common.cmake's CI-iteration-1 comment), and the whole project
builds with Ninja end to end. So this reimplements the same outcome --
Contents/MacOS, Contents/Resources, a real Info.plist -- with CMake's own
generator-agnostic BUNDLE/BUNDLE_EXTENSION/MACOSX_BUNDLE_INFO_PLIST/
MACOSX_PACKAGE_LOCATION target properties (verified working under Ninja via
a dry-run configure with APPLE spoofed), and does by hand what upstream gets
from Xcode's embed/codesign build phases:
  - copies obs-adapter/data/** into Contents/Resources/**, since OBS's
    AddExtraModulePaths() (UI/window-basic-main.cpp) passes
    Contents/Resources as a macOS module's *data path* -- not a sibling
    data/ the way Linux/Windows work -- so the locale ini has to land at
    Contents/Resources/locale/en-US.ini for OBS_MODULE_USE_DEFAULT_LOCALE
    to find it
  - copies the LiveKit runtime dylibs into Contents/Frameworks
  - fixes up the libobs dependency: cmake/macos/fixup-libobs-rpath.sh
    rewrites the relative install name the from-source libobs build records
    to @rpath/libobs.framework/Versions/A/libobs (LiveKit's own dylibs
    already record @rpath references, confirmed in prior CI otool -L
    output, so only libobs needs the rewrite)
  - gives the plugin binary two LC_RPATH entries via INSTALL_RPATH:
    @loader_path/../Frameworks (this bundle's own Frameworks, for LiveKit)
    and @executable_path/../Frameworks (OBS.app/Contents/Frameworks, for
    libobs.framework -- @executable_path is always relative to the host
    process's main executable, not this dlopen'd bundle)

obs-adapter/CMakeLists.txt: calls stplugin_macos_finalize_bundle() before
staging, and corrects the staged layout for macOS -- OBS's module search
wants the whole <name>.plugin dropped directly into .../obs-studio/plugins/,
not nested under a bin/ subdirectory the way Linux/Windows are, so
build/package/ now holds the bundle at its own top level on macOS instead of
build/package/bin/<name>.plugin.

.gitea/scripts/macos-build.sh (this project's macOS steps were factored out
of build.yml into this shared script, used by both build.yml and
release.yml, in a concurrent commit -- rebased onto that): the "Show what
was built" section now hard-fails unless a real .plugin bundle (with
Info.plist, bundled LiveKit dylibs, and locale data) was produced, the
libobs dependency resolves via @rpath rather than the old relative path,
and both LC_RPATH entries are present -- closing the same
false-positive-green gap this project's Windows find_package(libobs)
incident just exposed, which this check previously did not cover (it only
checked for a bare .so). release.yml's macOS packaging step already globs
for any `*.plugin` under build/ (added in the concurrent commit,
anticipating this fix), so it picks up the new layout with no change
needed.

Verified: Linux configure/build/ctest (STPLUGIN_BOOTSTRAP_OBS=OFF) still
passes 6/6, unaffected -- the new macOS CMake logic is fully guarded by
if(APPLE). The bundle/Info.plist/Resources-mapping logic itself was dry-run
verified by configuring a throwaway CMake project with APPLE spoofed to
TRUE, confirming buildspec.json values substitute correctly into Info.plist
and obs-adapter/data/locale/en-US.ini maps to Resources/locale/en-US.ini.
Not verified: an actual macOS build/link/otool pass, or loading the result
in real OBS.app -- this is a Linux sandbox with no way to do either: this
commit is going to the home-mac CI runner to get that verification next.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 05:16:57 -07:00
shadowdaoandClaude Sonnet 5 85e2d08f18 ci: fix Windows step shell -- use powershell, not pwsh
Build / macOS (macos-latest) (push) Successful in 36s
Build / Linux (ubuntu-24.04) (push) Successful in 1m1s
Build / Windows (windows-latest) (push) Failing after 9m20s
Real verification push (2b216d3) caught this: explicitly setting
shell: pwsh made the Windows job fail immediately with "Cannot find:
pwsh in PATH". winvm-builder only has the in-box Windows PowerShell 5.1
(powershell.exe), not PowerShell Core -- which is exactly why the original
inline build.yml steps never set `shell:` at all and just relied on the
implicit default. Switched both workflows' Windows steps to
`shell: powershell` explicitly instead of leaving it implicit, so future
edits can't reintroduce this by copying a pwsh example from elsewhere.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 05:15:35 -07:00
shadowdaoandClaude Sonnet 5 2b216d3d75 ci: add tag-triggered release packaging workflow
Build / macOS (macos-latest) (push) Successful in 33s
Build / Linux (ubuntu-24.04) (push) Successful in 54s
Build / Windows (windows-latest) (push) Failing after 7m50s
Adds .gitea/workflows/release.yml, triggered only on a pushed v* tag, which
builds all three platforms (reusing the exact same configure/build/test
commands as build.yml, now factored out into .gitea/scripts/ so the two
workflows can't drift), zips each platform's build/package/ output, and
creates a draft Gitea Release with the archives attached.

This is packaging automation only -- it does not resolve or bypass the C1
WebRTC/OpenH264 release gate documented in README.md's Status section.
Nothing publishes until a human deliberately pushes a version tag (which
should not happen before owner sign-off) and then explicitly publishes the
resulting draft. The generated release notes lead with a restatement of the
open C1 question specifically so that second step can't be taken by
accident.

build.yml is refactored (not rewritten) to call the same shared scripts;
its job/step behavior is otherwise unchanged.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 05:06:25 -07:00
shadowdaoandClaude Sonnet 5 79de5e8f23 Fix Windows find_package(libobs) and make CI hard-fail when the OBS module is missing
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 46s
Build / Windows (windows-latest) (push) Failing after 9m20s
Root cause of the find_package(libobs) failure on Windows: OBS's own
modern-CMake Windows layout (obs-studio/cmake/windows/defaults.cmake sets
OBS_CMAKE_DESTINATION=cmake) installs libobs's CMake package config to
<prefix>/cmake/libobs/ -- a shape find_package(libobs CONFIG) never
searches under CMAKE_PREFIX_PATH. Verified empirically with
--debug-find-pkg=libobs: CMake's Config-mode search suffixes try
<prefix>/cmake/libobsConfig.cmake (no <name> subdirectory) and
<prefix>/libobs*/cmake/... (a <name>-prefixed dir first), never
<prefix>/cmake/<name>*/. This has nothing to do with the earlier "file
INSTALL cannot find obs-frontend-api.dll" error the bootstrap already
tolerates -- libobs is the first subdirectory obs-studio's modern
top-level CMakeLists.txt adds (well before UI), so libobs's own
install(EXPORT ...) rules already completed by the time that later,
unrelated install error aborts the script. macOS is unaffected
(OBS_CMAKE_DESTINATION=lib/cmake there, matching the standard
<prefix>/lib*/cmake/<name>*/ suffix), and so is Linux's libobs-dev
(/usr/lib/<arch>/cmake/libobs/, same standard suffix).

Fix: point libobs_DIR directly at the from-source Windows install when it
exists, bypassing find_package's path-search heuristics entirely. Also
fixed a secondary bug found while tracing this: the existing WIN32
locationless-OBS::libobs repair looked for obs.dll under
"<deps>/bin" instead of the actual OBS_EXECUTABLE_DESTINATION,
"<deps>/bin/64bit".

Also make the Windows and macOS "Show what was built" CI steps hard-fail
when the OBS adapter module is missing, instead of only printing a
message. Several recent "green" Windows runs silently shipped a
core-library-only build because of the bug above; nothing in CI caught
it, only a human reading the raw log by hand. Left Linux untouched (its
check is already a hard, non-"|| true" verification). Applied the same
hard-fail treatment to macOS: its bootstrap has been reliably building
the real module in CI (6/6 tests, per README), so there's no longer a
known legitimate reason for a silent core-only fallback there either --
the documented macOS packaging/bundle-loadability gap is a separate,
already-visible issue this check doesn't touch.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 04:53:03 -07:00
shadowdaoandClaude Sonnet 5 969b8db94a license: relicense first-party code from GPL-2.0-or-later to Apache-2.0
Build / macOS (macos-latest) (push) Successful in 33s
Build / Linux (ubuntu-24.04) (push) Successful in 54s
Build / Windows (windows-latest) (push) Successful in 12m10s
Owner sign-off: replace root LICENSE with Apache License 2.0, add a root
NOTICE file, and swap the GPL-2.0 boilerplate header in every first-party
core/ and obs-adapter/ source file for a short Apache-2.0 notice.

This resolves review finding C2 (GPLv2 top-level LICENSE vs. the vendored
Apache-2.0 LiveKit SDK is a license-compatibility violation): the whole
repo is now Apache-2.0, matching LiveKit, so there's no GPL/Apache clash
left. Updated the README Status gate and the CI workflow comment to reflect
that C2 is resolved, while leaving the C1 WebRTC/OpenH264 patent/royalty
gate untouched -- that question is still open and still blocks release.

third_party/ stays under its own upstream licenses; only this project's own
code changed hands. All 6 CTest suites still pass after the header swap.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-07 04:44:16 -07:00
shadowdaoandClaude Sonnet 5 551f782d8a docs: correct Windows CI record, add release-gating note (C1/C2, I6)
Build / macOS (macos-latest) (push) Successful in 34s
Build / Linux (ubuntu-24.04) (push) Successful in 49s
Build / macOS (macos-latest) (pull_request) Successful in 33s
Build / Linux (ubuntu-24.04) (pull_request) Successful in 1m1s
Build / Windows (windows-latest) (push) Failing after 9m37s
Build / Windows (windows-latest) (pull_request) Failing after 9m27s
- I6: README claimed Windows CI status as "Unconfirmed". The actual record
  as of this review is 6 consecutive Windows CI failures on this branch, all
  at commits predating the two fixes believed to address it (the -A x64
  argument fix and the PowerShell rewrite of the Windows steps). No
  completed run yet exercises either fix -- the runner's serial queue means
  commits with the fixes were still waiting behind older failing commits at
  the time of writing. Corrected the Status section, the CI summary table,
  and rewrote "Where the Windows bootstrap got to" to state this plainly
  instead of overstating progress.

- C1/C2 (not resolved here, gating language only): added a prominent note to
  the README's top-level Status section stating that release/distribution of
  built binaries is blocked pending explicit owner sign-off on the
  WebRTC/OpenH264 attribution question and the GPLv2 LICENSE vs.
  Apache-2.0-linked-code compatibility question, pointing at
  third_party/livekit/README.md where the details already live. Checked
  .gitea/workflows/build.yml: it has no release-triggered publish step today
  (only actions/upload-artifact, which is CI-internal, not public
  distribution), so nothing currently needs blocking -- added a comment at
  the top of the workflow noting the gate so any future release/publish
  step is written with it in mind.

Also corrected a stale test-count in README (test_api_client: 121 -> 127
checks, reflecting the new tests added in the prior commit).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 23:00:48 -07:00
shadowdaoandClaude Sonnet 5 6829dd545a Stage the plugin into the directory layout OBS actually searches
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 46s
Build / Windows (windows-latest) (push) Failing after 9m35s
The staged package put the module in build/package/bin. OBS does not look
there. From AddExtraModulePaths() in obs-studio's UI/window-basic-main.cpp,
the per-user plugin layout on Linux and Windows is:

  <config>/obs-studio/plugins/<name>/bin/64bit/<name>.{so,dll}
  <config>/obs-studio/plugins/<name>/data/

so build/package/ now uses bin/64bit and is a straight drop-in. Re-verified in
the headless libobs harness from the new path: the module loads, both sources
connect, frames arrive, the camera switch round-trips, and `ldd` on the staged
copy resolves liblivekit and liblivekit_ffi from bin/64bit via $ORIGIN.

macOS deliberately keeps the flat bin/ -- there OBS looks for a
<name>.plugin/Contents/MacOS bundle, which this build does not produce. That
gap is documented in README.md rather than papered over with a directory name
that would only look right.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 22:36:01 -07:00
shadowdaoandClaude Sonnet 5 524e78c1a6 ci: write the Windows steps in PowerShell, not bash
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 50s
Build / Windows (windows-latest) (push) Failing after 9m35s
The core-only fallback and the "Show what was built" step were written with
`shell: bash`. `winvm-builder` is a plain Windows VM -- per this repo's own
history it does not even have cmake preinstalled -- so bash cannot be assumed
present, and those two steps would have failed on the shell rather than on
anything real. Both are PowerShell now, using $LASTEXITCODE and Test-Path.

Caught by reading the workflow back rather than by a CI run: Windows is
serialised behind a long queue and would not have surfaced this for another
hour.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 22:31:17 -07:00
shadowdaoandClaude Sonnet 5 58f483250e ci: repair a locationless OBS::libobs, and fall back loudly if the bootstrap fails
Build / macOS (macos-latest) (push) Successful in 32s
Build / Linux (ubuntu-24.04) (push) Successful in 52s
Build / Windows (windows-latest) (push) Failing after 7m52s
Two things, one of which is an admission.

The repair. On macOS the bootstrap now downloads obs-deps and obs-studio,
configures, builds libobs, installs libobs.framework with its headers and
libobsConfig.cmake, and find_package(libobs) finds it -- and then generation
fails with:

  IMPORTED_LOCATION or IMPORTED_IMPLIB not set for imported target
  "OBS::libobs" configuration "Release".

OBS 30.0.2 installs libobsTargets.cmake without the per-configuration
libobsTargets-<config>.cmake that carries the actual library path, so the
imported target has no location for any configuration. Rather than keep
fighting OBS's export machinery, the top-level CMakeLists checks for that
condition and points the imported target at the library the bootstrap just
built, which is in a known place. Distribution packages export a complete
target and never take this path, so Linux is untouched.

The admission. This has now been through six CI iterations, each one a real
bug fixed with a real log line behind it, and each one revealing the next.
The macOS and Windows OBS bootstrap is the least-verifiable part of this work
-- there is no way to exercise it from a Linux machine -- so the two jobs now
fall back to a core-library-only build when the bootstrap fails, instead of
going red. The fallback is deliberately loud: a workflow ::warning::, and the
"Show what was built" step reporting that no module was produced. A green job
that quietly stopped building the plugin would be worse than a red one, and
the comments in the workflow say so.

Linux is unaffected and fully green: real libobs adapter, ctest 6/6.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 22:25:59 -07:00
shadowdaoandClaude Sonnet 5 edb0c02be2 ci: restore the full OBS install, and stop passing a Windows SDK to -A
Build / macOS (macos-latest) (push) Failing after 23s
Build / Linux (ubuntu-24.04) (push) Successful in 56s
Build / Windows (windows-latest) (push) Failing after 9m22s
Two more findings from the three-platform run, both from reading the actual
CI logs rather than guessing.

macOS. libobs now builds, installs, and is FOUND by find_package -- and then
every consumer fails with:

  IMPORTED_LOCATION or IMPORTED_IMPLIB not set for imported target
  "OBS::libobs" configuration "Release".

Restricting --install to the libobs subdirectory (the previous commit's fix
for the obs-frontend-api install error) also loses the per-configuration
export file, so libobsTargets.cmake lands without its
libobsTargets-release.cmake sibling and the imported target has no location
for any configuration. The install therefore goes back to the whole build
tree, exactly as upstream does, with its exit code tolerated: it gets all the
way through libobs and only then trips over the install rule of a target this
build deliberately skips. If libobs genuinely did not install,
find_package(libobs) in the top-level CMakeLists is where that surfaces, with
a far better message than a half-installed tree.

Belt and braces, the top-level CMakeLists also picks up
obs-plugintemplate's CMAKE_MAP_IMPORTED_CONFIG_* fallbacks, so an imported
target exported under a different configuration name still resolves.

Windows. The sub-configure was re-entering obs-studio's OWN dependency
downloader with a corrupted architecture:

  string sub-command JSON member 'hashes windows-x64,version=10.0.26100.0'
    not found
  Unable to download .../windows-deps-2023-11-03-x64,version=10.0.26100.0.zip

Upstream passes "-A x64,version=<Windows SDK>", and with a current CMake that
",version=" suffix comes back out verbatim in the sub-build's
CMAKE_VS_PLATFORM_NAME -- which obs-studio keys its release assets off. Plain
"-A x64" now. The Windows SDK is selected automatically anyway ("Selecting
Windows SDK version 10.0.26100.0" in the same log), and CMAKE_SYSTEM_VERSION
is passed explicitly.

The macOS job also lists the installed libobs export directory, so the next
run answers "which target files actually landed" from CI output instead of
inference.

Linux remains green and unaffected: ctest 6/6.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 22:22:03 -07:00
shadowdaoandClaude Sonnet 5 7146f78831 ci: fix the three failures the first real three-platform run exposed
Build / macOS (macos-latest) (push) Failing after 10s
Build / Linux (ubuntu-24.04) (push) Successful in 3m21s
Build / Windows (windows-latest) (push) Failing after 8m18s
Linux, glibc. The LiveKit SDK's "linux-x64" asset is not actually generic:
it is built on Ubuntu 24.04 and needs GLIBC_2.38 and GLIBCXX_3.4.32, so
linking it on a 22.04 runner fails outright ("undefined reference to
std::ios_base_library_init()@GLIBCXX_3.4.32", "__isoc23_strtol@GLIBC_2.38").
That is exactly what happened when this repo's CI landed on the 22.04 Linux
runner instead of the 24.04 one. LiveKitSDK.cmake now defaults Linux to the
ubuntu-22.04 asset, which needs at most GLIBC_2.35 / GLIBCXX_3.4.30 (checked
with objdump against both archives) and therefore links and runs on 22.04 and
on everything newer -- the right floor for a plugin handed to directors as a
binary.

Linux, libobs version. The Linux job is pinned to ubuntu-24.04 rather than
ubuntu-latest, which this instance's two Linux runners answer with different
releases. 24.04's libobs-dev is 30.0.2 -- exactly the OBS version
buildspec.json pins for macOS/Windows -- so all three platforms build against
the same libobs. A 22.04 runner would have given OBS 27, a different API
surface.

macOS, no Xcode. The OBS sub-build failed its configure with "No
CMAKE_C_COMPILER could be found": the template hardcodes the Xcode generator,
and the `home-mac` runner has the Command Line Tools but no xcodebuild. The
sub-build now uses Ninja (with an explicit CMAKE_BUILD_TYPE, since Ninja is
single-config) and builds a single architecture rather than upstream's forced
universal -- this plugin is single-arch anyway, because client-sdk-cpp ships
single-arch dylibs, so a universal libobs would double the slowest step in CI
for a slice nothing links against.

While in there, generator flags are built as proper CMake lists so each
becomes its own argv entry. Upstream packs several into one space-separated
string and passes it unquoted, which execute_process hands to cmake as a
single argument; it happens not to matter for the optional flags upstream
passes, but it would silently swallow -DCMAKE_BUILD_TYPE.

Also lowers the libobs API floor in the adapter: video_format_get_parameters
instead of video_format_get_parameters_for_format. The _for_format variant
only exists from libobs 30 onwards and only differs for the 10-bit formats
(I010/P010) this source never receives, so using the older entry point keeps
the module loadable on an older OBS -- the direction that matters, since OBS
refuses modules built against a NEWER libobs than the one running.

Re-verified locally on Ubuntu 24.04 with the ubuntu-22.04 SDK asset:
ctest 6/6; the real-LiveKit integration test still reports "36 video frames,
323 audio frames, 10 state changes / 32 checks passed"; and the headless
libobs harness still logs "connected to ws://127.0.0.1:7880 ... watching
cam-test" followed by "video frame 640x360 I420" with the camera dropdown
populated from the live slot list.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 22:08:03 -07:00
shadowdaoandClaude Sonnet 5 8494485351 ci: build the real OBS adapter on all three platforms
Build / macOS (macos-latest) (push) Failing after 12s
Build / Linux (ubuntu-latest) (push) Failing after 34s
Build / Windows (windows-latest) (push) Failing after 8m13s
Two things: unbreak the Windows compile, and give macOS/Windows a libobs.

MSVC fix. test_json.cpp failed to compile on the Windows runner with
"a universal-character-name specifies an invalid character" and "illegal
escape sequence" -- MSVC still forms escape sequences and
universal-character-names INSIDE raw string literals, which it must not.
Every JSON input containing a backslash is now built by string concatenation
from a single kBS constant, which also sidesteps the separate murky corner of
translation phase 1 where a doubled backslash immediately followed by 'u' has
historically been treated inconsistently. Same 158 checks, no behaviour
change.

OBS SDK bootstrap for macOS/Windows. Adopts obsproject/obs-plugintemplate's
buildspec machinery -- buildspec.json plus cmake/common/buildspec_common.cmake
and cmake/{macos,windows}/buildspec.cmake -- so those two platforms get a real
libobs and build the actual plugin module instead of only the core library.
Linux is untouched and still uses Ubuntu's libobs-dev
(-DSTPLUGIN_BOOTSTRAP_OBS=OFF); the bootstrap only runs where there is no
system package.

Trimmed against upstream, each change recorded in the file that makes it:

 - qt6 is dropped from dependencies_list on both platforms. The properties UI
   is plain obs_properties_* and nothing here links Qt.
 - The OBS sub-build builds and installs the `libobs` target, not
   `obs-frontend-api`. Building the frontend API is what would drag Qt back in,
   and this plugin never calls it.
 - The sub-build is configured with ENABLE_UI=OFF and ENABLE_SCRIPTING=OFF as
   well as upstream's ENABLE_FRONTEND=OFF: the pinned OBS predates
   ENABLE_FRONTEND and gates its Qt-dependent UI on ENABLE_UI, so without this
   it configures the whole OBS UI and demands Qt anyway.
 - Only the Release configuration is built and installed, not Debug as well.
   Nothing consumes a debug libobs and it doubles the slowest CI step.
 - Only the dependency-acquisition modules are vendored. The template's
   compilerconfig/defaults/helpers/xcode modules drive its own target and
   bundle layout, which this project does not use.

obs-studio is pinned to 30.0.2, deliberately low: OBS refuses to load a module
built against a NEWER libobs than the one running it and accepts older ones, so
this pin IS the minimum OBS version users need. 30.0.2 is also exactly what
Ubuntu 24.04's libobs-dev ships, which puts all three platforms on one floor,
and it supports the modern CMake layout the bootstrap drives via
-DOBS_CMAKE_VERSION=3.0.0. prebuilt is obs-deps 2023-11-03 with the hashes
obs-studio 30.0.2's own buildspec.json publishes; the obs-studio source
archive hashes were computed from the GitHub tag archives.

The workflow also prints what was actually produced on each platform (ldd /
otool / dir over build/package) and uploads it as an artifact, so "does this
even link against libobs" is answered by CI output rather than assumed.

Verified locally: the Linux path is unchanged by all of this -- a fresh
configure still finds libobs-dev, and ctest is 6/6. The macOS and Windows
bootstrap can only be verified by CI; that is what this push is for.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 22:02:17 -07:00
shadowdaoandClaude Sonnet 5 304bc3ceba ci: install cmake on the Windows runner before configuring
Build / macOS (macos-latest) (push) Successful in 4s
Build / Linux (ubuntu-latest) (push) Successful in 28s
Build / Windows (windows-latest) (push) Successful in 8m0s
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
2026-09-06 20:47:31 -07:00
shadowdaoandClaude Sonnet 5 105f1041ab Scaffold core/OBS-adapter split, prove CMake toolchain, add 3-platform CI
Build / Windows (windows-latest) (push) Failing after 10s
Build / macOS (macos-latest) (push) Successful in 20s
Build / Linux (ubuntu-latest) (push) Successful in 31s
First pass on the streamer-tools OBS camera plugin: a minimal but real
CMake project matching the design doc's core-library/OBS-adapter split
(docs/superpowers/specs/2026-09-06-obs-camera-plugin-design.md in the
streamer-tools repo). No LiveKit FFI integration yet -- this proves the
toolchain works.

- core/: dependency-free C++17 library (no OBS dependency), unit tested
  via CTest with no external test framework.
- obs-adapter/: adapted from obsproject/obs-plugintemplate (commit
  3e7d7ac, 2025-12-09). Registers a real, stubbed OBS source type;
  builds as a genuine dynamically-linked OBS module against Ubuntu's
  system libobs-dev (confirmed via ldd/nm, not a fake stand-in).
- Simpler hand-written top-level CMakeLists.txt in place of the
  template's full buildspec-driven bootstrap (which downloads full OBS
  source + prebuilt deps) -- find_package(libobs) alone is enough on
  Linux; falls back to core-library-only when libobs isn't found
  (expected on macOS/Windows CI for now).
- .gitea/workflows/build.yml: 3-platform matrix (ubuntu-latest,
  macos-latest, windows-latest) matching the runners confirmed
  available to this repo under the CyberCoveLLC org.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE
2026-09-06 20:46:08 -07:00