From 4ea94107f91bf6f59106d1604a9d10dba51e649a Mon Sep 17 00:00:00 2001 From: OgBops Date: Sun, 17 May 2026 20:05:42 -0700 Subject: [PATCH 01/17] Brand fork as OBS Studio Plus, add roadmap - Rewrite README.rst to identify this as a fork of upstream OBS Studio, with attribution preserved and pointers to the upstream project for general OBS docs. - Add ROADMAP.md describing the three anchor features (multi-destination streaming, native multi-canvas UI, modern UI + AI plugin suite) and versioning targets. - Allow ROADMAP.md in the project's allowlist-style .gitignore. --- .gitignore | 1 + README.rst | 121 +++++++++++++++++++++++++++++---------------------- ROADMAP.md | 124 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 194 insertions(+), 52 deletions(-) create mode 100644 ROADMAP.md diff --git a/.gitignore b/.gitignore index e7c7cd4e4a20e9..9746eabd7cd08b 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,7 @@ !COPYING !INSTALL !README.rst +!ROADMAP.md # Exclude lock files *.lock.json diff --git a/README.rst b/README.rst index 67a4673ff48767..43be70a8a0792c 100644 --- a/README.rst +++ b/README.rst @@ -1,79 +1,96 @@ -OBS Studio -=================================== +OBS Studio Plus +=============== -.. image:: https://github.com/obsproject/obs-studio/actions/workflows/push.yaml/badge.svg?branch=master - :alt: OBS Studio Build Status - GitHub Actions - :target: https://github.com/obsproject/obs-studio/actions/workflows/push.yaml?query=branch%3Amaster +OBS Studio Plus is a community fork of `OBS Studio `_ +that aims to bring native multi-canvas streaming, first-class multi-destination +output, and a modern UI to the world's most popular live-streaming software. -.. image:: https://badges.crowdin.net/obs-studio/localized.svg - :alt: OBS Studio Translation Project Progress - :target: https://crowdin.com/project/obs-studio +This fork preserves full compatibility with upstream OBS plugins, scenes, and +profiles. Everything that works in OBS Studio works in OBS Studio Plus. -.. image:: https://img.shields.io/discord/348973006581923840.svg?label=&logo=discord&logoColor=ffffff&color=7389D8&labelColor=6A7EC2 - :alt: OBS Studio Discord Server - :target: https://obsproject.com/discord +Status +------ -What is OBS Studio? -------------------- +Early development. See `ROADMAP.md `_ for the planned feature set +and current progress. -OBS Studio is software designed for capturing, compositing, encoding, -recording, and streaming video content, efficiently. +What's different from upstream OBS? +----------------------------------- -It's distributed under the GNU General Public License v2 (or any later -version) - see the accompanying COPYING file for more details. +The upstream OBS Studio project has quietly built much of the infrastructure +needed for modern streaming workflows (multi-canvas, multi-output) but has not +yet surfaced these capabilities to users. OBS Studio Plus exposes them, plus +adds new capabilities on top: + +- **Native vertical + horizontal canvases** — stream 16:9 to Twitch and 9:16 + to TikTok / Shorts / Reels simultaneously, from a single OBS instance. +- **First-class multi-destination streaming** — push your stream to multiple + services at once with per-destination bitrate and resolution settings. +- **Modern UI shell** — refreshed theming, restructured panels, unified + Go-Live workflow. +- **Local-first AI features** — auto-framing, live captions, and improved + noise suppression as opt-in plugins. No cloud dependencies for core features. + +License +------- + +OBS Studio Plus is distributed under the GNU General Public License v2 (or any +later version), the same license as upstream OBS Studio. See the accompanying +``COPYING`` file for details. Quick Links ----------- -- Website: https://obsproject.com +- This fork's repository: https://github.com/OgBops/obs-studio-plus + +- Upstream OBS Studio: https://github.com/obsproject/obs-studio + +- Upstream OBS website: https://obsproject.com -- Help/Documentation/Guides: https://github.com/obsproject/obs-studio/wiki +- Upstream build instructions: + https://github.com/obsproject/obs-studio/wiki/Install-Instructions -- Forums: https://obsproject.com/forum/ +- Upstream developer/API documentation: https://obsproject.com/docs -- Build Instructions: https://github.com/obsproject/obs-studio/wiki/Install-Instructions +Building from Source +-------------------- -- Developer/API Documentation: https://obsproject.com/docs +Build instructions are identical to upstream OBS Studio. See the upstream wiki +for platform-specific guidance: +https://github.com/obsproject/obs-studio/wiki/Install-Instructions -- Donating/backing/sponsoring: https://obsproject.com/contribute +Quick start (macOS):: -- Bug Tracker: https://github.com/obsproject/obs-studio/issues + cmake --preset macos + cmake --build --preset macos + +Quick start (Linux):: + + cmake --preset ubuntu-x86_64 + cmake --build --preset ubuntu-x86_64 Contributing ------------ -- If you would like to help fund or sponsor the project, you can do so - via `Patreon `_, `OpenCollective - `_, or `PayPal - `_. See our `contribute page - `_ for more information. +Contributions are welcome. Before opening a pull request, please: -- If you wish to contribute code to the project, please make sure to - read the coding and commit guidelines: +- Read the upstream coding guidelines: https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.md - -- Code for the project follows the code style guidelines, located - here: https://github.com/obsproject/obs-studio/blob/master/CODESTYLE.md - -- Developer/API documentation can be found here: - https://obsproject.com/docs - -- If you wish to contribute translations, do not submit pull requests. - Instead, please use Crowdin. For more information read this page: - https://obsproject.com/wiki/How-To-Contribute-Translations-For-OBS -- Contributors to OBS Studio and related repositories are expected to - follow our Code of Conduct, which can be read here: - https://github.com/obsproject/obs-studio/blob/master/COC.rst +- Follow the upstream code style: + https://github.com/obsproject/obs-studio/blob/master/CODESTYLE.md -- Other ways to contribute are by helping people out with support on - our forums or in our community chat. Please limit support to topics - you fully understand -- bad advice is worse than no advice. When it - comes to something that you don't fully know or understand, please - defer to the official help or official channels. +- Open work-in-progress changes against the ``dev`` branch, not ``master``. + ``master`` tracks upstream OBS Studio so we can pull in their changes + cleanly. +Acknowledgements +---------------- -SAST Tools ----------- +OBS Studio Plus is built on top of the work of the OBS Studio team and its +hundreds of contributors. See the ``AUTHORS`` file for the full list. This +fork would not exist without their work. -`PVS-Studio `_ - static analyzer for C, C++, C#, and Java code. +If you would like to support upstream OBS Studio (which we recommend, since +this fork depends on their continued work), see +https://obsproject.com/contribute. diff --git a/ROADMAP.md b/ROADMAP.md new file mode 100644 index 00000000000000..9975997c7e6e6c --- /dev/null +++ b/ROADMAP.md @@ -0,0 +1,124 @@ +# OBS Studio Plus — Roadmap + +This roadmap tracks the planned feature set for OBS Studio Plus, the goals +behind each anchor feature, and the current status. Things will change as we +build. + +## Guiding principles + +- **Don't break upstream compatibility.** Scenes, profiles, plugins, and + collections from upstream OBS must continue to load. We add capability + rather than diverge. +- **Local-first.** Anything that touches a streamer's content (audio, video, + metadata) runs on their machine by default. Cloud features are opt-in and + clearly disclosed. +- **Stay mergeable with upstream.** `master` tracks upstream OBS Studio. All + fork-specific work happens on `dev` and feature branches that periodically + merge `master`. We will surface upstream-equivalent features the moment + upstream ships them, and keep our changes small enough to rebase. +- **Plugins over core hacks.** Whenever a feature can ship as a plugin, it + ships as a plugin. The only changes that go into `libobs` and the frontend + are ones that genuinely require it (e.g., multi-canvas UI surfacing). + +## Anchor features + +These three are the reason this fork exists. Everything else is a stretch +goal. + +### 1. Multi-destination streaming (Status: planned, v0.1 target) + +Stream to N services simultaneously from one OBS instance, with per-destination +bitrate, resolution, and encoder settings. + +**Why now:** Upstream OBS supports multi-output through `obs_output_t`'s API, +and the `WHIPSimulcastEncoders` pattern in +`frontend/utility/WHIPSimulcastEncoders.hpp` already creates parallel encoder +chains. The core supports it. The UI doesn't. + +**Approach:** +- Vectorize `streamOutput` in `frontend/utility/BasicOutputHandler.{hpp,cpp}` + from a single output to a `std::vector`. +- New dock: `frontend/widgets/MultiDestinationDock.{hpp,cpp}` listing each + target with live status (connected / bitrate / dropped frames). +- Settings UI: extend `frontend/settings/OBSBasicSettings_Stream.cpp` to a + list of services rather than a single service. +- Optional: shared encoder mode (one encode, N muxers) when destinations + match resolution; per-destination encoders otherwise. + +**Risk:** Encoder licensing and per-platform service rules (e.g., Twitch +ToS on simultaneous streaming). Document, don't enforce. + +### 2. Native multi-canvas (Status: planned, v0.2 target) + +Run a 16:9 horizontal canvas and a 9:16 vertical canvas simultaneously from +one OBS instance. Stream each independently. Switch scenes per-canvas. + +**Why now:** The upstream `obs_canvas_t` API in `libobs/obs-canvas.c` is +complete. `OBSBasic.hpp` already declares `std::vector canvases`. +The C++ wrapper (`frontend/utility/OBSCanvas.{hpp,cpp}`) is in place. +`obs_view_add2` accepts a per-canvas `obs_video_info`. The frontend UI is the +last missing piece. + +**Approach:** +- Surface canvas management UI in `frontend/widgets/OBSBasic_Canvases.cpp` + (currently 62 lines of barebones plumbing). +- Multi-preview: extend `frontend/widgets/OBSBasic_Preview.cpp` to render N + canvases (tabbed or side-by-side). +- Per-canvas scene/source lists in + `frontend/widgets/OBSBasic_{Scenes,SceneItems}.cpp`. +- Audit every implicit `obs_get_video()` call in the frontend and route + through the active canvas instead. + +**Risk:** Hundreds of frontend call sites assume one canvas. The work is +diffuse, not deep. Estimate 4-6 weeks for one engineer. + +### 3. Modern UI + AI plugin suite (Status: planned, v0.2 target) + +A refreshed visual identity plus a starter set of local-AI features that +replace third-party paid plugins. + +**Why now:** Streamlabs and Streamerbot are eating OBS's mindshare on +polish. NVIDIA Broadcast and Aitum Vertical are paid third-party tools doing +things OBS could do natively. + +**Approach:** + +- **Theme:** new `.ovt` theme file in `frontend/data/themes/` based on the + existing Yami variable system. Refreshed icon set. +- **AI Captions plugin** (`plugins/obs-ai-captions/`): audio source filter + wrapping `whisper.cpp`. Real-time captions overlaid on canvas, optional + translation. Modeled after `plugins/obs-filters/noise-suppress-filter.c`. +- **AI Auto-framing plugin** (`plugins/obs-ai-autoframe/`): video source + filter running a small subject-detection model (MediaPipe or YOLO-nano) + and feeding the result into the source's transform. +- **DeepFilterNet noise suppression**: extend + `plugins/obs-filters/noise-suppress-filter.c` with a third backend + alongside RNNoise and NVIDIA NoiseRemoval. + +**Risk:** Model size and licensing. Default to small, permissively-licensed +models. Larger models behind opt-in download. + +## Stretch features (not committed) + +- Auto-highlight detection from stream recordings (post-stream offline tool). +- Smart scene switching (replace Advanced Scene Switcher rule trees with a + small classifier). +- Unified Go-Live panel that combines stream key entry, multi-destination + config, and pre-stream checks into one dialog. +- Built-in chat overlay with multi-platform aggregation (Twitch + YouTube + + Kick into one feed). + +## Versioning + +- **v0.1** — Multi-destination streaming. Modern theme. Renamed brand + (this README, splash screen, application name). +- **v0.2** — Native multi-canvas UI. AI captions plugin shipping by default. +- **v0.3** — Auto-framing plugin. DeepFilterNet noise suppression. Unified + Go-Live panel. + +Versions are aspirational, not contractual. We ship when it's stable. + +## How to contribute + +See `README.rst`. Open issues against this fork for fork-specific work; open +issues against upstream OBS for bugs that exist there too. From 2b3ee2b1446309a780fe7b4f0b4c9aaacaba2dbb Mon Sep 17 00:00:00 2001 From: OgBops Date: Sun, 17 May 2026 20:08:25 -0700 Subject: [PATCH 02/17] Run CI on dev and feature/** branches Upstream's push workflow only triggers builds on master and release/**. Since this fork uses master to track upstream and dev as the integration branch, we extend the push trigger and the format check to run on dev and feature/** branches as well. This means every push to dev or a feature branch will exercise the full macOS, Ubuntu, and Windows build matrix on GitHub Actions, which is our substitute for a local cross-platform dev environment. --- .github/workflows/push.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index f61753abca6873..98bacaebc795ac 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -7,6 +7,8 @@ on: branches: - master - 'release/**' + - dev + - 'feature/**' tags: - '*' permissions: @@ -14,7 +16,7 @@ permissions: jobs: check-format: name: Format 🔍 - if: github.ref_name == 'master' + if: github.ref_name == 'master' || github.ref_name == 'dev' || startsWith(github.ref_name, 'feature/') uses: ./.github/workflows/check-format.yaml permissions: contents: read From a1636cc6c8c6485c7e078b7cfb7dbd0ac09a04fc Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 12:55:51 -0700 Subject: [PATCH 03/17] ci: trigger first build after enabling Actions From fdc70fbdab5a992cb5c748833c8f647b573d56a5 Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 13:21:40 -0700 Subject: [PATCH 04/17] ci: re-trigger after enabling Actions From a98f4a4c1e3602384b8761920bd802f355e4b038 Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 13:33:46 -0700 Subject: [PATCH 05/17] ci: kick build after enabling fork actions From 6027584f4aca128ce6fba63829bb2da43402c7a5 Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 13:55:36 -0700 Subject: [PATCH 06/17] ci: nudge workflow registration on fork --- .github/workflows/push.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 98bacaebc795ac..2c7aee168dda54 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -1,4 +1,5 @@ name: Push +# obs-studio-plus fork: re-register after enabling Actions run-name: ${{ github.ref_name }} push run 🚀 on: push: From 63a8d899847e29bf925026f15d75daf710f2bd4d Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 13:57:34 -0700 Subject: [PATCH 07/17] ci: post-PUT trigger From 0647ee1e42252f315185f11a169c7073071db148 Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 14:03:13 -0700 Subject: [PATCH 08/17] ci: trigger after workflows registered From 86364eaaf04d0e5938cd16305fd99ab1d3ddde8a Mon Sep 17 00:00:00 2001 From: OgBops Date: Thu, 21 May 2026 14:06:28 -0700 Subject: [PATCH 09/17] ci: add workflow_dispatch trigger to push workflow --- .github/workflows/push.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 2c7aee168dda54..0f0e6aed78f70b 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -12,6 +12,7 @@ on: - 'feature/**' tags: - '*' + workflow_dispatch: permissions: contents: write jobs: From 86839167c7d7680b38d0c6773a1ffe2de343031e Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 12:22:01 -0700 Subject: [PATCH 10/17] cmake: fall back to default version when no git tag is reachable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The obs-studio-plus fork has no upstream tags pushed to origin, so CI runs hit `git describe` returning a bare SHA, which versionconfig.cmake then fed into project()/regexes that expect M.m.p — failing the macOS build with "VERSION format invalid" before configure finished. Detect the no-tag case and fall back to _obs_default_version (0.0.1). --- cmake/common/versionconfig.cmake | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/cmake/common/versionconfig.cmake b/cmake/common/versionconfig.cmake index 7a1e753125eeec..8c7d2514e01fa2 100644 --- a/cmake/common/versionconfig.cmake +++ b/cmake/common/versionconfig.cmake @@ -21,7 +21,16 @@ if(NOT DEFINED OBS_VERSION_OVERRIDE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git endif() if(_obs_version_result EQUAL 0) - string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+).*" "\\1;\\2;\\3" _obs_version_canonical ${_obs_version}) + if(_obs_version MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+).*") + string(REGEX REPLACE "([0-9]+)\\.([0-9]+)\\.([0-9]+).*" "\\1;\\2;\\3" _obs_version_canonical ${_obs_version}) + else() + # obs-studio-plus fork: no upstream tags reachable from this commit, so + # `git describe` returned a bare SHA. Fall back to _obs_default_version + # for the canonical M.m.p triple and the raw OBS_VERSION string. + message(STATUS "OBS version: no tag reachable, using default ${_obs_default_version} (git describe: ${_obs_version})") + set(_obs_version ${_obs_default_version}) + set(_obs_version_canonical ${_obs_default_version}) + endif() endif() elseif(DEFINED OBS_VERSION_OVERRIDE) if(OBS_VERSION_OVERRIDE MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+).*") From 969dd9350c0488f324a1e60e909777a9f97820ef Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 12:28:28 -0700 Subject: [PATCH 11/17] cmake: gersemi format on versionconfig.cmake fallback message --- cmake/common/versionconfig.cmake | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/cmake/common/versionconfig.cmake b/cmake/common/versionconfig.cmake index 8c7d2514e01fa2..615d44109f3cbc 100644 --- a/cmake/common/versionconfig.cmake +++ b/cmake/common/versionconfig.cmake @@ -27,7 +27,10 @@ if(NOT DEFINED OBS_VERSION_OVERRIDE AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git # obs-studio-plus fork: no upstream tags reachable from this commit, so # `git describe` returned a bare SHA. Fall back to _obs_default_version # for the canonical M.m.p triple and the raw OBS_VERSION string. - message(STATUS "OBS version: no tag reachable, using default ${_obs_default_version} (git describe: ${_obs_version})") + message( + STATUS + "OBS version: no tag reachable, using default ${_obs_default_version} (git describe: ${_obs_version})" + ) set(_obs_version ${_obs_default_version}) set(_obs_version_canonical ${_obs_default_version}) endif() From 0e6b88465ce4536691cdd9945628e954e99ce1e6 Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 12:41:05 -0700 Subject: [PATCH 12/17] ci: package scripts tolerate fork with no upstream tags `.package.zsh` and `Package-Windows.ps1` both call `git describe --tags --long` which exits non-zero when no tag is reachable, breaking the macOS DMG name and Windows zip name on the obs-studio-plus fork (zero tags on origin). Detect the empty result and synthesize a `--g` string from the commit count + short HEAD hash so packaging proceeds. --- .github/scripts/.package.zsh | 10 +++++++++- .github/scripts/Package-Windows.ps1 | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/scripts/.package.zsh b/.github/scripts/.package.zsh index 821dc9f385241d..41ea04772b41c7 100755 --- a/.github/scripts/.package.zsh +++ b/.github/scripts/.package.zsh @@ -110,7 +110,15 @@ package() { local commit_hash if [[ -d ${project_root}/.git ]] { - local git_description="$(git describe --tags --long)" + local git_description="$(git describe --tags --long 2>/dev/null)" + if [[ -z ${git_description} ]] { + # obs-studio-plus fork: no tags pushed to origin, so `git describe --tags` + # fails. Synthesize the same shape (--g) using + # total commit count and the short HEAD hash. + local _short_hash="$(git rev-parse --short=9 HEAD)" + local _commit_count="$(git rev-list --count HEAD)" + git_description="0.0.1-${_commit_count}-g${_short_hash}" + } commit_version="${${git_description%-*}%-*}" commit_hash="${git_description##*-g}" commit_distance="${${git_description%-*}##*-}" diff --git a/.github/scripts/Package-Windows.ps1 b/.github/scripts/Package-Windows.ps1 index e2f276a0d1cdf3..890d72a8fd4c27 100644 --- a/.github/scripts/Package-Windows.ps1 +++ b/.github/scripts/Package-Windows.ps1 @@ -44,7 +44,15 @@ function Package { Install-BuildDependencies -WingetFile "${ScriptHome}/.Wingetfile" - $GitDescription = Invoke-External git describe --tags --long + # obs-studio-plus fork: tolerate missing tags (git describe --tags fails + # when no tag is reachable). Fall back to --g. + $GitDescription = $null + try { $GitDescription = Invoke-External git describe --tags --long } catch { } + if ( -not $GitDescription ) { + $ShortHash = (Invoke-External git rev-parse --short=9 HEAD).Trim() + $CommitCount = (Invoke-External git rev-list --count HEAD).Trim() + $GitDescription = "0.0.1-${CommitCount}-g${ShortHash}" + } $Tokens = ($GitDescription -split '-') $CommitVersion = $Tokens[0..$($Tokens.Count - 3)] -join '-' $CommitHash = $($Tokens[-1]).SubString(1) From 987418cab779f327b203821a832a26dba7bc2622 Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 13:14:08 -0700 Subject: [PATCH 13/17] ci: harden packaging against missing tags Two follow-ups to the previous package script change: 1. The fallback in `.package.zsh` was bypassed: with `setopt ERR_RETURN`, a failing `git describe` inside `$(...)` triggered TRAPZERR, leaking the script callstack into `git_description`. Adding `|| true` keeps the substitution successful so the empty-string check actually runs. 2. `frontend/cmake/os-linux.cmake` populated `APPDATA_RELEASE_DATE` with `git log --tags -1`, which returns empty when no tag exists. Empty date fails flatpak-builder-lint with `release-time-missing date`. Fall back to the latest commit's date. --- .github/scripts/.package.zsh | 9 +++++---- frontend/cmake/os-linux.cmake | 11 +++++++++++ 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/.github/scripts/.package.zsh b/.github/scripts/.package.zsh index 41ea04772b41c7..ec4b4c9a2037bb 100755 --- a/.github/scripts/.package.zsh +++ b/.github/scripts/.package.zsh @@ -110,11 +110,12 @@ package() { local commit_hash if [[ -d ${project_root}/.git ]] { - local git_description="$(git describe --tags --long 2>/dev/null)" + # `|| true` keeps ERR_RETURN/TRAPZERR from firing (and leaking the + # callstack into the variable) when the fork has no tags reachable. + local git_description="$(git describe --tags --long 2>/dev/null || true)" if [[ -z ${git_description} ]] { - # obs-studio-plus fork: no tags pushed to origin, so `git describe --tags` - # fails. Synthesize the same shape (--g) using - # total commit count and the short HEAD hash. + # obs-studio-plus fork fallback: synthesize --g + # from the commit count and short HEAD hash so packaging proceeds. local _short_hash="$(git rev-parse --short=9 HEAD)" local _commit_count="$(git rev-list --count HEAD)" git_description="0.0.1-${_commit_count}-g${_short_hash}" diff --git a/frontend/cmake/os-linux.cmake b/frontend/cmake/os-linux.cmake index d146e7297e1e49..fd9f3eccec2c6c 100644 --- a/frontend/cmake/os-linux.cmake +++ b/frontend/cmake/os-linux.cmake @@ -33,6 +33,17 @@ if(NOT DEFINED APPDATA_RELEASE_DATE) WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" OUTPUT_STRIP_TRAILING_WHITESPACE ) + # obs-studio-plus fork: no tags reachable, so the tag-scoped log returns + # empty and the appstream metainfo loses its release date. Fall back to + # the most recent commit's date. + if(APPDATA_RELEASE_DATE STREQUAL "") + execute_process( + COMMAND git log -1 --pretty=%cd --date=short + OUTPUT_VARIABLE APPDATA_RELEASE_DATE + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() elseif(EXISTS "${CMAKE_SOURCE_DIR}/cmake/.CMakeBuildNumber") file(TIMESTAMP "${CMAKE_SOURCE_DIR}/cmake/.CMakeBuildNumber" APPDATA_RELEASE_DATE "%Y-%m-%d") else() From c4d5a9a87c5bee9432e66a57a2b5089a3258dd29 Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 15:02:08 -0700 Subject: [PATCH 14/17] docs: rewrite README to reflect current fork status honestly Previous README pitched features that don't exist yet ("native vertical + horizontal canvases", "first-class multi-destination streaming") as if they shipped. Replace with: - Honest "current status" section listing each branch and what's on it - A clear "today a build from dev looks like upstream" disclaimer - Pointers to the Actions tab for prebuilt artifacts, with the macOS quarantine-strip command since builds are ad-hoc signed - A build-status badge for dev --- README.rst | 154 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 58 deletions(-) diff --git a/README.rst b/README.rst index 43be70a8a0792c..42b8b8bba0dbc9 100644 --- a/README.rst +++ b/README.rst @@ -1,65 +1,77 @@ OBS Studio Plus =============== -OBS Studio Plus is a community fork of `OBS Studio `_ -that aims to bring native multi-canvas streaming, first-class multi-destination -output, and a modern UI to the world's most popular live-streaming software. - -This fork preserves full compatibility with upstream OBS plugins, scenes, and -profiles. Everything that works in OBS Studio works in OBS Studio Plus. - -Status ------- - -Early development. See `ROADMAP.md `_ for the planned feature set -and current progress. - -What's different from upstream OBS? ------------------------------------ - -The upstream OBS Studio project has quietly built much of the infrastructure -needed for modern streaming workflows (multi-canvas, multi-output) but has not -yet surfaced these capabilities to users. OBS Studio Plus exposes them, plus -adds new capabilities on top: - -- **Native vertical + horizontal canvases** — stream 16:9 to Twitch and 9:16 - to TikTok / Shorts / Reels simultaneously, from a single OBS instance. -- **First-class multi-destination streaming** — push your stream to multiple - services at once with per-destination bitrate and resolution settings. -- **Modern UI shell** — refreshed theming, restructured panels, unified - Go-Live workflow. -- **Local-first AI features** — auto-framing, live captions, and improved - noise suppression as opt-in plugins. No cloud dependencies for core features. - -License +|build-status| + +OBS Studio Plus is a personal fork of `OBS Studio `_ +that explores three additions on top of upstream: + +1. **Native multi-destination streaming** — push the same stream to several + services in parallel, with per-destination configuration. +2. **Native multi-canvas** — surface the existing ``obs_canvas_t`` engine + (already complete in ``libobs/obs-canvas.c``) so users can compose 16:9 + + 9:16 outputs from a single OBS instance. +3. **Local-first AI plugins** — captions (whisper.cpp), auto-framing, and + improved noise suppression as optional drop-in plugins. No cloud + dependencies. + +Compatibility with upstream OBS plugins, scenes, and profiles is preserved. + +Current status +-------------- + +Early development. The fork is being built incrementally; today's branches +contain plumbing rather than user-visible features. + +================================ ============================================== +Branch Status +================================ ============================================== +``master`` Tracks upstream OBS, untouched +``dev`` Integration branch. Fork branding, CI fixes + for the no-tags state, and other plumbing. + CI builds all 6 platforms green. +``feature/multi-output-foundation`` Header-only structural seam + (``additionalStreamOutputs`` vector + + ``AllStreamOutputs()`` helper) for the + multi-destination work to land on. +``feature/multi-destination-dock`` Qt dock scaffold (~316 LOC). Compiles in + isolation; not wired into ``OBSBasic`` yet. +``feature/ai-captions-plugin`` Plugin scaffold (~379 LOC) with a no-op + backend. Pending whisper.cpp integration. +================================ ============================================== + +Right now, a binary built from ``dev`` looks and behaves exactly like upstream +OBS — that is intentional. The user-visible features land once the foundation +is in place. + +Downloads +--------- + +CI produces prebuilt binaries for every push to ``dev`` and ``feature/**``. +Artifacts (macOS arm64/x86_64 ``.dmg``, Ubuntu 24.04 ``.deb``, Flatpak, +Windows x64/arm64 zips) are attached to each successful run on the +`Actions tab `_ and expire +90 days after the build. + +There is no signed release yet. macOS builds are ad-hoc signed; clear the +quarantine attribute after downloading:: + + xattr -dr com.apple.quarantine /path/to/OBS.app + +Roadmap ------- -OBS Studio Plus is distributed under the GNU General Public License v2 (or any -later version), the same license as upstream OBS Studio. See the accompanying -``COPYING`` file for details. +See `ROADMAP.md `_ for the planned feature set and milestone +ordering. -Quick Links ------------ - -- This fork's repository: https://github.com/OgBops/obs-studio-plus - -- Upstream OBS Studio: https://github.com/obsproject/obs-studio - -- Upstream OBS website: https://obsproject.com - -- Upstream build instructions: - https://github.com/obsproject/obs-studio/wiki/Install-Instructions - -- Upstream developer/API documentation: https://obsproject.com/docs - -Building from Source +Building from source -------------------- -Build instructions are identical to upstream OBS Studio. See the upstream wiki -for platform-specific guidance: +Build instructions are identical to upstream OBS Studio. The upstream wiki +covers platform setup: https://github.com/obsproject/obs-studio/wiki/Install-Instructions -Quick start (macOS):: +Quick start (macOS, requires full Xcode.app):: cmake --preset macos cmake --build --preset macos @@ -69,20 +81,42 @@ Quick start (Linux):: cmake --preset ubuntu-x86_64 cmake --build --preset ubuntu-x86_64 +A Command-Line-Tools-only macOS build using Ninja is in progress on +``feature/macos-clt-build`` but is not currently the recommended local path. + Contributing ------------ -Contributions are welcome. Before opening a pull request, please: +This is a personal fork. External contributions are welcome but not actively +solicited at this stage. If you do open a pull request: - Read the upstream coding guidelines: https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.md - - Follow the upstream code style: https://github.com/obsproject/obs-studio/blob/master/CODESTYLE.md - -- Open work-in-progress changes against the ``dev`` branch, not ``master``. - ``master`` tracks upstream OBS Studio so we can pull in their changes +- Open work-in-progress changes against ``dev``, not ``master``. + ``master`` tracks upstream OBS Studio so upstream changes can be pulled in cleanly. +- Run the project's formatters before pushing — CI rejects unformatted + changes:: + + ./build-aux/run-format clang-format + ./build-aux/run-gersemi + +License +------- + +OBS Studio Plus is distributed under the GNU General Public License v2 (or +any later version), the same license as upstream OBS Studio. See ``COPYING`` +for details. + +Quick links +----------- + +- This fork: https://github.com/OgBops/obs-studio-plus +- Upstream OBS Studio: https://github.com/obsproject/obs-studio +- Upstream OBS website: https://obsproject.com +- Upstream developer/API documentation: https://obsproject.com/docs Acknowledgements ---------------- @@ -91,6 +125,10 @@ OBS Studio Plus is built on top of the work of the OBS Studio team and its hundreds of contributors. See the ``AUTHORS`` file for the full list. This fork would not exist without their work. -If you would like to support upstream OBS Studio (which we recommend, since +If you would like to support upstream OBS Studio (which is recommended, since this fork depends on their continued work), see https://obsproject.com/contribute. + +.. |build-status| image:: https://github.com/OgBops/obs-studio-plus/actions/workflows/push.yaml/badge.svg?branch=dev + :target: https://github.com/OgBops/obs-studio-plus/actions/workflows/push.yaml + :alt: dev branch build status From 484f16b2462a9265201078db3e6ed6659d649e3a Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 15:03:02 -0700 Subject: [PATCH 15/17] ci: skip full build for docs-only changes paths-ignore already covered .md; extend to .rst (the README format), plus AUTHORS and COPYING which are touched periodically when syncing upstream. Saves a 30+ min cross-platform run for documentation edits. --- .github/workflows/push.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index 0f0e6aed78f70b..cdd1d5b9561102 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -5,6 +5,9 @@ on: push: paths-ignore: - '**.md' + - '**.rst' + - 'AUTHORS' + - 'COPYING' branches: - master - 'release/**' From 29dca3a6add54800425197d6d291d44fbef5bcce Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 15:39:53 -0700 Subject: [PATCH 16/17] docs: pivot fork to engine for Plus desktop app MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The fork's purpose changes from "OBS with extra Qt features" to "headless plus-host engine for the Plus desktop app." Plus is a separate, future Rust + Tauri product that talks to libobs over IPC, the same way Streamlabs Desktop uses obs-studio-node. Running libobs out-of-process keeps the GPL boundary at the IPC pipe and allows the Plus app to be licensed independently. Concretely: - PLUS_PLAN.md: full plan, 9 phases, ~80 weeks. Phase 0 starts next. - CONTRIBUTING.md: prepended fork-specific rules. OBS core (libobs/, plugins/, frontend C++/Qt, deps/) is read-only. Smell test, escape hatch, branching policy. - README.rst: rewritten to describe the engine role. The previous "OBS with multi-canvas + multi-dest + AI plugins" pitch is retired. - ROADMAP.md: stub pointing at PLUS_PLAN.md. - .github/workflows/no-core-changes.yaml: CI guard that diffs against upstream/master and fails any push that modifies off-limits paths. - .gitignore: allowlist PLUS_PLAN.md and /engine for upcoming phase 0. The previous Qt feature branches (multi-output-foundation, multi-destination-dock, ai-captions-plugin) are deleted from origin in the same session. Their work isn't wasted — concepts move into the IPC protocol — but they don't move forward as Qt code. --- .github/workflows/no-core-changes.yaml | 99 +++++++++++++++++ .gitignore | 2 + CONTRIBUTING.md | 105 ++++++++++++++++++ PLUS_PLAN.md | 147 +++++++++++++++++++++++++ README.rst | 145 +++++++++++------------- ROADMAP.md | 134 +++------------------- 6 files changed, 434 insertions(+), 198 deletions(-) create mode 100644 .github/workflows/no-core-changes.yaml create mode 100644 PLUS_PLAN.md diff --git a/.github/workflows/no-core-changes.yaml b/.github/workflows/no-core-changes.yaml new file mode 100644 index 00000000000000..07c2e45a1794f6 --- /dev/null +++ b/.github/workflows/no-core-changes.yaml @@ -0,0 +1,99 @@ +name: No Core Changes +# Enforces the obs-studio-plus fork rule: libobs/, plugins/, deps/, and the +# C++/Qt parts of frontend/ track upstream OBS Studio untouched. Only files +# under engine/, CI infrastructure, and explicitly-allowlisted fork-specific +# build fixes may diverge. +# +# See CONTRIBUTING.md for the full policy. + +on: + push: + branches: + - dev + - 'engine/**' + pull_request: + branches: + - dev + - master + +permissions: + contents: read + +jobs: + diff-against-upstream: + name: Diff Against Upstream OBS + runs-on: ubuntu-24.04 + steps: + - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 + with: + fetch-depth: 0 + + - name: Add upstream remote + run: | + git remote add upstream https://github.com/obsproject/obs-studio.git + git fetch --depth=200 upstream master + + - name: Check off-limits paths + run: | + set -euo pipefail + + # Off-limits paths (see CONTRIBUTING.md). + OFF_LIMITS=( + 'libobs/' + 'libobs-d3d11/' + 'libobs-opengl/' + 'libobs-winrt/' + 'plugins/' + 'deps/' + ) + + # Frontend is special: only the C++/Qt code is off-limits. The + # frontend/cmake/os-linux.cmake flatpak fix is allowlisted below. + # We restrict to actual source files, not cmake. + OFF_LIMITS+=( + 'frontend/*.cpp' + 'frontend/*.hpp' + 'frontend/*.h' + 'frontend/*.mm' + 'frontend/*.swift' + 'frontend/data/' + 'frontend/dialogs/' + 'frontend/docks/' + 'frontend/forms/' + 'frontend/idian/' + 'frontend/menu/' + 'frontend/models/' + 'frontend/oauth/' + 'frontend/plugins/' + 'frontend/settings/' + 'frontend/utility/' + 'frontend/widgets/' + 'frontend/window-basic-main.*' + ) + + MERGE_BASE=$(git merge-base upstream/master HEAD) + echo "Merge base with upstream/master: ${MERGE_BASE}" + + # Find any diff in off-limits paths. + CHANGED=$(git diff --name-only "${MERGE_BASE}" HEAD -- "${OFF_LIMITS[@]}" || true) + + if [[ -z "${CHANGED}" ]]; then + echo '✅ No core changes detected. Fork rule respected.' + exit 0 + fi + + echo '❌ The following files were modified in off-limits paths:' + echo '---' + echo "${CHANGED}" + echo '---' + echo '' + echo 'See CONTRIBUTING.md ("OBS Studio Plus — Fork Contribution Rules").' + echo 'OBS core (libobs, plugins, frontend C++) tracks upstream untouched.' + echo '' + echo 'Options:' + echo ' 1. Move the change into engine/ (preferred)' + echo ' 2. File the change upstream first (obsproject/obs-studio)' + echo ' 3. If the change is genuinely fork-specific build/CI infrastructure' + echo ' and would be accepted upstream as a robustness fix, update' + echo ' CONTRIBUTING.md to allowlist it explicitly.' + exit 1 diff --git a/.gitignore b/.gitignore index 9746eabd7cd08b..77f8b4427eb64c 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ !INSTALL !README.rst !ROADMAP.md +!PLUS_PLAN.md +!/engine # Exclude lock files *.lock.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 3ade81b445778d..42c9a58a1c91e8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,3 +1,108 @@ +OBS Studio Plus — Fork Contribution Rules +========================================= + +> The section below is **specific to this fork** (`OgBops/obs-studio-plus`). +> Upstream OBS Studio's full contribution guide follows further down and +> applies to any code that is intended to be submitted upstream. + +This repository is the **engine** for the Plus desktop app. Plus is a +separate user-facing product (separate repository, future). This fork +exists for one reason: produce a headless `plus-host` binary that runs +`libobs` in a sidecar process and exposes its functionality over IPC. + +## The hard rule: OBS core is read-only + +We do **not** modify the engine, plugins, or any code that ships as part of +upstream OBS Studio. The fork's value is in keeping libobs unmodified so +upstream changes merge cleanly forever. + +### Off-limits paths + +| Path | What it is | +|------|-----------| +| `libobs/` | The OBS engine itself | +| `libobs-d3d11/`, `libobs-opengl/`, `libobs-winrt/` | Engine GPU backends | +| `plugins/` | Every encoder, capture source, filter, output | +| `frontend/` (C++/Qt code) | Upstream Qt UI. We don't link it; we also don't modify it. | +| `deps/` | Third-party dependencies as upstream ships them | + +### Allowed playgrounds + +| Path | Purpose | +|------|---------| +| `engine/` | All Plus engine code (IPC server, host wrapper). New code lives here. | +| `.github/workflows/`, `.github/scripts/`, `.github/actions/` | CI infrastructure | +| `cmake/common/versionconfig.cmake` | Already-shipped fork-specific build robustness fix | +| `frontend/cmake/os-linux.cmake` | Already-shipped flatpak metadata fix | +| `*.md`, `*.rst`, `AUTHORS`, `COPYING` | Documentation and licensing | +| `build-aux/` | Project tooling | + +### Smell test + +Before any commit outside `engine/`: + +> "Would this change still be correct if we deleted the entire fork tomorrow +> and submitted it upstream as a PR?" + +If yes, fine. If no, you're modifying core. Stop. + +## What if libobs is genuinely missing what we need? + +We file the change **upstream first**. + +1. Search [obsproject/obs-studio issues](https://github.com/obsproject/obs-studio/issues) + for prior discussion. +2. Open an upstream PR or issue with the API change request. +3. Wait for upstream review. +4. Once accepted upstream, sync via `master`. + +We do not carry local core patches. The discipline is the point. + +## Where Plus engine code goes + +``` +engine/ +├─ host/ # plus-host binary: links libobs, runs IPC server +│ ├─ ipc/ # newline-JSON IPC protocol implementation +│ ├─ methods/ # IPC method handlers (capture, output, scenes...) +│ └─ main.cpp # entry point +├─ protocol/ # IPC protocol schema (shared definitions) +└─ spike/ # Phase 0 throwaway code (deleted at end of phase 0) +``` + +## CI enforcement + +The workflow `.github/workflows/no-core-changes.yaml` runs on every push to +`dev` and `engine/**`. It diffs against `upstream/master` and fails the +build if any off-limits path has changed beyond explicitly-allowlisted +commits. + +To intentionally update the allowlist (rare — only for upstream-able +fork-specific build/CI fixes), edit the allowlist in the workflow itself +and reference the upstream issue or PR. + +## Branching + +| Branch | Purpose | +|--------|---------| +| `master` | Tracks upstream OBS Studio. Untouched. | +| `dev` | Integration branch. Branding, CI, the engine entry points land here. | +| `engine/` | Active engine work. Branch off `dev`. | +| `engine/spike` | Phase 0 spike. Temporary; deleted after the spike retro. | + +Open work-in-progress PRs against `dev`, never `master`. + +## License + +Files in `engine/` are licensed under the GPL v2 or later, same as upstream +OBS Studio, because they link `libobs`. + +The Plus app (separate repository) does **not** link `libobs` — it +communicates with `plus-host` over IPC — and is therefore not subject to +GPL. That separation is load-bearing. Keep it that way. + +--- + OBS Studio Contribution Guidelines ============ diff --git a/PLUS_PLAN.md b/PLUS_PLAN.md new file mode 100644 index 00000000000000..43f9364cc9e1a7 --- /dev/null +++ b/PLUS_PLAN.md @@ -0,0 +1,147 @@ +# Plus — Project Plan + +This document is the north star for `obs-studio-plus`. When in doubt about +scope, refer back here. When this document is wrong, update it before +writing code that contradicts it. + +## What we're building + +**Plus** — a cross-platform desktop streaming app, owned end-to-end, that +covers three streaming modes: general (OBS-like), vertical-first +(TikTok/Shorts/Reels), and podcast/interview-style. + +## Architecture + +Plus is two binaries: + +``` +┌─ Plus.app ─────────────────────────────────────┐ +│ Rust + Tauri (this repo: not yet created) │ +│ - UI shell (TypeScript/React in webview) │ +│ - Mode logic (general / vertical / podcast) │ +│ - Multi-destination fanout policy │ +│ - Talks to plus-host over IPC │ +│ │ +│ Closed-source-capable (no GPL linkage) │ +└──────────────────┬──────────────────────────────┘ + │ named pipe (Win) / Unix socket (mac/linux) + │ + shared GPU texture handle (later phase) +┌──────────────────▼──────────────────────────────┐ +│ plus-host (THIS REPO, the OBS fork) │ +│ - libobs + every upstream plugin │ +│ - IPC server (engine/host/ipc) │ +│ - IPC method handlers (engine/host/methods) │ +│ - No Qt frontend │ +│ │ +│ GPL v2 (same as upstream OBS Studio) │ +└──────────────────────────────────────────────────┘ +``` + +The architecture mirrors how Streamlabs Desktop works (their +`obs-studio-node` is the analog of our `plus-host`). The legal point of +running libobs in a sidecar process is that the GPL boundary stops at +the IPC pipe. The Plus app does not link libobs and is not a derived +work. + +## Hard constraints + +- **OBS core is read-only** — see `CONTRIBUTING.md`. Enforced in CI by + `.github/workflows/no-core-changes.yaml`. +- **Plus must remain closed-source-capable.** No statically-linked GPL + code. No `#include` paths into libobs from the Plus side. IPC only. +- **Upstream merges stay clean.** `master` tracks `obsproject/obs-studio` + untouched. Quarterly merge into `dev`. + +## Phases + +| # | Phase | Weeks | What lands | +|---|-----------------------------------|-------|------------| +| 0 | Spike & validate | 2 | 200-LOC Rust + 400-LOC C++ end-to-end pipeline. Two binaries, one pipe, one RTMP stream. Both platforms. Throwaway. | +| 1 | Strip Qt, real IPC server | 6 | `plus-host` builds without `frontend/`. JSON-RPC IPC server. `ping`/`version`/`shutdown`. | +| 2 | IPC protocol v0.1 | 8 | Scene/source/output CRUD over IPC. Streaming start/stop. Stats. Settings persistence. CLI test client. | +| 3 | Shared GPU texture preview | 6 | D3D11 shared handles (Win), IOSurface (mac), DMA-BUF (Linux). Zero-copy 60fps preview. Hardest piece. | +| 4 | Plus shell — General mode | 8 | Tauri app. Source list, scene editor, "Go Live". Functional parity with vanilla OBS for single-destination. | +| 5 | Multi-destination (local fanout) | 4 | N parallel `obs_output_t` instances. Per-destination bitrate. UI for adding destinations. | +| 6 | Vertical mode | 4 | 9:16 canvas, source layout templates, vertical default scenes. | +| 7 | Podcast mode P0 | 12 | WebRTC mesh ≤4 participants. Guests join via web client (no install). Live composite. No per-participant local recording yet. | +| 8 | Podcast mode P1 | 10 | Per-participant local recording in browser via MediaRecorder. Background upload. Post-session merge. The Riverside-killer piece. | +| 9 | Polish & ship | 8 | Code signing on both platforms. Auto-updater. Installers. Telemetry (opt-in). Marketing site. Public beta. | + +**Total realistic timeline: ~80 weeks (1.5 years).** Slack accounted for. + +### Decision points where the plan should bend + +- **End of phase 3:** if shared GPU texture doesn't work cleanly on + Windows, fall back to CPU-side preview. Don't let perfection kill phase 3. +- **End of phase 6:** if vertical-first turns out to be the killer mode, + ship vertical alone as the public beta. Phases 7–8 can wait. +- **End of phase 8:** podcast mode is the riskiest. If it's not working + at week 60, cut it. Plus ships as a 2-mode product. Podcast is v2. + +## Phase 0 — feasibility spike + +See `engine/spike/PLAN.md` (created at the start of phase 0). + +**Goal:** prove the architecture isn't fiction. The smallest possible +end-to-end pipeline. + +**Done = green checkmark on every line:** +1. ✅ `plus-host-spike` builds and runs on macOS arm64 and Windows x64 +2. ✅ `plus-spike-client` (Rust) connects to it on both platforms +3. ✅ End-to-end stream works on both (verified by ffplay) +4. ✅ Both processes exit cleanly under normal shutdown +5. ✅ Total new C++ code in `plus-host-spike` < 600 LOC +6. ✅ Total Rust code < 300 LOC +7. ✅ `git diff upstream/master..HEAD -- libobs/ plugins/ frontend/cpp deps/` is empty + +If 1–4 fail, re-plan (one re-plan budget). If 5–6 are massively over, +that signals the Qt-strip is bigger than expected; phase 1 estimate +doubles. + +## Repo layout, target + +``` +obs-studio-plus/ +├─ master/ ← tracks upstream OBS, untouched +├─ dev/ ← integration: branding, CI, engine entry points +├─ engine/spike/ ← phase 0, throwaway +├─ engine/host/ ← plus-host (phases 1+) +│ ├─ ipc/ ← JSON-RPC server +│ ├─ methods/ ← IPC method handlers +│ └─ main.cpp +├─ engine/protocol/ ← IPC schema (shared definitions) +├─ libobs/ ← UPSTREAM, READ-ONLY +├─ plugins/ ← UPSTREAM, READ-ONLY +├─ frontend/ ← UPSTREAM, READ-ONLY (we don't link, don't modify) +└─ ... ← upstream as-is +``` + +The Plus app itself lives in a separate repository (created at the start +of phase 4). + +## Risk register (top of mind) + +| Risk | Likelihood | Impact | Mitigation | +|------|-----------|--------|-----------| +| Shared GPU texture path differs subtly per platform/GPU | High | High | Phase 0 spike on real hardware. CPU-fallback path planned. | +| Stripping Qt cascades through more code than expected | Medium | High | Don't delete `frontend/` immediately — make it not link, then prune. Preserves upstream merge compat. | +| GPL boundary gets challenged | Low | Existential | Follow Streamlabs' pattern exactly: separate process, IPC only, no shared address space. Document the design decision. | +| Upstream OBS API changes break plus-host | Medium/quarter | Medium | Track `master` against upstream, merge quarterly, fix breakage. | +| Podcast WebRTC stack is its own 6-month project | High | Medium | Use existing libraries (`webrtc-rs`, `mediasoup`). Don't roll our own SFU. | +| Code signing gets stuck on dev enrollment | Medium | Low (delay) | Apply for Apple Developer Program + Windows EV cert before phase 9. | +| First 100 beta users find a thousand bugs | Certain | Medium | Phase 9 includes telemetry + crash reporting from day 1. | + +## What this plan replaces + +The previous OBS-Plus roadmap (multi-destination dock, AI captions plugin, +Qt-frontend feature work) is **abandoned**. The work wasn't wasted — concepts +move into the IPC protocol — but the Qt path is no longer the route to those +features. See git history on the deleted branches: +`feature/multi-output-foundation`, `feature/multi-destination-dock`, +`feature/ai-captions-plugin`. + +## Updating this document + +When phase boundaries change, when a phase actually ships, when the architecture +gets revised, **update this file in the same commit as the change**. A plan +doc that's out of sync with reality is worse than no plan doc at all. diff --git a/README.rst b/README.rst index 42b8b8bba0dbc9..466cd2bfa29c0e 100644 --- a/README.rst +++ b/README.rst @@ -3,67 +3,69 @@ OBS Studio Plus |build-status| -OBS Studio Plus is a personal fork of `OBS Studio `_ -that explores three additions on top of upstream: - -1. **Native multi-destination streaming** — push the same stream to several - services in parallel, with per-destination configuration. -2. **Native multi-canvas** — surface the existing ``obs_canvas_t`` engine - (already complete in ``libobs/obs-canvas.c``) so users can compose 16:9 + - 9:16 outputs from a single OBS instance. -3. **Local-first AI plugins** — captions (whisper.cpp), auto-framing, and - improved noise suppression as optional drop-in plugins. No cloud - dependencies. - -Compatibility with upstream OBS plugins, scenes, and profiles is preserved. - -Current status --------------- - -Early development. The fork is being built incrementally; today's branches -contain plumbing rather than user-visible features. - -================================ ============================================== -Branch Status -================================ ============================================== -``master`` Tracks upstream OBS, untouched -``dev`` Integration branch. Fork branding, CI fixes - for the no-tags state, and other plumbing. - CI builds all 6 platforms green. -``feature/multi-output-foundation`` Header-only structural seam - (``additionalStreamOutputs`` vector + - ``AllStreamOutputs()`` helper) for the - multi-destination work to land on. -``feature/multi-destination-dock`` Qt dock scaffold (~316 LOC). Compiles in - isolation; not wired into ``OBSBasic`` yet. -``feature/ai-captions-plugin`` Plugin scaffold (~379 LOC) with a no-op - backend. Pending whisper.cpp integration. -================================ ============================================== - -Right now, a binary built from ``dev`` looks and behaves exactly like upstream -OBS — that is intentional. The user-visible features land once the foundation -is in place. +This repository is the **engine** for the Plus desktop app — a future +cross-platform streaming application that covers general streaming, +vertical-first content (TikTok / Shorts / Reels), and podcast/interview +workflows. + +It is a fork of `OBS Studio `_ that exists for one +specific purpose: to produce a headless ``plus-host`` binary which runs +``libobs`` in a sidecar process and exposes its functionality over IPC. +The Plus desktop app (separate repository, written in Rust + Tauri) talks +to ``plus-host`` over a named pipe. + +This is the same architecture Streamlabs Desktop uses with their +``obs-studio-node`` — running libobs out of process keeps the GPL boundary +at the IPC layer so the Plus app itself can be developed under any +license, while the engine here remains GPL v2 like upstream OBS. + +Status +------ + +**Pre-alpha.** The fork has just pivoted from "OBS with extra Qt features" +to "engine for a separate app." Phase 0 (a 2-week feasibility spike) is +the current work. There is no shippable product yet. + +Today, a build from ``dev`` looks and behaves exactly like vanilla OBS +Studio — that is intentional. The engine wrapper and the Plus app land in +later phases. See `PLUS_PLAN.md `_ for the full plan. + +Repository layout +----------------- + +================================ =============================================== +Branch / path What it is +================================ =============================================== +``master`` Tracks upstream OBS Studio, untouched. +``dev`` Integration branch. Branding, CI fixes for + the no-tags state, engine entry points land + here. CI builds all 6 platforms green. +``engine/spike`` Phase 0 spike. Created at the start of phase 0, + deleted after the retro. +``engine/host`` ``plus-host`` proper (created in phase 1). +``libobs/``, ``plugins/``, Read-only mirror of upstream OBS. Modifying +``frontend/`` C++ these files fails CI. +================================ =============================================== + +The hard rule: see `CONTRIBUTING.md `_. OBS core is +read-only in this fork. The CI workflow ``no-core-changes.yaml`` enforces +the rule by diffing against ``upstream/master``. Downloads --------- -CI produces prebuilt binaries for every push to ``dev`` and ``feature/**``. -Artifacts (macOS arm64/x86_64 ``.dmg``, Ubuntu 24.04 ``.deb``, Flatpak, -Windows x64/arm64 zips) are attached to each successful run on the -`Actions tab `_ and expire -90 days after the build. +CI produces prebuilt binaries for every push to ``dev`` and ``engine/**``. +Today these are vanilla OBS builds. Artifacts (macOS arm64/x86_64 ``.dmg``, +Ubuntu 24.04 ``.deb``, Flatpak, Windows x64/arm64 zips) are attached to +each successful run on the +`Actions tab `_ and +expire 90 days after the build. There is no signed release yet. macOS builds are ad-hoc signed; clear the quarantine attribute after downloading:: xattr -dr com.apple.quarantine /path/to/OBS.app -Roadmap -------- - -See `ROADMAP.md `_ for the planned feature set and milestone -ordering. - Building from source -------------------- @@ -81,41 +83,26 @@ Quick start (Linux):: cmake --preset ubuntu-x86_64 cmake --build --preset ubuntu-x86_64 -A Command-Line-Tools-only macOS build using Ninja is in progress on -``feature/macos-clt-build`` but is not currently the recommended local path. - -Contributing ------------- - -This is a personal fork. External contributions are welcome but not actively -solicited at this stage. If you do open a pull request: - -- Read the upstream coding guidelines: - https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.md -- Follow the upstream code style: - https://github.com/obsproject/obs-studio/blob/master/CODESTYLE.md -- Open work-in-progress changes against ``dev``, not ``master``. - ``master`` tracks upstream OBS Studio so upstream changes can be pulled in - cleanly. -- Run the project's formatters before pushing — CI rejects unformatted - changes:: - - ./build-aux/run-format clang-format - ./build-aux/run-gersemi - License ------- -OBS Studio Plus is distributed under the GNU General Public License v2 (or -any later version), the same license as upstream OBS Studio. See ``COPYING`` -for details. +The engine code in this repository (everything that links ``libobs``, +including any code we add under ``engine/``) is distributed under the GNU +General Public License v2 (or any later version), the same license as +upstream OBS Studio. See ``COPYING`` for details. + +The Plus desktop app — which lives in a separate repository — does not +link ``libobs``. It communicates with ``plus-host`` over IPC. That +separation is load-bearing for keeping the Plus app closed-source-capable. +Don't break it. Quick links ----------- - This fork: https://github.com/OgBops/obs-studio-plus +- Plan: `PLUS_PLAN.md `_ +- Fork rules: `CONTRIBUTING.md `_ - Upstream OBS Studio: https://github.com/obsproject/obs-studio -- Upstream OBS website: https://obsproject.com - Upstream developer/API documentation: https://obsproject.com/docs Acknowledgements @@ -125,8 +112,8 @@ OBS Studio Plus is built on top of the work of the OBS Studio team and its hundreds of contributors. See the ``AUTHORS`` file for the full list. This fork would not exist without their work. -If you would like to support upstream OBS Studio (which is recommended, since -this fork depends on their continued work), see +If you would like to support upstream OBS Studio (which is recommended, +since this fork depends on their continued work), see https://obsproject.com/contribute. .. |build-status| image:: https://github.com/OgBops/obs-studio-plus/actions/workflows/push.yaml/badge.svg?branch=dev diff --git a/ROADMAP.md b/ROADMAP.md index 9975997c7e6e6c..f5854d94eb3aac 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,124 +1,20 @@ -# OBS Studio Plus — Roadmap +# Roadmap -This roadmap tracks the planned feature set for OBS Studio Plus, the goals -behind each anchor feature, and the current status. Things will change as we -build. +The high-level roadmap and planning document is `PLUS_PLAN.md`. This file +is preserved as a pointer so links from the README and elsewhere don't +break. -## Guiding principles +→ See **[PLUS_PLAN.md](PLUS_PLAN.md)** for: -- **Don't break upstream compatibility.** Scenes, profiles, plugins, and - collections from upstream OBS must continue to load. We add capability - rather than diverge. -- **Local-first.** Anything that touches a streamer's content (audio, video, - metadata) runs on their machine by default. Cloud features are opt-in and - clearly disclosed. -- **Stay mergeable with upstream.** `master` tracks upstream OBS Studio. All - fork-specific work happens on `dev` and feature branches that periodically - merge `master`. We will surface upstream-equivalent features the moment - upstream ships them, and keep our changes small enough to rebase. -- **Plugins over core hacks.** Whenever a feature can ship as a plugin, it - ships as a plugin. The only changes that go into `libobs` and the frontend - are ones that genuinely require it (e.g., multi-canvas UI surfacing). +- The Plus app architecture +- Hard constraints (OBS core is read-only) +- All 9 phases with timelines +- Phase 0 (the current work) details +- Risk register -## Anchor features +→ See **[CONTRIBUTING.md](CONTRIBUTING.md)** for: -These three are the reason this fork exists. Everything else is a stretch -goal. - -### 1. Multi-destination streaming (Status: planned, v0.1 target) - -Stream to N services simultaneously from one OBS instance, with per-destination -bitrate, resolution, and encoder settings. - -**Why now:** Upstream OBS supports multi-output through `obs_output_t`'s API, -and the `WHIPSimulcastEncoders` pattern in -`frontend/utility/WHIPSimulcastEncoders.hpp` already creates parallel encoder -chains. The core supports it. The UI doesn't. - -**Approach:** -- Vectorize `streamOutput` in `frontend/utility/BasicOutputHandler.{hpp,cpp}` - from a single output to a `std::vector`. -- New dock: `frontend/widgets/MultiDestinationDock.{hpp,cpp}` listing each - target with live status (connected / bitrate / dropped frames). -- Settings UI: extend `frontend/settings/OBSBasicSettings_Stream.cpp` to a - list of services rather than a single service. -- Optional: shared encoder mode (one encode, N muxers) when destinations - match resolution; per-destination encoders otherwise. - -**Risk:** Encoder licensing and per-platform service rules (e.g., Twitch -ToS on simultaneous streaming). Document, don't enforce. - -### 2. Native multi-canvas (Status: planned, v0.2 target) - -Run a 16:9 horizontal canvas and a 9:16 vertical canvas simultaneously from -one OBS instance. Stream each independently. Switch scenes per-canvas. - -**Why now:** The upstream `obs_canvas_t` API in `libobs/obs-canvas.c` is -complete. `OBSBasic.hpp` already declares `std::vector canvases`. -The C++ wrapper (`frontend/utility/OBSCanvas.{hpp,cpp}`) is in place. -`obs_view_add2` accepts a per-canvas `obs_video_info`. The frontend UI is the -last missing piece. - -**Approach:** -- Surface canvas management UI in `frontend/widgets/OBSBasic_Canvases.cpp` - (currently 62 lines of barebones plumbing). -- Multi-preview: extend `frontend/widgets/OBSBasic_Preview.cpp` to render N - canvases (tabbed or side-by-side). -- Per-canvas scene/source lists in - `frontend/widgets/OBSBasic_{Scenes,SceneItems}.cpp`. -- Audit every implicit `obs_get_video()` call in the frontend and route - through the active canvas instead. - -**Risk:** Hundreds of frontend call sites assume one canvas. The work is -diffuse, not deep. Estimate 4-6 weeks for one engineer. - -### 3. Modern UI + AI plugin suite (Status: planned, v0.2 target) - -A refreshed visual identity plus a starter set of local-AI features that -replace third-party paid plugins. - -**Why now:** Streamlabs and Streamerbot are eating OBS's mindshare on -polish. NVIDIA Broadcast and Aitum Vertical are paid third-party tools doing -things OBS could do natively. - -**Approach:** - -- **Theme:** new `.ovt` theme file in `frontend/data/themes/` based on the - existing Yami variable system. Refreshed icon set. -- **AI Captions plugin** (`plugins/obs-ai-captions/`): audio source filter - wrapping `whisper.cpp`. Real-time captions overlaid on canvas, optional - translation. Modeled after `plugins/obs-filters/noise-suppress-filter.c`. -- **AI Auto-framing plugin** (`plugins/obs-ai-autoframe/`): video source - filter running a small subject-detection model (MediaPipe or YOLO-nano) - and feeding the result into the source's transform. -- **DeepFilterNet noise suppression**: extend - `plugins/obs-filters/noise-suppress-filter.c` with a third backend - alongside RNNoise and NVIDIA NoiseRemoval. - -**Risk:** Model size and licensing. Default to small, permissively-licensed -models. Larger models behind opt-in download. - -## Stretch features (not committed) - -- Auto-highlight detection from stream recordings (post-stream offline tool). -- Smart scene switching (replace Advanced Scene Switcher rule trees with a - small classifier). -- Unified Go-Live panel that combines stream key entry, multi-destination - config, and pre-stream checks into one dialog. -- Built-in chat overlay with multi-platform aggregation (Twitch + YouTube + - Kick into one feed). - -## Versioning - -- **v0.1** — Multi-destination streaming. Modern theme. Renamed brand - (this README, splash screen, application name). -- **v0.2** — Native multi-canvas UI. AI captions plugin shipping by default. -- **v0.3** — Auto-framing plugin. DeepFilterNet noise suppression. Unified - Go-Live panel. - -Versions are aspirational, not contractual. We ship when it's stable. - -## How to contribute - -See `README.rst`. Open issues against this fork for fork-specific work; open -issues against upstream OBS for bugs that exist there too. +- Off-limits paths +- The "smell test" for any change outside `engine/` +- How to escalate when libobs is genuinely missing what we need +- Branching policy From 15647287da88464a8a88ad9cbfd54086c2c32191 Mon Sep 17 00:00:00 2001 From: OgBops Date: Fri, 22 May 2026 16:17:04 -0700 Subject: [PATCH 17/17] docs: rename project to Mosaic (trademark separation) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The OBS Project requested we stop using "OBS" branding in this fork. Renaming everything that was forward-facing as "OBS Studio Plus" or "Plus" to "Mosaic". The repository on GitHub has been renamed to OgBops/mosaic in the same change; old OBS-branded CI artifacts have been deleted from the Actions tab. Concretely: - README.rst: rewritten under the Mosaic name with an explicit trademark notice section. No public binary releases until the Mosaic app exists with its own branding. - CONTRIBUTING.md (fork section): renamed; added a "Branding separation" subsection codifying that we don't redistribute upstream-branded binaries. - PLUS_PLAN.md → MOSAIC_PLAN.md: full plan updated; project history notes the rename. plus-host → mosaic-host throughout. New risk entry for trademark separation. - ROADMAP.md: stub now points at MOSAIC_PLAN.md. - .github/workflows/no-core-changes.yaml: error message references Mosaic. - .github/workflows/push.yaml: top comment updated. - .gitignore: PLUS_PLAN.md allowlist replaced with MOSAIC_PLAN.md. Local clone path stays as ~/Desktop/obs-studio because the directory is the upstream source we work in, not the product. The product name doesn't have to match the local directory name. --- .github/workflows/no-core-changes.yaml | 8 +- .github/workflows/push.yaml | 2 +- .gitignore | 2 +- CONTRIBUTING.md | 68 +++++++++----- PLUS_PLAN.md => MOSAIC_PLAN.md | 98 +++++++++++--------- README.rst | 122 +++++++++++++------------ ROADMAP.md | 4 +- 7 files changed, 168 insertions(+), 136 deletions(-) rename PLUS_PLAN.md => MOSAIC_PLAN.md (61%) diff --git a/.github/workflows/no-core-changes.yaml b/.github/workflows/no-core-changes.yaml index 07c2e45a1794f6..781e9427eb9869 100644 --- a/.github/workflows/no-core-changes.yaml +++ b/.github/workflows/no-core-changes.yaml @@ -1,7 +1,7 @@ name: No Core Changes -# Enforces the obs-studio-plus fork rule: libobs/, plugins/, deps/, and the -# C++/Qt parts of frontend/ track upstream OBS Studio untouched. Only files -# under engine/, CI infrastructure, and explicitly-allowlisted fork-specific +# Enforces the Mosaic fork rule: libobs/, plugins/, deps/, and the C++/Qt +# parts of frontend/ track upstream OBS Studio untouched. Only files under +# engine/, CI infrastructure, and explicitly-allowlisted fork-specific # build fixes may diverge. # # See CONTRIBUTING.md for the full policy. @@ -87,7 +87,7 @@ jobs: echo "${CHANGED}" echo '---' echo '' - echo 'See CONTRIBUTING.md ("OBS Studio Plus — Fork Contribution Rules").' + echo 'See CONTRIBUTING.md ("Mosaic — Fork Contribution Rules").' echo 'OBS core (libobs, plugins, frontend C++) tracks upstream untouched.' echo '' echo 'Options:' diff --git a/.github/workflows/push.yaml b/.github/workflows/push.yaml index cdd1d5b9561102..1a8ae1172d8356 100644 --- a/.github/workflows/push.yaml +++ b/.github/workflows/push.yaml @@ -1,5 +1,5 @@ name: Push -# obs-studio-plus fork: re-register after enabling Actions +# Mosaic fork: triggers on dev and engine/** branches run-name: ${{ github.ref_name }} push run 🚀 on: push: diff --git a/.gitignore b/.gitignore index 77f8b4427eb64c..1cbef1a12ad7cb 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ !INSTALL !README.rst !ROADMAP.md -!PLUS_PLAN.md +!MOSAIC_PLAN.md !/engine # Exclude lock files diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 42c9a58a1c91e8..35b5410ffc203b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,28 +1,30 @@ -OBS Studio Plus — Fork Contribution Rules -========================================= +Mosaic — Fork Contribution Rules +================================ -> The section below is **specific to this fork** (`OgBops/obs-studio-plus`). +> The section below is **specific to this fork** (`OgBops/mosaic`). > Upstream OBS Studio's full contribution guide follows further down and > applies to any code that is intended to be submitted upstream. -This repository is the **engine** for the Plus desktop app. Plus is a -separate user-facing product (separate repository, future). This fork -exists for one reason: produce a headless `plus-host` binary that runs -`libobs` in a sidecar process and exposes its functionality over IPC. +This repository hosts `mosaic-host`, the engine for the Mosaic desktop +app. Mosaic is a separate user-facing product (separate repository, +future). This fork exists for one reason: produce a headless +`mosaic-host` binary that runs the upstream broadcasting engine in a +sidecar process and exposes its functionality over IPC. -## The hard rule: OBS core is read-only +## The hard rule: upstream broadcasting code is read-only -We do **not** modify the engine, plugins, or any code that ships as part of -upstream OBS Studio. The fork's value is in keeping libobs unmodified so -upstream changes merge cleanly forever. +We do **not** modify the upstream broadcasting engine, its plugins, or +any code that ships as part of upstream OBS Studio. The fork's value is +in keeping the upstream code unmodified so upstream changes merge cleanly +forever. ### Off-limits paths | Path | What it is | |------|-----------| -| `libobs/` | The OBS engine itself | +| `libobs/` | The upstream broadcasting engine | | `libobs-d3d11/`, `libobs-opengl/`, `libobs-winrt/` | Engine GPU backends | -| `plugins/` | Every encoder, capture source, filter, output | +| `plugins/` | Every upstream encoder, capture source, filter, output | | `frontend/` (C++/Qt code) | Upstream Qt UI. We don't link it; we also don't modify it. | | `deps/` | Third-party dependencies as upstream ships them | @@ -30,7 +32,7 @@ upstream changes merge cleanly forever. | Path | Purpose | |------|---------| -| `engine/` | All Plus engine code (IPC server, host wrapper). New code lives here. | +| `engine/` | All Mosaic engine code (IPC server, host wrapper). New code lives here. | | `.github/workflows/`, `.github/scripts/`, `.github/actions/` | CI infrastructure | | `cmake/common/versionconfig.cmake` | Already-shipped fork-specific build robustness fix | | `frontend/cmake/os-linux.cmake` | Already-shipped flatpak metadata fix | @@ -44,9 +46,9 @@ Before any commit outside `engine/`: > "Would this change still be correct if we deleted the entire fork tomorrow > and submitted it upstream as a PR?" -If yes, fine. If no, you're modifying core. Stop. +If yes, fine. If no, you're modifying upstream code. Stop. -## What if libobs is genuinely missing what we need? +## What if the upstream engine is genuinely missing what we need? We file the change **upstream first**. @@ -58,11 +60,11 @@ We file the change **upstream first**. We do not carry local core patches. The discipline is the point. -## Where Plus engine code goes +## Where Mosaic engine code goes ``` engine/ -├─ host/ # plus-host binary: links libobs, runs IPC server +├─ host/ # mosaic-host binary: links the upstream engine, runs IPC server │ ├─ ipc/ # newline-JSON IPC protocol implementation │ ├─ methods/ # IPC method handlers (capture, output, scenes...) │ └─ main.cpp # entry point @@ -81,12 +83,30 @@ To intentionally update the allowlist (rare — only for upstream-able fork-specific build/CI fixes), edit the allowlist in the workflow itself and reference the upstream issue or PR. +## Branding separation (trademark) + +"OBS" and "OBS Studio" are trademarks of the OBS Project. Mosaic is an +independent project and does not redistribute upstream-branded binaries. +Specifically: + +- The Mosaic desktop app, when it exists, has its own name, icon, and + bundle identifier — it never ships as "OBS.app" or + `com.obsproject.obs-studio`. +- This repository's `master` branch carries upstream code with its + original branding, but `master` is never tagged or released from this + repository. +- The CI artifacts produced from `dev` are for our own development + verification only and are not redistributed publicly. +- Any release artifact from this repository must be built from + `engine/`-only code, or from a `dev` HEAD where the build has been + explicitly re-branded. + ## Branching | Branch | Purpose | |--------|---------| | `master` | Tracks upstream OBS Studio. Untouched. | -| `dev` | Integration branch. Branding, CI, the engine entry points land here. | +| `dev` | Integration branch. Mosaic docs, CI, the engine entry points land here. | | `engine/` | Active engine work. Branch off `dev`. | | `engine/spike` | Phase 0 spike. Temporary; deleted after the spike retro. | @@ -94,12 +114,12 @@ Open work-in-progress PRs against `dev`, never `master`. ## License -Files in `engine/` are licensed under the GPL v2 or later, same as upstream -OBS Studio, because they link `libobs`. +Files in `engine/` are licensed under the GPL v2 or later, same as the +upstream broadcasting source, because they link the upstream engine. -The Plus app (separate repository) does **not** link `libobs` — it -communicates with `plus-host` over IPC — and is therefore not subject to -GPL. That separation is load-bearing. Keep it that way. +The Mosaic app (separate repository) does **not** link the upstream +engine — it communicates with `mosaic-host` over IPC — and is therefore +not subject to GPL. That separation is load-bearing. Keep it that way. --- diff --git a/PLUS_PLAN.md b/MOSAIC_PLAN.md similarity index 61% rename from PLUS_PLAN.md rename to MOSAIC_PLAN.md index 43f9364cc9e1a7..bdef6f70b915d1 100644 --- a/PLUS_PLAN.md +++ b/MOSAIC_PLAN.md @@ -1,70 +1,74 @@ -# Plus — Project Plan +# Mosaic — Project Plan -This document is the north star for `obs-studio-plus`. When in doubt about +This document is the north star for the Mosaic project. When in doubt about scope, refer back here. When this document is wrong, update it before writing code that contradicts it. ## What we're building -**Plus** — a cross-platform desktop streaming app, owned end-to-end, that -covers three streaming modes: general (OBS-like), vertical-first -(TikTok/Shorts/Reels), and podcast/interview-style. +**Mosaic** — a cross-platform desktop streaming app, owned end-to-end, +that covers three streaming modes: general streaming (OBS-like), vertical- +first (TikTok/Shorts/Reels), and podcast/interview-style. ## Architecture -Plus is two binaries: +Mosaic is two binaries: ``` -┌─ Plus.app ─────────────────────────────────────┐ -│ Rust + Tauri (this repo: not yet created) │ +┌─ Mosaic.app ───────────────────────────────────┐ +│ Rust + Tauri (separate repo, not yet created) │ │ - UI shell (TypeScript/React in webview) │ │ - Mode logic (general / vertical / podcast) │ │ - Multi-destination fanout policy │ -│ - Talks to plus-host over IPC │ +│ - Talks to mosaic-host over IPC │ │ │ │ Closed-source-capable (no GPL linkage) │ └──────────────────┬──────────────────────────────┘ │ named pipe (Win) / Unix socket (mac/linux) │ + shared GPU texture handle (later phase) ┌──────────────────▼──────────────────────────────┐ -│ plus-host (THIS REPO, the OBS fork) │ -│ - libobs + every upstream plugin │ +│ mosaic-host (THIS REPO, derived from OBS) │ +│ - Upstream broadcasting engine + plugins │ │ - IPC server (engine/host/ipc) │ │ - IPC method handlers (engine/host/methods) │ │ - No Qt frontend │ │ │ -│ GPL v2 (same as upstream OBS Studio) │ +│ GPL v2 (same as the upstream source) │ └──────────────────────────────────────────────────┘ ``` The architecture mirrors how Streamlabs Desktop works (their -`obs-studio-node` is the analog of our `plus-host`). The legal point of -running libobs in a sidecar process is that the GPL boundary stops at -the IPC pipe. The Plus app does not link libobs and is not a derived -work. +`obs-studio-node` is the analog of our `mosaic-host`). The legal point of +running the broadcasting engine in a sidecar process is that the GPL +boundary stops at the IPC pipe. The Mosaic app does not link the +broadcasting engine and is not a derived work. ## Hard constraints -- **OBS core is read-only** — see `CONTRIBUTING.md`. Enforced in CI by - `.github/workflows/no-core-changes.yaml`. -- **Plus must remain closed-source-capable.** No statically-linked GPL - code. No `#include` paths into libobs from the Plus side. IPC only. -- **Upstream merges stay clean.** `master` tracks `obsproject/obs-studio` - untouched. Quarterly merge into `dev`. +- **Upstream broadcasting code is read-only** — see `CONTRIBUTING.md`. + Enforced in CI by `.github/workflows/no-core-changes.yaml`. +- **Mosaic must remain closed-source-capable.** No statically-linked GPL + code in the Mosaic app. No `#include` paths into the broadcasting + engine from the Mosaic side. IPC only. +- **Upstream merges stay clean.** `master` tracks upstream untouched. + Quarterly merge into `dev`. +- **Trademark separation.** Mosaic uses its own name, icon, bundle ID, + and branding. We do not redistribute upstream-branded binaries from + this repository. ## Phases | # | Phase | Weeks | What lands | |---|-----------------------------------|-------|------------| | 0 | Spike & validate | 2 | 200-LOC Rust + 400-LOC C++ end-to-end pipeline. Two binaries, one pipe, one RTMP stream. Both platforms. Throwaway. | -| 1 | Strip Qt, real IPC server | 6 | `plus-host` builds without `frontend/`. JSON-RPC IPC server. `ping`/`version`/`shutdown`. | +| 1 | Strip Qt, real IPC server | 6 | `mosaic-host` builds without `frontend/`. JSON-RPC IPC server. `ping`/`version`/`shutdown`. | | 2 | IPC protocol v0.1 | 8 | Scene/source/output CRUD over IPC. Streaming start/stop. Stats. Settings persistence. CLI test client. | | 3 | Shared GPU texture preview | 6 | D3D11 shared handles (Win), IOSurface (mac), DMA-BUF (Linux). Zero-copy 60fps preview. Hardest piece. | -| 4 | Plus shell — General mode | 8 | Tauri app. Source list, scene editor, "Go Live". Functional parity with vanilla OBS for single-destination. | -| 5 | Multi-destination (local fanout) | 4 | N parallel `obs_output_t` instances. Per-destination bitrate. UI for adding destinations. | +| 4 | Mosaic shell — General mode | 8 | Tauri app. Source list, scene editor, "Go Live". Functional parity with general streaming for single-destination. | +| 5 | Multi-destination (local fanout) | 4 | N parallel output instances. Per-destination bitrate. UI for adding destinations. | | 6 | Vertical mode | 4 | 9:16 canvas, source layout templates, vertical default scenes. | | 7 | Podcast mode P0 | 12 | WebRTC mesh ≤4 participants. Guests join via web client (no install). Live composite. No per-participant local recording yet. | -| 8 | Podcast mode P1 | 10 | Per-participant local recording in browser via MediaRecorder. Background upload. Post-session merge. The Riverside-killer piece. | +| 8 | Podcast mode P1 | 10 | Per-participant local recording in browser via MediaRecorder. Background upload. Post-session merge. | | 9 | Polish & ship | 8 | Code signing on both platforms. Auto-updater. Installers. Telemetry (opt-in). Marketing site. Public beta. | **Total realistic timeline: ~80 weeks (1.5 years).** Slack accounted for. @@ -76,7 +80,7 @@ work. - **End of phase 6:** if vertical-first turns out to be the killer mode, ship vertical alone as the public beta. Phases 7–8 can wait. - **End of phase 8:** podcast mode is the riskiest. If it's not working - at week 60, cut it. Plus ships as a 2-mode product. Podcast is v2. + at week 60, cut it. Mosaic ships as a 2-mode product. Podcast is v2. ## Phase 0 — feasibility spike @@ -86,11 +90,11 @@ See `engine/spike/PLAN.md` (created at the start of phase 0). end-to-end pipeline. **Done = green checkmark on every line:** -1. ✅ `plus-host-spike` builds and runs on macOS arm64 and Windows x64 -2. ✅ `plus-spike-client` (Rust) connects to it on both platforms +1. ✅ `mosaic-host-spike` builds and runs on macOS arm64 and Windows x64 +2. ✅ `mosaic-spike-client` (Rust) connects to it on both platforms 3. ✅ End-to-end stream works on both (verified by ffplay) 4. ✅ Both processes exit cleanly under normal shutdown -5. ✅ Total new C++ code in `plus-host-spike` < 600 LOC +5. ✅ Total new C++ code in `mosaic-host-spike` < 600 LOC 6. ✅ Total Rust code < 300 LOC 7. ✅ `git diff upstream/master..HEAD -- libobs/ plugins/ frontend/cpp deps/` is empty @@ -101,11 +105,11 @@ doubles. ## Repo layout, target ``` -obs-studio-plus/ -├─ master/ ← tracks upstream OBS, untouched -├─ dev/ ← integration: branding, CI, engine entry points +mosaic/ +├─ master/ ← tracks upstream broadcasting source, untouched +├─ dev/ ← integration: Mosaic docs, CI, engine entry points ├─ engine/spike/ ← phase 0, throwaway -├─ engine/host/ ← plus-host (phases 1+) +├─ engine/host/ ← mosaic-host (phases 1+) │ ├─ ipc/ ← JSON-RPC server │ ├─ methods/ ← IPC method handlers │ └─ main.cpp @@ -116,8 +120,8 @@ obs-studio-plus/ └─ ... ← upstream as-is ``` -The Plus app itself lives in a separate repository (created at the start -of phase 4). +The Mosaic desktop app itself lives in a separate repository (created at +the start of phase 4). ## Risk register (top of mind) @@ -126,19 +130,23 @@ of phase 4). | Shared GPU texture path differs subtly per platform/GPU | High | High | Phase 0 spike on real hardware. CPU-fallback path planned. | | Stripping Qt cascades through more code than expected | Medium | High | Don't delete `frontend/` immediately — make it not link, then prune. Preserves upstream merge compat. | | GPL boundary gets challenged | Low | Existential | Follow Streamlabs' pattern exactly: separate process, IPC only, no shared address space. Document the design decision. | -| Upstream OBS API changes break plus-host | Medium/quarter | Medium | Track `master` against upstream, merge quarterly, fix breakage. | +| Trademark dispute with upstream re-emerges | Low (now) | High | Renamed 2026-05-22. Ongoing: strict branding separation in any user-facing artifact. | +| Upstream API changes break mosaic-host | Medium/quarter | Medium | Track `master` against upstream, merge quarterly, fix breakage. | | Podcast WebRTC stack is its own 6-month project | High | Medium | Use existing libraries (`webrtc-rs`, `mediasoup`). Don't roll our own SFU. | | Code signing gets stuck on dev enrollment | Medium | Low (delay) | Apply for Apple Developer Program + Windows EV cert before phase 9. | | First 100 beta users find a thousand bugs | Certain | Medium | Phase 9 includes telemetry + crash reporting from day 1. | -## What this plan replaces - -The previous OBS-Plus roadmap (multi-destination dock, AI captions plugin, -Qt-frontend feature work) is **abandoned**. The work wasn't wasted — concepts -move into the IPC protocol — but the Qt path is no longer the route to those -features. See git history on the deleted branches: -`feature/multi-output-foundation`, `feature/multi-destination-dock`, -`feature/ai-captions-plugin`. +## Project history + +- **2026-05-17:** Cloned upstream OBS, started exploring as "OBS Studio Plus" + fork. +- **2026-05-22 (early):** CI green on all 6 platforms after no-tag survival + patches. +- **2026-05-22 (mid):** Pivot from "OBS with Qt features" to engine-for-Mosaic + architecture. +- **2026-05-22 (late):** Renamed from "OBS Studio Plus" to **Mosaic** after + trademark notice from the OBS Project. All public OBS-branded artifacts + deleted from CI. Repository renamed to `OgBops/mosaic`. ## Updating this document diff --git a/README.rst b/README.rst index 466cd2bfa29c0e..5566e2380b02f4 100644 --- a/README.rst +++ b/README.rst @@ -1,34 +1,36 @@ -OBS Studio Plus -=============== +Mosaic +====== |build-status| -This repository is the **engine** for the Plus desktop app — a future -cross-platform streaming application that covers general streaming, -vertical-first content (TikTok / Shorts / Reels), and podcast/interview -workflows. +Mosaic is a cross-platform desktop streaming application targeting three +modes: general streaming, vertical-first content (TikTok / Shorts / Reels), +and podcast/interview workflows. -It is a fork of `OBS Studio `_ that exists for one -specific purpose: to produce a headless ``plus-host`` binary which runs -``libobs`` in a sidecar process and exposes its functionality over IPC. -The Plus desktop app (separate repository, written in Rust + Tauri) talks -to ``plus-host`` over a named pipe. +This repository hosts ``mosaic-host``, the engine. It is a fork of +`OBS Studio `_ stripped to a headless binary that +runs the upstream broadcasting engine in a sidecar process and exposes its +functionality over local IPC. The Mosaic desktop app (separate repository, +written in Rust + Tauri) talks to ``mosaic-host`` over a named pipe. -This is the same architecture Streamlabs Desktop uses with their -``obs-studio-node`` — running libobs out of process keeps the GPL boundary -at the IPC layer so the Plus app itself can be developed under any -license, while the engine here remains GPL v2 like upstream OBS. +Running the broadcasting engine out of process keeps the GPL boundary at +the IPC layer so the Mosaic app itself can be developed under any license, +while ``mosaic-host`` remains GPL v2 like the upstream code it links. + +This is **not** a re-distribution of OBS Studio. Mosaic is a separate +product. See the `OBS Studio project `_ for the +original software. Status ------ -**Pre-alpha.** The fork has just pivoted from "OBS with extra Qt features" -to "engine for a separate app." Phase 0 (a 2-week feasibility spike) is -the current work. There is no shippable product yet. +**Pre-alpha.** The repository is in the middle of a foundational rebuild. +Phase 0 (a 2-week feasibility spike) is the current work. There is no +shippable product yet, and no public binary releases. -Today, a build from ``dev`` looks and behaves exactly like vanilla OBS -Studio — that is intentional. The engine wrapper and the Plus app land in -later phases. See `PLUS_PLAN.md `_ for the full plan. +Today, a build from ``dev`` is just the upstream broadcasting source — +that is intentional. The engine wrapper and the Mosaic app land in later +phases. See `MOSAIC_PLAN.md `_ for the full plan. Repository layout ----------------- @@ -37,40 +39,33 @@ Repository layout Branch / path What it is ================================ =============================================== ``master`` Tracks upstream OBS Studio, untouched. -``dev`` Integration branch. Branding, CI fixes for - the no-tags state, engine entry points land - here. CI builds all 6 platforms green. +``dev`` Integration branch. Mosaic-specific docs, CI + fixes, engine entry points land here. ``engine/spike`` Phase 0 spike. Created at the start of phase 0, deleted after the retro. -``engine/host`` ``plus-host`` proper (created in phase 1). -``libobs/``, ``plugins/``, Read-only mirror of upstream OBS. Modifying -``frontend/`` C++ these files fails CI. +``engine/host`` ``mosaic-host`` proper (created in phase 1). +``libobs/``, ``plugins/``, Read-only mirror of the upstream broadcasting +``frontend/`` C++/Qt source. Modifying these files fails CI. ================================ =============================================== -The hard rule: see `CONTRIBUTING.md `_. OBS core is -read-only in this fork. The CI workflow ``no-core-changes.yaml`` enforces -the rule by diffing against ``upstream/master``. +The hard rule: see `CONTRIBUTING.md `_. Upstream broadcasting +core code is read-only in this fork. The CI workflow ``no-core-changes.yaml`` +enforces the rule by diffing against ``upstream/master``. Downloads --------- -CI produces prebuilt binaries for every push to ``dev`` and ``engine/**``. -Today these are vanilla OBS builds. Artifacts (macOS arm64/x86_64 ``.dmg``, -Ubuntu 24.04 ``.deb``, Flatpak, Windows x64/arm64 zips) are attached to -each successful run on the -`Actions tab `_ and -expire 90 days after the build. - -There is no signed release yet. macOS builds are ad-hoc signed; clear the -quarantine attribute after downloading:: - - xattr -dr com.apple.quarantine /path/to/OBS.app +There are no public binary releases at this time. CI builds the upstream +broadcasting source on every push to ``dev`` and ``engine/**`` for our own +verification, but those builds are not redistributed. Public Mosaic +releases will begin once the Mosaic desktop app exists in its own +repository under its own application name. Building from source -------------------- -Build instructions are identical to upstream OBS Studio. The upstream wiki -covers platform setup: +Build instructions for ``mosaic-host`` follow upstream OBS Studio's build +process. The upstream wiki covers platform setup: https://github.com/obsproject/obs-studio/wiki/Install-Instructions Quick start (macOS, requires full Xcode.app):: @@ -86,36 +81,45 @@ Quick start (Linux):: License ------- -The engine code in this repository (everything that links ``libobs``, -including any code we add under ``engine/``) is distributed under the GNU -General Public License v2 (or any later version), the same license as -upstream OBS Studio. See ``COPYING`` for details. +The engine code in this repository (everything that links the upstream +broadcasting engine, including any code we add under ``engine/``) is +distributed under the GNU General Public License v2 (or any later +version), the same license as the upstream source. See ``COPYING`` for +details. + +The Mosaic desktop app — which lives in a separate repository — does not +link the upstream engine. It communicates with ``mosaic-host`` over IPC. +That separation is load-bearing for keeping the Mosaic app +closed-source-capable. Don't break it. + +Trademark notice +---------------- -The Plus desktop app — which lives in a separate repository — does not -link ``libobs``. It communicates with ``plus-host`` over IPC. That -separation is load-bearing for keeping the Plus app closed-source-capable. -Don't break it. +"OBS" and "OBS Studio" are trademarks of the OBS Project. Mosaic is an +independent project and is not affiliated with, endorsed by, or sponsored +by the OBS Project. References to OBS Studio in this repository refer +solely to the upstream open-source project from which the engine code is +derived. Quick links ----------- -- This fork: https://github.com/OgBops/obs-studio-plus -- Plan: `PLUS_PLAN.md `_ +- This repository: https://github.com/OgBops/mosaic +- Plan: `MOSAIC_PLAN.md `_ - Fork rules: `CONTRIBUTING.md `_ - Upstream OBS Studio: https://github.com/obsproject/obs-studio -- Upstream developer/API documentation: https://obsproject.com/docs Acknowledgements ---------------- -OBS Studio Plus is built on top of the work of the OBS Studio team and its -hundreds of contributors. See the ``AUTHORS`` file for the full list. This -fork would not exist without their work. +Mosaic is built on top of the work of the OBS Studio team and its +hundreds of contributors. See the ``AUTHORS`` file for the full list. +This project would not exist without their work. If you would like to support upstream OBS Studio (which is recommended, since this fork depends on their continued work), see https://obsproject.com/contribute. -.. |build-status| image:: https://github.com/OgBops/obs-studio-plus/actions/workflows/push.yaml/badge.svg?branch=dev - :target: https://github.com/OgBops/obs-studio-plus/actions/workflows/push.yaml +.. |build-status| image:: https://github.com/OgBops/mosaic/actions/workflows/push.yaml/badge.svg?branch=dev + :target: https://github.com/OgBops/mosaic/actions/workflows/push.yaml :alt: dev branch build status diff --git a/ROADMAP.md b/ROADMAP.md index f5854d94eb3aac..a825b8f773684e 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -1,10 +1,10 @@ # Roadmap -The high-level roadmap and planning document is `PLUS_PLAN.md`. This file +The high-level roadmap and planning document is `MOSAIC_PLAN.md`. This file is preserved as a pointer so links from the README and elsewhere don't break. -→ See **[PLUS_PLAN.md](PLUS_PLAN.md)** for: +→ See **[MOSAIC_PLAN.md](MOSAIC_PLAN.md)** for: - The Plus app architecture - Hard constraints (OBS core is read-only)