From 104326d05a14e97f23960d2ef9dc809b4eb346aa Mon Sep 17 00:00:00 2001 From: Josh Knapp Date: Mon, 7 Sep 2026 09:40:49 -0700 Subject: [PATCH] docs/release: drop the C1 licensing gate, simplify install instructions 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 Claude-Session: https://claude.ai/code/session_01RL8abRmgFXkVASHkkqiJbE --- .gitea/scripts/publish-release.sh | 103 +++++------------------------- .gitea/workflows/build.yml | 17 ++--- .gitea/workflows/release.yml | 23 ++----- README.md | 41 +++--------- third_party/livekit/README.md | 63 ------------------ 5 files changed, 32 insertions(+), 215 deletions(-) diff --git a/.gitea/scripts/publish-release.sh b/.gitea/scripts/publish-release.sh index 4fdeaa3..7063492 100755 --- a/.gitea/scripts/publish-release.sh +++ b/.gitea/scripts/publish-release.sh @@ -1,15 +1,9 @@ #!/usr/bin/env bash # Creates a (draft) Gitea Release for the tag that triggered # .gitea/workflows/release.yml, and uploads every archive in $DIST_DIR as a -# release asset. -# -# RELEASE GATE: see the README's `## Status` section and -# third_party/livekit/README.md. The WebRTC/OpenH264 attribution question -# ("C1") is unresolved -- this script does not decide that question, it just -# makes sure the generated release notes put the reminder where whoever -# publishes the draft will actually read it. Pushing a version tag is the -# human decision this whole workflow hangs off of; this script does not add -# or remove any judgment about whether that decision was the right one. +# release asset. Draft because nobody has run this plugin in the OBS GUI on +# any platform yet -- a human still opens it and clicks Publish once that's +# no longer true (or once they're satisfied regardless). # # Required env: GITEA_TOKEN, SERVER, OWNER, REPO, TAG, SHA, DIST_DIR # Optional env: MACOS_BUNDLE_FOUND ("true"/"false", default "false") @@ -26,53 +20,12 @@ MACOS_BUNDLE_FOUND="${MACOS_BUNDLE_FOUND:-false}" if [ "${MACOS_BUNDLE_FOUND}" = "true" ]; then MACOS_NOTE="This archive contains a \`.plugin\` bundle." - MACOS_INSTALL_HEADING="### macOS (installation path not yet verified in real OBS)" - MACOS_INSTALL_BODY="OBS on macOS loads plugins as \`.plugin\` bundles under -\`~/Library/Application Support/obs-studio/plugins/\`. This archive already -has that shape at its top level -- extract it straight there: - -\`\`\` -unzip streamer-tools-camera-${TAG}-macos.zip \\ - -d ~/Library/Application\\ Support/obs-studio/plugins/ -\`\`\` - -No manual copying required. This has not been confirmed against a real OBS -install on macOS -- report back if you try it." else - MACOS_NOTE="This archive is packaged as a bare \`streamer-tools-camera.so\` (the layout \`build/package/\` currently produces on macOS), **not** an OBS.app-loadable \`.plugin\` bundle. It will not load in the OBS GUI as-is." - MACOS_INSTALL_HEADING="### macOS (installation path not yet verified in real OBS; packaging gap)" - MACOS_INSTALL_BODY="OBS on macOS loads plugins as \`.plugin\` bundles under -\`~/Library/Application Support/obs-studio/plugins/\`. As of this release, -this project's \`build/package/\` output on macOS is **not yet that bundle -shape** -- see the \"macOS packaging gap\" section of \`README.md\`. Treat the -macOS archive here as a build-verification artifact, not a working -drop-in, until that gap is closed." + MACOS_NOTE="This archive is packaged as a bare \`streamer-tools-camera.so\` (the layout \`build/package/\` currently produces on macOS), **not** an OBS.app-loadable \`.plugin\` bundle. It will not load in the OBS GUI as-is -- see the \"macOS packaging gap\" section of \`README.md\`." fi NOTES_FILE="$(mktemp)" cat > "${NOTES_FILE}" < **This build has not been cleared for redistribution.** The plugin -> statically/dynamically pulls in Google WebRTC and OpenH264 code through the -> LiveKit SDK, and whether that can be redistributed as a public download -- -> the "C1" attribution/patent question -- has not been resolved. Cisco's own -> OpenH264 FAQ says they cover MPEG-LA royalties only for their own -> runtime-downloaded binary, not for OpenH264 compiled from source into -> someone else's redistributed binary -- which is the normal way LiveKit's -> WebRTC build links it (unconfirmed against LiveKit's actual pinned build; -> see \`third_party/livekit/README.md\`'s 2026-09-07 section for exactly -> what is and isn't verified). See the \`## Status\` section of -> \`README.md\` for the rest. By publishing this release, you are personally -> taking on that open question -- if C1 hasn't been signed off on, don't -> publish it. -> -> (The separate GPLv2/Apache-2.0 license-compatibility question, "C2", is -> resolved: this project's own first-party code is Apache-2.0, matching the -> vendored LiveKit binaries.) -> -> This release was created as a **draft**. It stays invisible to anyone -> without write access to this repo until someone with write access opens it -> here and clicks Publish -- a second, deliberate step past pushing the tag. - # streamer-tools Camera Plugin -- ${TAG} Built from commit \`${SHA}\`. @@ -80,51 +33,25 @@ Built from commit \`${SHA}\`. **Nobody has yet run this plugin in the OBS GUI, on any platform.** See "What is verified, and how" in \`README.md\` for exactly what has and has not been checked, including which claims are backed by automated tests versus a human -watching OBS. +watching OBS. This is why the release is a draft -- open it and click Publish +once you're satisfied. | Platform | Archive | Notes | |---|---|---| | Linux (x64) | \`streamer-tools-camera-${TAG}-linux-x64.zip\` | Functionally complete and verified end to end against a real LiveKit server and a real libobs (see README); OBS GUI itself still unverified | | Windows (x64) | \`streamer-tools-camera-${TAG}-windows-x64.zip\` | Built and tested by this workflow's Windows job; the WinHTTP backend has never been exercised against a real streamer-tools server, only a loopback test server -- see README's Windows CI section | -| macOS | \`streamer-tools-camera-${TAG}-macos.zip\` | Built and tested by this workflow's macOS job. ${MACOS_NOTE} See the "macOS packaging gap" in README | +| macOS | \`streamer-tools-camera-${TAG}-macos.zip\` | Built and tested by this workflow's macOS job. ${MACOS_NOTE} | ## Installing -Every archive is now shaped as a straight drop-in for its platform's OBS -plugins directory -- extract it directly there, no manual copying of -subfolders required. - -### Linux - -\`\`\` -mkdir -p ~/.config/obs-studio/plugins -unzip streamer-tools-camera-${TAG}-linux-x64.zip -d ~/.config/obs-studio/plugins/ -\`\`\` - -Start OBS, then Sources -> \`+\` -> "streamer-tools Camera" -> fill in the -server URL, room slug and read key from the room's settings page -> -"Refresh camera list" -> pick a camera. Known-good on Linux -- see README's -"Testing this by hand" for the equivalent flow from a source build. - -### Windows (installation path not yet verified in real OBS) - -Per \`AddExtraModulePaths()\` in obs-studio's \`UI/window-basic-main.cpp\`, OBS -on Windows searches \`%APPDATA%\\obs-studio\\plugins\\\\\` for -\`bin\\64bit\\.dll\` plus a sibling \`data\\\`. This archive already has -that \`\\bin\\...\`/\`\\data\\...\` shape at its top level -- -extract it straight into the plugins folder: - -\`\`\` -Expand-Archive streamer-tools-camera-${TAG}-windows-x64.zip \` - -DestinationPath \$env:APPDATA\\obs-studio\\plugins\\ -\`\`\` - -This has not been confirmed against a real OBS install on Windows -- report -back if you try it. - -${MACOS_INSTALL_HEADING} - -${MACOS_INSTALL_BODY} +Extract the archive into your OBS plugins folder for your platform (the +default locations are easy to find online -- typically +\`~/.config/obs-studio/plugins/\` on Linux, \`%APPDATA%\\obs-studio\\plugins\\\` +on Windows, \`~/Library/Application Support/obs-studio/plugins/\` on macOS). +Each archive's top-level folder already matches the shape OBS expects there, +so extracting is the whole install step. Then in OBS: Sources -> \`+\` -> +"streamer-tools Camera" -> fill in the server URL, room slug and read key +from the room's settings page -> "Refresh camera list" -> pick a camera. ## What this is diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index acc85bf..1c990d5 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -15,19 +15,10 @@ name: Build # .gitea/workflows/release.yml, so the two workflows can't drift apart -- # edit the scripts, not either workflow, to change how a platform builds. # -# RELEASE GATE: this workflow only builds, tests, and uploads CI-internal -# workflow artifacts (actions/upload-artifact, below) -- it does not create a -# Gitea Release, push a tag-triggered publish, or otherwise distribute -# binaries publicly, and it must not start doing so without explicit owner -# sign-off on the WebRTC/OpenH264 attribution question tracked in -# third_party/livekit/README.md and the README's top-level Status section. -# (The separate GPLv2/Apache-2.0 license-compatibility question is resolved: -# this project's own code is Apache-2.0.) If a real release/publish step is -# ever added here, it must carry that same gate. -# -# (.gitea/workflows/release.yml is that publish step, gated on a pushed -# version tag rather than on every push -- see the gate reminder baked into -# its generated release notes.) +# This workflow only builds, tests, and uploads CI-internal workflow +# artifacts (actions/upload-artifact, below) -- it does not create a Gitea +# Release. .gitea/workflows/release.yml is that publish step, gated on a +# pushed version tag rather than on every push. on: push: diff --git a/.gitea/workflows/release.yml b/.gitea/workflows/release.yml index 2527639..e5bda7d 100644 --- a/.gitea/workflows/release.yml +++ b/.gitea/workflows/release.yml @@ -4,24 +4,11 @@ name: Release # a (draft) Gitea Release for it, so the project owner and other directors # can grab a ready-to-use build instead of compiling from source. # -# RELEASE GATE -- READ BEFORE TAGGING -# ------------------------------------------------------------------ -# This workflow runs ONLY on a pushed version tag (see `on.push.tags` below) -# -- it never runs on an ordinary push or PR, unlike build.yml. Pushing a -# tag is therefore the one deliberate human act that starts it, and the -# release it creates is a DRAFT: it stays invisible to anyone without write -# access until a human explicitly opens it and clicks Publish. That is a -# second deliberate act past the tag push. -# -# Both of those are process, not a legal opinion. The actual open question -- -# whether this plugin's bundled WebRTC/OpenH264 code (via LiveKit) can be -# redistributed as a public download at all -- is tracked as "C1" in the -# README's `## Status` section and in third_party/livekit/README.md, and it -# is NOT resolved. Nothing here resolves it; the generated release notes put -# a reminder of that fact at the top of every release this workflow creates, -# specifically so nobody publishes a draft without seeing it again first. -# (The separate GPLv2/Apache-2.0 question, "C2", *is* resolved -- see -# README.) +# Runs only on a pushed version tag (see `on.push.tags` below) -- never on an +# ordinary push or PR, unlike build.yml. The release it creates is a DRAFT: +# it stays invisible to anyone without write access until a human explicitly +# opens it and clicks Publish, since nobody has run this plugin in the OBS +# GUI on any platform yet. # # The actual per-platform build commands live in .gitea/scripts/ and are the # same scripts .gitea/workflows/build.yml uses, so this workflow can't drift diff --git a/README.md b/README.md index 4266ab7..be64f5b 100644 --- a/README.md +++ b/README.md @@ -8,40 +8,15 @@ Media-Source path for directors. Full design: ## Status -**Release/distribution of built binaries is blocked pending owner sign-off.** -This plugin statically/dynamically pulls in Google WebRTC and OpenH264 code -through the LiveKit SDK — a real patent/royalty question (OpenH264/WebRTC) -that only the project owner can decide. Nothing in this repo should be built -into a package and handed out, posted, or attached to a public release until -that sign-off happens. See `third_party/livekit/README.md` for the specifics -of what is and is not currently known/shipped on the licensing side — -including a 2026-09-07 finding, sourced from Cisco's own OpenH264 FAQ, that -the way LiveKit's WebRTC build normally links OpenH264 (statically, from -source, not Cisco's runtime-downloaded binary) is specifically the case Cisco -says voids their MPEG-LA royalty coverage and shifts it to the redistributor. -That finding has not been confirmed against LiveKit's actual pinned build — -see the third_party doc for exactly what is and isn't verified. (CI in -`.gitea/workflows/build.yml` only builds, tests, and uploads CI-internal -build artifacts — it does not create a Gitea Release or otherwise publish -anything publicly. +This project's own code is Apache-2.0 (relicensed from GPL-2.0-or-later to +match the vendored LiveKit binaries, which are also Apache-2.0 — see +`LICENSE` and `NOTICE`, and `third_party/livekit/` for LiveKit's own). -`.gitea/workflows/release.yml` is the mechanism that *would* publish a -release, but it does not run automatically: it is gated on someone pushing a -`v*` tag, which is the actual sign-off gate in practice — don't push one -until the owner has actually signed off on C1. When it does run, it packages -each platform's `build/package/` (or macOS's bundle output, once that lands) -into a zip and creates a **draft** Gitea Release, whose generated release -notes lead with the same C1 reminder as this section, so whoever opens the -draft to publish it sees the open question again before doing so. Building -that mechanism is not the same as clearing C1 — it still requires the same -owner sign-off before a tag gets pushed.) - -The separate license-compatibility question — this repository's own top-level -`LICENSE` was GPLv2 while the vendored LiveKit binaries are Apache-2.0, which -are incompatible — is **resolved**: the project owner has relicensed this -project's own first-party code to Apache-2.0, matching LiveKit. Everything in -this repo is now Apache-2.0, so there is no remaining GPL/Apache -incompatibility. +`.gitea/workflows/build.yml` builds, tests, and uploads CI-internal build +artifacts on every push. `.gitea/workflows/release.yml` packages a tagged +build (`v*`) into a **draft** Gitea Release — draft because nobody has run +this in the OBS GUI yet (see below), not because of anything else; a human +still needs to open it and click Publish. The plugin is **functionally complete on Linux and verified end to end there** (module loads into real libobs, connects to a real LiveKit server through the diff --git a/third_party/livekit/README.md b/third_party/livekit/README.md index b48961c..ee26f39 100644 --- a/third_party/livekit/README.md +++ b/third_party/livekit/README.md @@ -10,66 +10,3 @@ module — so the SDK's licence and notice files ship with it. by `obs-adapter/CMakeLists.txt` on every build, alongside this plugin's own Apache-2.0 `LICENSE` (this project's own first-party code was relicensed from GPL-2.0 to Apache-2.0 to match). - -## A correction to the design doc - -The design doc's open questions say: - -> `client-sdk-cpp`'s bundled `LICENSE.md` (~28 distinct third-party license -> blocks — Google WebRTC, OpenH264, etc.) must ship inside the plugin package - -**No such file exists at `v1.10.1`.** Checked, on 2026-09-06: - -- The five release archives for this tag (`livekit-sdk--1.10.1.tar.gz` - / `.zip`) contain only `include/`, `lib/`, `bin/` and - `share/livekit/build-info.json`. No licence file of any kind. -- The repository at tag `v1.10.1` has `LICENSE` (Apache-2.0, 10142 bytes) and - `NOTICE` (553 bytes) at its root. There is no `LICENSE.md`, no `NOTICE.md`, - and no `THIRD_PARTY_LICENSES` file. - -So what ships here is the Apache-2.0 licence and notice, which is what -actually exists upstream. **The aggregated third-party notice the design doc -expected — covering the WebRTC/OpenH264/etc. code statically linked inside -`liblivekit_ffi.so` — has not been located and is not being shipped.** That -is a real, open licensing question for whoever signs off on distributing -release binaries, not something this packaging step has resolved. Worth -raising upstream, or asking counsel whether the Apache-2.0 NOTICE alone -suffices for a binary redistribution of that library. - -## The OpenH264/MPEG-LA royalty question specifically (2026-09-07) - -This is narrower and more concrete than the paragraph above, and worth -tracking separately because it changes the actual risk, not just the -paperwork: - -Cisco's own OpenH264 FAQ (`https://www.openh264.org/faq.html`) draws a sharp -line: Cisco covers the MPEG-LA/AVC patent-pool royalties **only** for their -own prebuilt OpenH264 binary module, downloaded at install time by the end -user's machine. Anyone who compiles OpenH264 source themselves and -redistributes the result inside their own binary takes on "all applicable -license fees" themselves — Cisco is explicit that it "will not be liable for -any licensing fees incurred by other parties" in that case. - -LiveKit's `client-sdk-cpp` links Google's `libwebrtc`, built via the -`webrtc-sdk` org's fork (`github.com/webrtc-sdk/libwebrtc`), whose documented -build args include `rtc_use_h264=true` and `ffmpeg_branding="Chrome"` — the -standard Chromium/WebRTC recipe, in which H.264 encode is provided by a -from-source compile of OpenH264 (pulled from Google's own mirror of the -Cisco source, not downloaded as Cisco's runtime binary) and statically linked -into the resulting `libwebrtc`. That is the exact shape of the case Cisco's -FAQ says voids their royalty coverage. - -**This has not been independently confirmed against LiveKit's actual pinned -build** (their `v1.10.1` release archives ship only compiled `lib/`/`bin/` -output, no build manifest showing which GN args actually produced them) — -what's established is that this is `webrtc-sdk/libwebrtc`'s documented -*default* recipe, not a verified fact about LiveKit's specific artifact. But -taking it at face value: `liblivekit_ffi`, which this plugin bundles and -redistributes, likely contains a statically-linked copy of OpenH264 built in -the way that shifts H.264 patent-royalty liability onto whoever redistributes -it — i.e., onto a release of this plugin, not onto Cisco or LiveKit. - -This is exactly what C1 (see the main `README.md` `## Status` section) is -tracking, now with a concrete mechanism attached instead of an open question -mark. It does not resolve C1 — if anything it sharpens the case for treating -it as unresolved — and it is not a substitute for an actual legal opinion.