Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d9f73926e4 | ||
|
|
ee44fb6a73 | ||
|
|
abd4dc9aca | ||
|
|
1571d7ecea | ||
|
|
bfc38f45ca |
@@ -1,9 +1,15 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
# Creates a (draft) Gitea Release for the tag that triggered
|
# Creates a published Gitea Release for the tag that triggered
|
||||||
# .gitea/workflows/release.yml, and uploads every archive in $DIST_DIR as a
|
# .gitea/workflows/release.yml, and uploads every archive in $DIST_DIR as a
|
||||||
# release asset. Draft because nobody has run this plugin in the OBS GUI on
|
# release asset.
|
||||||
# any platform yet -- a human still opens it and clicks Publish once that's
|
#
|
||||||
# no longer true (or once they're satisfied regardless).
|
# This used to create a DRAFT, on the grounds that nobody had run the plugin
|
||||||
|
# in the OBS GUI on any platform. That stopped being true on 2026-09-09, when
|
||||||
|
# the v0.1.0 Windows artifact loaded into OBS 32.2.2 on Windows 11 -- so the
|
||||||
|
# release publishes directly and the per-platform table below carries the
|
||||||
|
# remaining caveats instead. Assets upload AFTER the release row is created
|
||||||
|
# either way, so a release is briefly visible with no files attached; that is
|
||||||
|
# the tradeoff for not needing a human click.
|
||||||
#
|
#
|
||||||
# Required env: GITEA_TOKEN, SERVER, OWNER, REPO, TAG, SHA, DIST_DIR
|
# Required env: GITEA_TOKEN, SERVER, OWNER, REPO, TAG, SHA, DIST_DIR
|
||||||
# Optional env: MACOS_BUNDLE_FOUND ("true"/"false", default "false")
|
# Optional env: MACOS_BUNDLE_FOUND ("true"/"false", default "false")
|
||||||
@@ -30,26 +36,44 @@ cat > "${NOTES_FILE}" <<EOF
|
|||||||
|
|
||||||
Built from commit \`${SHA}\`.
|
Built from commit \`${SHA}\`.
|
||||||
|
|
||||||
**Nobody has yet run this plugin in the OBS GUI, on any platform.** See "What
|
**Read the per-platform notes below before relying on this.** The module has
|
||||||
is verified, and how" in \`README.md\` for exactly what has and has not been
|
been loaded in the OBS GUI exactly once -- Windows, OBS 32.2.2 on Windows 11,
|
||||||
checked, including which claims are backed by automated tests versus a human
|
2026-09-09 -- and only "it loads and registers its source type" is confirmed
|
||||||
watching OBS. This is why the release is a draft -- open it and click Publish
|
there. Whether video renders correctly, A/V sync, end-to-end latency and
|
||||||
once you're satisfied.
|
mid-show publisher restart are all still unverified on every platform. See
|
||||||
|
"What is verified, and how" in \`README.md\` for exactly what is backed by
|
||||||
|
automated tests versus a human watching OBS.
|
||||||
|
|
||||||
| Platform | Archive | Notes |
|
| 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 |
|
| 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 |
|
| Windows (x64) | \`streamer-tools-camera-${TAG}-windows-x64.zip\` | Built and tested by this workflow's Windows job. Confirmed to load in the OBS GUI (32.2.2 / Windows 11, 2026-09-09); nothing past module load is verified. 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} |
|
| macOS | \`streamer-tools-camera-${TAG}-macos.zip\` | Built and tested by this workflow's macOS job. ${MACOS_NOTE} |
|
||||||
|
|
||||||
## Installing
|
## Installing
|
||||||
|
|
||||||
Extract the archive into your OBS plugins folder for your platform (the
|
Extract the archive into your OBS plugins folder. **The directory is not the
|
||||||
default locations are easy to find online -- typically
|
same shape on every platform, and picking the wrong one fails silently -- OBS
|
||||||
\`~/.config/obs-studio/plugins/\` on Linux, \`%APPDATA%\\obs-studio\\plugins\\\`
|
logs nothing at all for a plugin it never finds:**
|
||||||
on Windows, \`~/Library/Application Support/obs-studio/plugins/\` on macOS).
|
|
||||||
Each archive's top-level folder already matches the shape OBS expects there,
|
| Platform | Extract into |
|
||||||
so extracting is the whole install step. Then in OBS: Sources -> \`+\` ->
|
|---|---|
|
||||||
|
| Windows | \`C:\\ProgramData\\obs-studio\\plugins\\\` -- **not** \`%APPDATA%\\obs-studio\\\`, which is where OBS keeps its config and is never scanned for plugins |
|
||||||
|
| macOS | \`~/Library/Application Support/obs-studio/plugins/\` |
|
||||||
|
| Linux | \`~/.config/obs-studio/plugins/\` |
|
||||||
|
|
||||||
|
Each archive's top-level folder already matches the shape OBS expects, so
|
||||||
|
extracting is the whole install step -- but check the result is exactly one
|
||||||
|
folder deep. Windows Explorer's "Extract All..." adds a folder named after the
|
||||||
|
zip unless you clear it from the destination box, which nests it one level too
|
||||||
|
far and is equally silent. On Windows the finished path must be:
|
||||||
|
|
||||||
|
\`\`\`
|
||||||
|
C:\\ProgramData\\obs-studio\\plugins\\streamer-tools-camera\\bin\\64bit\\streamer-tools-camera.dll
|
||||||
|
\`\`\`
|
||||||
|
|
||||||
|
To confirm it loaded, restart OBS and check Help -> Log Files -> View Current
|
||||||
|
Log for \`streamer-tools-camera\` under "Loaded Modules". Then in OBS: Sources -> \`+\` ->
|
||||||
"streamer-tools Camera" -> fill in the server URL, room slug and read key
|
"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.
|
from the room's settings page -> "Refresh camera list" -> pick a camera.
|
||||||
|
|
||||||
@@ -73,7 +97,7 @@ print(json.dumps({
|
|||||||
"tag_name": tag,
|
"tag_name": tag,
|
||||||
"name": tag,
|
"name": tag,
|
||||||
"body": notes,
|
"body": notes,
|
||||||
"draft": True,
|
"draft": False,
|
||||||
"prerelease": False,
|
"prerelease": False,
|
||||||
}))
|
}))
|
||||||
PYEOF
|
PYEOF
|
||||||
@@ -87,7 +111,7 @@ RESP="$(curl -sS -f -X POST \
|
|||||||
"${SERVER}/api/v1/repos/${OWNER}/${REPO}/releases")"
|
"${SERVER}/api/v1/repos/${OWNER}/${REPO}/releases")"
|
||||||
|
|
||||||
RELEASE_ID="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"${RESP}")"
|
RELEASE_ID="$(python3 -c 'import json,sys; print(json.load(sys.stdin)["id"])' <<<"${RESP}")"
|
||||||
echo "Created release id ${RELEASE_ID} (draft)."
|
echo "Created release id ${RELEASE_ID} (published; assets upload next)."
|
||||||
|
|
||||||
shopt -s nullglob
|
shopt -s nullglob
|
||||||
ASSETS=("${DIST_DIR}"/*)
|
ASSETS=("${DIST_DIR}"/*)
|
||||||
@@ -106,4 +130,4 @@ for f in "${ASSETS[@]}"; do
|
|||||||
> /dev/null
|
> /dev/null
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Done. Draft release: ${SERVER}/${OWNER}/${REPO}/releases/${RELEASE_ID}"
|
echo "Done. Release: ${SERVER}/${OWNER}/${REPO}/releases/${RELEASE_ID}"
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
name: Release
|
name: Release
|
||||||
|
|
||||||
# Packages a build of each platform into a downloadable archive and creates
|
# Packages a build of each platform into a downloadable archive and creates
|
||||||
# a (draft) Gitea Release for it, so the project owner and other directors
|
# a published Gitea Release for it, so the project owner and other directors
|
||||||
# can grab a ready-to-use build instead of compiling from source.
|
# can grab a ready-to-use build instead of compiling from source.
|
||||||
#
|
#
|
||||||
# Runs only on a pushed version tag (see `on.push.tags` below) -- never on an
|
# 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:
|
# ordinary push or PR, unlike build.yml. The release it creates is PUBLISHED
|
||||||
# it stays invisible to anyone without write access until a human explicitly
|
# immediately. It used to be a draft, gated on a human clicking Publish
|
||||||
# opens it and clicks Publish, since nobody has run this plugin in the OBS
|
# because nobody had run the plugin in the OBS GUI on any platform; the first
|
||||||
# GUI on any platform yet.
|
# confirmed GUI load (Windows, 2026-09-09) retired that. The caveats that
|
||||||
|
# remain live in the generated release notes, not in the draft flag -- see
|
||||||
|
# .gitea/scripts/publish-release.sh.
|
||||||
#
|
#
|
||||||
# The actual per-platform build commands live in .gitea/scripts/ and are the
|
# 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
|
# same scripts .gitea/workflows/build.yml uses, so this workflow can't drift
|
||||||
@@ -183,7 +185,7 @@ jobs:
|
|||||||
path: dist
|
path: dist
|
||||||
|
|
||||||
release:
|
release:
|
||||||
name: Create Gitea Release (draft)
|
name: Create Gitea Release
|
||||||
needs: [linux, macos, windows]
|
needs: [linux, macos, windows]
|
||||||
runs-on: ubuntu-24.04
|
runs-on: ubuntu-24.04
|
||||||
permissions:
|
permissions:
|
||||||
@@ -214,7 +216,7 @@ jobs:
|
|||||||
name: release-archive-windows-x64
|
name: release-archive-windows-x64
|
||||||
path: dist
|
path: dist
|
||||||
|
|
||||||
- name: Create draft release and upload assets
|
- name: Create release and upload assets
|
||||||
run: .gitea/scripts/publish-release.sh
|
run: .gitea/scripts/publish-release.sh
|
||||||
env:
|
env:
|
||||||
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
|
||||||
|
|||||||
@@ -14,18 +14,32 @@ match the vendored LiveKit binaries, which are also Apache-2.0 — see
|
|||||||
|
|
||||||
`.gitea/workflows/build.yml` builds, tests, and uploads CI-internal build
|
`.gitea/workflows/build.yml` builds, tests, and uploads CI-internal build
|
||||||
artifacts on every push. `.gitea/workflows/release.yml` packages a tagged
|
artifacts on every push. `.gitea/workflows/release.yml` packages a tagged
|
||||||
build (`v*`) into a **draft** Gitea Release — draft because nobody has run
|
build (`v*`) into a **published** Gitea Release. It created drafts until
|
||||||
this in the OBS GUI yet (see below), not because of anything else; a human
|
2026-09-09, gated on a human clicking Publish because nobody had run the
|
||||||
still needs to open it and click Publish.
|
plugin in the OBS GUI; the first confirmed GUI load retired that gate, and the
|
||||||
|
remaining caveats live in the generated release notes instead.
|
||||||
|
|
||||||
The plugin is **functionally complete on Linux and verified end to end there**
|
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
|
(module loads into real libobs, connects to a real LiveKit server through the
|
||||||
real streamer-tools API shape, and pushes decoded frames into
|
real streamer-tools API shape, and pushes decoded frames into
|
||||||
`obs_source_output_video`/`_audio`).
|
`obs_source_output_video`/`_audio`).
|
||||||
|
|
||||||
It has **not been run in the OBS GUI on any platform.** macOS builds the real
|
**First confirmed OBS GUI load: Windows, 2026-09-09** — the v0.1.0 release
|
||||||
module in CI but its artifact is not yet loadable (see the macOS packaging gap
|
artifact loaded into OBS 32.2.2 on Windows 11 (build 26200) on a director's
|
||||||
under CI).
|
machine, from
|
||||||
|
`C:\ProgramData\obs-studio\plugins\streamer-tools-camera\bin\64bit\`.
|
||||||
|
That retires "the module will not even load in a real OBS" for Windows. It
|
||||||
|
does **not** yet cover whether video renders correctly, colours, A/V sync or
|
||||||
|
latency — see "Not verified anywhere" below for what is still open. Linux and
|
||||||
|
macOS have still never been opened in the GUI; macOS builds the real module in
|
||||||
|
CI but its artifact is not yet loadable (see the macOS packaging gap under CI).
|
||||||
|
|
||||||
|
⚠️ **The install directory is not the same on every platform, and getting it
|
||||||
|
wrong fails silently.** On Windows it is
|
||||||
|
`C:\ProgramData\obs-studio\plugins\` (`GetProgramDataPath` →
|
||||||
|
`CSIDL_COMMON_APPDATA`), **not** `%APPDATA%\obs-studio\` — see the packaging
|
||||||
|
section. That mistake cost the director above an evening: OBS logs nothing at
|
||||||
|
all for a plugin it never finds.
|
||||||
|
|
||||||
**Windows CI is now green.** The run at `f27b1c0` is the first completed
|
**Windows CI is now green.** The run at `f27b1c0` is the first completed
|
||||||
green Windows job on this repository: the from-source libobs bootstrap
|
green Windows job on this repository: the from-source libobs bootstrap
|
||||||
@@ -35,8 +49,8 @@ suites pass, and `build\package\bin\64bit\streamer-tools-camera.dll`
|
|||||||
out of the job's own log body, not inferred from the job status. That also
|
out of the job's own log body, not inferred from the job status. That also
|
||||||
retires three previously-unproven items in one go: the `-A x64` argument fix,
|
retires three previously-unproven items in one go: the `-A x64` argument fix,
|
||||||
the PowerShell rewrite of the Windows steps, and the `add_subdirectory`
|
the PowerShell rewrite of the Windows steps, and the `add_subdirectory`
|
||||||
patch for `OBS::w32-pthreads`. Windows is still **unverified in the OBS GUI**,
|
patch for `OBS::w32-pthreads`. Windows has since been **loaded in the real OBS
|
||||||
exactly like the other two platforms. See "Where the Windows bootstrap got
|
GUI** (see above); Linux and macOS have not. See "Where the Windows bootstrap got
|
||||||
to" under CI below for the whole trace, and check current CI status rather
|
to" under CI below for the whole trace, and check current CI status rather
|
||||||
than trusting this paragraph's age.
|
than trusting this paragraph's age.
|
||||||
|
|
||||||
@@ -66,7 +80,7 @@ scripts/livekit-dev-room.py - mints tokens for the integration test
|
|||||||
third_party/livekit/ - redistribution notices for the LiveKit binaries
|
third_party/livekit/ - redistribution notices for the LiveKit binaries
|
||||||
.gitea/scripts/ - the actual per-platform build commands, shared by build.yml and release.yml
|
.gitea/scripts/ - the actual per-platform build commands, shared by build.yml and release.yml
|
||||||
.gitea/workflows/build.yml - 3-platform CI matrix (every push/PR; never publishes)
|
.gitea/workflows/build.yml - 3-platform CI matrix (every push/PR; never publishes)
|
||||||
.gitea/workflows/release.yml - packages + creates a draft Gitea Release (only on a `v*` tag push; see Status above)
|
.gitea/workflows/release.yml - packages + publishes a Gitea Release (only on a `v*` tag push; see Status above)
|
||||||
```
|
```
|
||||||
|
|
||||||
## How it works
|
## How it works
|
||||||
@@ -142,17 +156,28 @@ build/package/licenses/...
|
|||||||
```
|
```
|
||||||
|
|
||||||
That is exactly the layout OBS searches on Linux and Windows —
|
That is exactly the layout OBS searches on Linux and Windows —
|
||||||
`<config>/obs-studio/plugins/<name>/bin/64bit` plus a sibling `data/`, per
|
`<base>/obs-studio/plugins/<name>/bin/64bit` plus a sibling `data/`, per
|
||||||
`AddExtraModulePaths()` in obs-studio's `UI/window-basic-main.cpp` — so
|
`AddExtraModulePaths()` in obs-studio (`UI/window-basic-main.cpp` in 30.x,
|
||||||
`build/package/` is a straight drop-in. The module resolves the LiveKit
|
`frontend/widgets/OBSBasic.cpp` in 32.x) — so `build/package/` is a straight
|
||||||
libraries from `$ORIGIN` (verified: `ldd` on the staged copy resolves both
|
drop-in. **`<base>` is NOT the same directory on every platform**, and getting
|
||||||
|
this wrong is silent: OBS logs nothing at all for a plugin it never finds.
|
||||||
|
Linux uses the user config dir (`GetAppConfigPath` → `~/.config`), but Windows
|
||||||
|
uses `GetProgramDataPath` (`CSIDL_COMMON_APPDATA`) — i.e.
|
||||||
|
`C:\ProgramData\obs-studio\plugins\`, **not** `%APPDATA%\obs-studio\`
|
||||||
|
(`CSIDL_APPDATA`), which on Windows holds OBS's config and is never scanned for
|
||||||
|
plugins. This bit a director on 2026-09-09: a correctly-shaped install under
|
||||||
|
`AppData\Roaming` produced a log with zero mention of the module.
|
||||||
|
|
||||||
|
The module resolves the LiveKit libraries from `$ORIGIN` (verified: `ldd` on the staged copy resolves both
|
||||||
to `bin/64bit/`), not from the build tree. macOS is not this shape; see the
|
to `bin/64bit/`), not from the build tree. macOS is not this shape; see the
|
||||||
macOS packaging gap under CI.
|
macOS packaging gap under CI.
|
||||||
|
|
||||||
## Testing this by hand
|
## Testing this by hand
|
||||||
|
|
||||||
**Nobody has yet run this in the OBS GUI. That test is still outstanding on
|
**The module has been loaded in the OBS GUI on Windows once (2026-09-09, OBS
|
||||||
all three platforms.** To do it on Linux:
|
32.2.2 / Windows 11 26200) — nothing beyond "it loads and registers its source"
|
||||||
|
is confirmed there, and Linux and macOS have never been opened in the GUI at
|
||||||
|
all.** To do it on Linux:
|
||||||
|
|
||||||
```
|
```
|
||||||
mkdir -p ~/.config/obs-studio/plugins/streamer-tools-camera
|
mkdir -p ~/.config/obs-studio/plugins/streamer-tools-camera
|
||||||
@@ -208,7 +233,11 @@ livekit-server 1.13.6 in dev mode):
|
|||||||
| Two sources in one OBS process | same harness with a second source added: both connect with distinct nonce identities, both receive frames, both tear down cleanly |
|
| Two sources in one OBS process | same harness with a second source added: both connect with distinct nonce identities, both receive frames, both tear down cleanly |
|
||||||
|
|
||||||
**Not verified anywhere:**
|
**Not verified anywhere:**
|
||||||
- The OBS GUI, on any platform. No human has looked at this in OBS.
|
- Anything past module load in the OBS GUI. Windows 2026-09-09 confirms the
|
||||||
|
module loads and its source type appears; whether video actually renders
|
||||||
|
(right way up, right colours), what the A/V sync and latency look like, and
|
||||||
|
whether a publisher restarting mid-show recovers on screen are all still
|
||||||
|
unanswered. Linux and macOS have not been opened in the GUI at all.
|
||||||
- macOS beyond "CI builds and links the real module and the core tests pass".
|
- macOS beyond "CI builds and links the real module and the core tests pass".
|
||||||
Its artifact is a bare `.so` with a relative libobs install name and will
|
Its artifact is a bare `.so` with a relative libobs install name and will
|
||||||
not load in OBS.app — see the macOS packaging gap under CI.
|
not load in OBS.app — see the macOS packaging gap under CI.
|
||||||
|
|||||||
Reference in New Issue
Block a user