diff --git a/README.md b/README.md
index 7318a00c..ea5710a8 100644
--- a/README.md
+++ b/README.md
@@ -2,28 +2,27 @@
-
+
### Turn any Android phone into a wireless camera source for OBS Studio
-[](https://github.com/YashasVM/OpenStream/releases/tag/v1.0.1)
+[Latest release](https://github.com/YashasVM/OpenStream/releases/latest)
[](https://github.com/YashasVM/OpenStream)
[](https://obsproject.com)
[](https://openstream.pages.dev)
-**Open-source** | **One phone, one camera** | **Hardware phone encoding** | **Local Wi-Fi**
+**Source available** | **One phone, one camera** | **Hardware phone encoding** | **Local Wi-Fi**
---
> [!IMPORTANT]
-> This branch simplifies OpenStream to one Android camera per OBS process and adds a native Linux build. Published V1.0.1 downloads predate these changes. Candidate builds need the device acceptance checks in [docs/testing.md](docs/testing.md) before release.
+> The repository branch may contain changes that are not in the latest published release. Candidate builds need the device acceptance checks in [docs/testing.md](docs/testing.md) before release.
-The supported V1.0.1 path is the legacy Android app plus the legacy OBS camera
-source/dock over local Wi-Fi. USB transport and USB camera-source support are
-not included in this release.
+The latest published release may not include the changes on this branch. USB
+transport and USB camera-source support are not included in the published app.
## Quick Downloads
@@ -32,7 +31,7 @@ not included in this release.
| 1 | [`openstream-android.apk`](https://github.com/YashasVM/OpenStream/releases/latest/download/openstream-android.apk) | Android phone |
| 2 | [`openstream-obs-plugin-installer-windows-x64.exe`](https://github.com/YashasVM/OpenStream/releases/latest/download/openstream-obs-plugin-installer-windows-x64.exe) | Windows OBS PC |
| Fallback | [`openstream-obs-windows-x64.zip`](https://github.com/YashasVM/OpenStream/releases/latest/download/openstream-obs-windows-x64.zip) | Manual OBS plugin install |
-| Linux candidate | [Build and install from source](docs/linux.md) | Native Linux OBS; the next tagged release will include a matched Linux package |
+| Linux candidate | [Build and install from source](docs/linux.md) | Native Linux OBS; check the release assets for a published package |
Need the non-technical walkthrough with screenshots? Start with [`docs/set-up.md`](docs/set-up.md).
@@ -40,20 +39,19 @@ Need the non-technical walkthrough with screenshots? Start with [`docs/set-up.md
## What is OpenStream?
-OpenStream V1.0.1 sends your Android phone camera directly into OBS Studio over local Wi-Fi. It uses Camera2, MediaCodec video/audio encoding, MPEG-TS muxing, SRT transport, two-way LAN discovery, single-camera pairing, and a native OBS source plugin.
+OpenStream sends an Android phone camera to OBS Studio over local Wi-Fi. The app uses Camera2 and MediaCodec, then carries MPEG-TS video and audio over SRT to an OBS source plugin.
```text
Phone camera -> hardware AVC/H.264 + AAC -> SRT over Wi-Fi -> OpenStream camera source in OBS
```
-### V1.0.1 Release
+### Published V1.0.1 release
| Area | V1.0.1 release detail |
|---|---|
-| **OBS setup** | The V1.0.1 release uses its legacy source controls. The current candidate exposes controls in source properties. |
-| **Scene compatibility** | Existing `OpenStream V7` scene sources keep loading while new sources appear as `OpenStream V8`. |
-| **Pairing clarity** | One camera per OBS process, with a simple computer picker on Android. |
-| **Release polish** | Version defaults, release notes, and setup docs are aligned around V1.0.1. |
+| **OBS setup** | The published plugin registers the source identifiers found in the historical release. Actual saved-scene settings and media compatibility still need device and OBS checks. |
+| **Source identity** | The plugin displays the source name `shin`; the historical release registers `openstream_phone_v7_source` and `openstream_phone_v8_source`. |
+| **Published assets** | The release includes the Android APK and Windows installer and plugin archive. |
## Quick Start
@@ -66,7 +64,7 @@ Download the APK from the release, copy it to your Android phone, open it, and a
Connect the phone with USB debugging enabled and run `cd android && ./gradlew
installDebug`. Repeating this command installs the updated app in place when
the installed build has the same application ID and signing key. The version
-name and code come from `android/gradle.properties`; increase the code there
+name and code come from `release/version.properties`; increase the code there
for a release. Android rejects an in-place update if the APK uses a different
signing key, such as when switching between a local debug build and the
published release. Keep using the same build type for day-to-day updates.
@@ -80,15 +78,15 @@ Download and run `openstream-obs-plugin-installer-windows-x64.exe` on the Window
### 3. Add One Camera in OBS
-In OBS, click `+` in Sources, choose `OpenStream V8`, and press OK. Keep one OpenStream source. To use the camera in another scene, select **Add Existing**. If upgrading a scene with multiple camera sources, remove the extras; additional capture sessions are blocked with an explanation.
+In OBS, click `+` in Sources and choose `OpenStream Camera`. Keep one OpenStream source. To use the camera in another scene, select **Add Existing**. If upgrading a scene with multiple camera sources, remove the extras; additional capture sessions are blocked with an explanation.
### 4. Pair the Phone
-Open the OpenStream Android app on the same Wi-Fi network as the PC. Its discovery panel lists available OBS computers; tap yours to connect. The camera feed should appear in OBS within a few seconds.
+Open the OpenStream Android app on the same Wi-Fi network as the PC. Its discovery panel lists available OBS computers; tap yours to connect. Check the source status and phone preview to confirm that the camera connected.
### 5. Stream
-Use OBS as usual. Open **Docks → OpenStream Camera Control** for the camera controls. Phone audio appears on the OpenStream source’s OBS mixer channel.
+Use the OpenStream source properties for camera controls. Phone audio appears on the OpenStream source’s OBS mixer channel.
> [!TIP]
> Use a 5 GHz or Wi-Fi 6 network, keep both devices on the same subnet, and disable VPNs or router client isolation during first setup.
@@ -102,7 +100,7 @@ Use OBS as usual. Open **Docks → OpenStream Camera Control** for the camera co
| **Phone OS** | Android 10+ with Camera2 and hardware MediaCodec support. |
| **OBS host** | Windows x64: OBS Studio 32.2.1. Native Linux: build against the installed OBS, Qt, and FFmpeg packages; see [Linux setup](docs/linux.md). Flatpak/Snap builds are not covered. |
| **Network** | Same LAN/subnet; guest Wi-Fi, VPNs, and client isolation can block discovery. |
-| **Release maturity** | V1.0.1. Expect device-specific camera quirks and Wi-Fi-dependent latency. |
+| **Release maturity** | Camera behavior varies by device, and network latency depends on Wi-Fi conditions. |
---
@@ -124,7 +122,7 @@ Use OBS as usual. Open **Docks → OpenStream Camera Control** for the camera co
| **Manual Connect** | Enable **Receive manual connection from phone** in OBS advanced settings, then enter the PC IP/port on the phone. Remote camera controls stay on the phone in this mode. |
| **Live Stream Telemetry** | Shows frames, keyframes, transferred megabits, errors, and active lens while streaming. |
| **Identify Overlay** | Displays a connection label on the phone when triggered from OBS. |
-| **Reconnect Hold** | Keeps a reserved OBS connection for `45` seconds after a disconnect to make brief Wi-Fi drops less disruptive. |
+| **Reconnect Hold** | Keeps a reserved OBS connection for `45` seconds after a disconnect. |
### OBS Plugin
@@ -133,7 +131,7 @@ For native Linux build and installation instructions, see [docs/linux.md](docs/l
| Feature | Details |
|---|---|
-| **Native OBS Source** | Adds an `OpenStream V8` source type inside OBS Studio while preserving V7 scene compatibility. |
+| **Native OBS Source** | Adds an `OpenStream Camera` source type inside OBS Studio. Saved-scene settings and media compatibility with the published release still need verification. |
| **OBS controls** | Connection, phone selection, zoom, torch, lens, and identify controls are exposed through source properties. |
| **One-Click Installer** | Windows installer copies the plugin into the OBS plugin folder. |
| **Phone ownership** | Each phone can be reserved by one OBS source at a time. Reuse that source across scenes. |
@@ -267,7 +265,7 @@ This is a developer/debug tool only. Normal users should install the OBS plugin.
| Link | URL |
|---|---|
-| Website | [OpenStream V1.0.1](https://openstream.pages.dev) |
+| Website | [OpenStream](https://openstream.pages.dev) |
| Releases | [github.com/YashasVM/OpenStream/releases](https://github.com/YashasVM/OpenStream/releases) |
| Issues | [github.com/YashasVM/OpenStream/issues](https://github.com/YashasVM/OpenStream/issues) |
diff --git a/docs/release-notes-template.md b/docs/release-notes-template.md
index a8cb663d..a6e16f74 100644
--- a/docs/release-notes-template.md
+++ b/docs/release-notes-template.md
@@ -1,44 +1,28 @@
-# OpenStream V1.0.1
+# OpenStream {{VERSION}}
-OpenStream V1.0.1 is a fixed Android-to-OBS camera release with V8 source naming, V7 scene compatibility, universal Android packaging, and install downloads for both surfaces.
+{{SUMMARY_OF_THE_RELEASE}}
-## What's New
+## What's new
-| Area | Change |
-|---|---|
-| OBS setup | Source properties now follow `1. Camera Slot`, `2. Live Camera Controls`, and `3. Network & Pairing (Advanced)`. |
-| Scene compatibility | Existing `OpenStream V7` scene sources keep loading through a compatibility source id. |
-| Pairing copy | OBS now explains the phone-side slot selection flow instead of leading with SRT details. |
-| Setup docs | The walkthrough now includes stale-plugin checks for Program Files, ProgramData, and per-user OBS plugin folders. |
-| OBS compatibility | Windows plugin releases target OBS Studio 32.2.1 x64 and its FFmpeg 62/62/60/9 ABI. |
+- {{USER_VISIBLE_CHANGE}}
## Downloads
| File | Use |
|---|---|
-| `openstream-android.apk` | Install this on your Android phone. |
-| `openstream-android.apk.sha256` | Verify the downloaded APK before installation. |
-| `openstream-obs-plugin-installer-windows-x64.exe` | Recommended Windows installer for the OBS plugin. |
-| `openstream-obs-windows-x64.zip` | Manual plugin package with DLL and install scripts. |
-| `openstream-obs-windows-x64.zip.sha256` | Verify the downloaded manual plugin package. |
-
-> [!NOTE]
-> The Android APK is release-signed and accompanied by a SHA-256 checksum. Public releases fail instead of publishing a debug-signed fallback when signing inputs are unavailable.
-
-## Install
+| `openstream-android.apk` | Install on an Android phone. |
+| `openstream-obs-plugin-installer-windows-x64.exe` | Install the OBS plugin on Windows. |
+| `openstream-obs-windows-x64.zip` | Install the Windows plugin manually. |
+| `shin-obs-linux-x86_64.tar.gz` | Install the Linux plugin on a compatible system. |
-1. Install the APK on your Android phone.
-2. Run the OBS plugin installer on your Windows OBS PC.
-3. Restart OBS Studio.
-4. Add an `OpenStream V8` source.
-5. Open the Android app on the same Wi-Fi network and tap the discovered OBS slot.
+## Compatibility
-For the screenshot walkthrough, read [`docs/set-up.md`](https://github.com/YashasVM/OpenStream/blob/main/docs/set-up.md).
+- Android: {{ANDROID_COMPATIBILITY}}
+- Windows OBS: {{WINDOWS_OBS_COMPATIBILITY}}
+- Linux OBS: {{LINUX_OBS_COMPATIBILITY}}
+- Scene compatibility: {{SCENE_COMPATIBILITY_EVIDENCE}}
## Notes
-- Windows OBS plugin only.
-- Existing source names may still say `OpenStream V7`; rename them in OBS if you want the scene label to match V1.0.1.
-- Use 5 GHz or Wi-Fi 6 for best results.
-- Keep both devices on the same subnet.
-- Please report issues on GitHub.
+- {{KNOWN_LIMITATION_OR_MIGRATION_NOTE}}
+- See the [setup guide](https://github.com/YashasVM/OpenStream/blob/main/docs/set-up.md).
diff --git a/docs/release.md b/docs/release.md
index cc44b683..ede8bd40 100644
--- a/docs/release.md
+++ b/docs/release.md
@@ -36,27 +36,42 @@ The APK is universal with `minSdk 29` and native libraries for `arm64-v8a`,
`armeabi-v7a`, `x86`, and `x86_64`. Camera lens availability and device-specific
Camera2 behavior still require checking on target phones.
-## Automated Release
+## Build and publish a release
-Set both `openstream.versionName` and `openstream.versionCode` in
-`android/gradle.properties`, then create and push a matching `vMAJOR.MINOR.PATCH`
-tag that points to that commit. The version name must equal the tag without its
-leading `v`; the version code must be a positive integer greater than every
-previous release code and no greater than Android's 2,100,000,000 limit.
+Set `productVersion` and `androidVersionCode` in `release/version.properties`.
+The version must match the `vMAJOR.MINOR.PATCH` tag without its leading `v`.
+The version code must be greater than the previous published APK and no greater
+than Android's 2,100,000,000 limit.
```powershell
-git tag v1.0.1
-git push origin v1.0.1
+git tag vMAJOR.MINOR.PATCH
+git push origin vMAJOR.MINOR.PATCH
```
-The same workflow can be run manually with an already pushed release tag. It
-builds the commit referenced by that tag and rejects malformed or mismatched
-tags. It does not create a release from the current default branch. Older
-releases used the tag commit timestamp as the Android version code; the
-workflow uses that value when checking historical tags without the canonical
-`openstream.versionCode` property.
+Pushing a tag runs the `Release candidate` workflow. It builds the Android APK,
+the Windows installer and plugin archive, and the Linux plugin archive. It
+checks the tag, APK package, version code, signing certificate, plugin versions,
+installer version, and artifact hashes. It uploads a candidate bundle as a
+GitHub Actions artifact with `release-manifest.json`; it does not publish a release.
-The `Release` workflow builds:
+After the candidate passes the device and OBS checks, dispatch the same workflow
+in `publish` mode. Enter the tag and successful candidate run ID. The workflow
+checks that the candidate belongs to the tagged commit, verifies its manifest
+and hashes, then publishes those downloaded files without rebuilding them.
+If an earlier published APK cannot be fetched, publication fails closed.
+
+The staged manifest records the product version, Android identity, protocol,
+supported OBS ABIs, and each artifact's filename, size, and SHA-256 hash. The
+website shows a version and version-specific download links only after the
+latest published release contains this manifest and the GitHub release API
+reports the matching size and SHA-256 digest for every listed asset. The
+website also checks that each published checksum sidecar matches the manifest.
+Until those checks pass, the website labels the links "Latest release".
+
+The website's npm package version is build-tool metadata. Keep it at `0.0.0`;
+release version changes belong in `release/version.properties`.
+
+The candidate workflow builds these files:
| Job | Output |
|---|---|
@@ -65,10 +80,16 @@ The `Release` workflow builds:
| OBS plugin installer | `openstream-obs-plugin-installer-windows-x64.exe`, `openstream-obs-plugin-installer-windows-x64.exe.sha256` |
| Linux OBS plugin | `shin-obs-linux-x86_64.tar.gz`, `shin-obs-linux-x86_64.tar.gz.sha256` |
-The publish job runs only after repository tests, Android unit tests and lint,
-the signed Android build, and both Windows and Linux plugin builds succeed. It
-downloads all artifacts, verifies each published binary's SHA-256 sidecar, and
-then runs `gh release create`.
+The workflow requires repository tests, Android unit tests and lint, the signed
+Android build, and both Windows and Linux plugin builds to pass before it stages
+a candidate. The publish job verifies the staged SHA-256 sidecars before it
+creates a GitHub release.
+
+Prepare new release notes for every release. Copy
+[`release-notes-template.md`](release-notes-template.md) into the workflow's
+`release_notes` input and replace every placeholder with details verified for
+that release. Keep earlier published notes unchanged. The publish workflow
+requires non-empty notes and uses the submitted text as the release body.
Public releases require all Android signing secrets. Missing or incomplete
signing inputs fail the workflow; it never publishes a debug-signed fallback.
@@ -146,14 +167,15 @@ only; do not publish that APK as a release.
## Release Checklist
-- Confirm the README links point to the release tag being published.
+- Confirm the README links use the latest published assets.
- Confirm the setup guide links to the same APK, installer EXE, and plugin zip.
- Confirm pytest, Android unit tests, lint, and Android, Windows, and Linux release builds passed.
- Confirm `openstream-android.apk.sha256` matches the APK.
- Confirm `openstream-obs-plugin-installer-windows-x64.exe.sha256` matches the installer.
- Confirm `openstream-obs-windows-x64.zip.sha256` matches the manual plugin package.
- Confirm `shin-obs-linux-x86_64.tar.gz.sha256` matches the Linux package.
-- Confirm OBS lists `OpenStream V8` and can still load saved `openstream_phone_v7_source` scenes.
+- Confirm the published `release-manifest.json` matches each artifact's name, size, and SHA-256 hash.
+- Confirm OBS lists `OpenStream Camera` and test saved scenes from each published plugin version. Record settings and media results; do not infer them from source registration alone.
- Confirm the dependency report names `avformat-62.dll`, `avcodec-62.dll`, `avutil-60.dll`, and `swscale-9.dll`, and the clean OBS 32.2.1 log has no OpenStream module-load error.
- Seed `openstream-obs.dll`, run both installer forms, and confirm stale Program Files, ProgramData, and AppData copies were migrated without touching OBS settings or scenes.
- Confirm the Android APK is release-signed and installable over the previous public release.
diff --git a/tests/test_production_contracts.py b/tests/test_production_contracts.py
index 87ed924d..d2f8954b 100644
--- a/tests/test_production_contracts.py
+++ b/tests/test_production_contracts.py
@@ -140,7 +140,10 @@ def test_android_and_obs_release_artifacts_stay_atomic() -> None:
assert "python -m pytest -q" in android_workflow
assert ":app:lintDebug" in android_workflow
assert "openstream-android.apk.sha256" in android_workflow
- assert "android/gradle.properties" in release_docs
+ assert "release/version.properties" in release_docs
+ assert "android/gradle.properties" not in release_docs
+ assert "release-manifest.json" in release_docs
+ assert "inputs.release_notes" in release_workflow
assert "release/version.properties" in release_workflow
assert "productVersion=" in release_workflow
assert "androidVersionCode=" in release_workflow
diff --git a/tests/test_repo_contract.py b/tests/test_repo_contract.py
index a4387ce3..3fe1a709 100644
--- a/tests/test_repo_contract.py
+++ b/tests/test_repo_contract.py
@@ -302,7 +302,9 @@ def test_release_workflows_build_streaming_apk_and_plugin_package() -> None:
assert "release/version.properties" in release_workflow
assert "productVersion=" in release_workflow
assert "androidVersionCode=" in release_workflow
- assert "android/gradle.properties" in release_docs
+ assert "release/version.properties" in release_docs
+ assert "android/gradle.properties" not in release_docs
+ assert "release-manifest.json" in release_docs
assert "OPENSTREAM_SKIP_INSTALL=1" in obs_workflow
assert "OPENSTREAM_PLUGIN_PACKAGE_DIR" in obs_workflow
assert "openstream-obs-windows-x64.zip" in obs_workflow
@@ -383,6 +385,25 @@ def test_website_package_version_is_tooling_only() -> None:
assert package["version"] == "0.0.0"
+def test_website_uses_only_published_manifest_version_for_release_copy() -> None:
+ website = read("website/src/main.jsx")
+ index = read("website/index.html")
+ readme = read("README.md")
+
+ assert '"Latest release"' in website
+ assert "release-manifest.json" in website
+ assert "expected.sha256" in website
+ assert 'actual.digest !== `sha256:${expected.sha256}`' in website
+ assert "publishedRelease.version" in website
+ assert "V1.0.1" not in website + index
+ assert "releases/latest/download" in readme
+ assert "releases/tag/v1.0.1" not in readme
+ release_docs = read("docs/release.md")
+ assert "release_notes` input" in release_docs
+ assert "GitHub release API" in release_docs
+ assert "passes this template directly" not in release_docs
+
+
def test_shin_linux_release_includes_native_obs_dock_dependencies() -> None:
app_gradle = read("android/app/build.gradle.kts")
cmake = read("obs-plugin/CMakeLists.txt")
diff --git a/website/index.html b/website/index.html
index 846c5e80..b9467c41 100644
--- a/website/index.html
+++ b/website/index.html
@@ -4,19 +4,19 @@
-
+
-
-
+
+
-
-
+
+
-
>
);
}
@@ -76,7 +154,7 @@ function Hero() {
const benefits = [
["⌕", "Smooth live zoom", "Zoom responds continuously while you drag the OBS slider, without stale commands piling up."],
["▤", "One phone camera", "Connect one phone to OBS and reuse its source across your scenes."],
- ["↻", "Fast reconnects", "Discovery, bounded queues, and reservation-aware recovery keep brief Wi-Fi drops manageable."],
+ ["↻", "Connection recovery", "See connection status and reconnect after a network interruption."],
["▥", "Separate AAC audio", "Phone microphone audio arrives in its own OBS mixer channel, separate from desktop audio."],
];
@@ -95,20 +173,26 @@ function ControlDock() {
function Features() {
return (
-
Control the shot without leaving OBS.
The native dock keeps the controls you touch most beside your preview—not buried in source properties.
+
Control the shot without leaving OBS.
Use source properties to select the phone and control the camera. Linux also includes a dock beside the preview.
Release integrity included. Published release downloads include SHA-256 checksums.
);
@@ -119,7 +203,7 @@ const steps = [
["02", "Install the OBS plugin", "Close OBS, run the Windows installer once, then reopen OBS Studio."],
["03", "Add your camera", "Add one OpenStream source in OBS. Use Add Existing to reuse it in other scenes."],
["04", "Pair on local Wi-Fi", "Choose your OBS computer on the phone. Enable manual receive in OBS if discovery is blocked."],
- ["05", "Frame and go live", "Open the Camera Control dock, verify audio, adjust zoom or lens, and stream."],
+ ["05", "Frame and go live", "Open the source controls, verify audio, adjust zoom or lens, and stream."],
];
function Setup() {
@@ -142,23 +226,62 @@ function Pipeline() {
);
}
-function Compatibility() {
+function Compatibility({ publishedRelease }) {
+ const computerSupport = publishedRelease
+ ? "Windows x64 and Linux x86_64 with OBS Studio"
+ : "Windows x64 with OBS Studio";
+ const currentLimits = publishedRelease
+ ? "macOS packages and adaptive bitrate are not included"
+ : "Linux and macOS packages and adaptive bitrate are not included in this release";
return (
Built for a strong LAN.
Use 5 GHz or Wi-Fi 6, keep both devices on the same subnet, and disable VPN or client isolation during first setup.
-
PhoneAndroid 10+ with Camera2 and hardware MediaCodec
ComputerWindows x64 with OBS Studio
NetworkSame LAN; guest networks may block discovery
Current limitsV1.0.1 supports Android and Windows; macOS/Linux packages and adaptive bitrate are not included
+
PhoneAndroid 10+ with Camera2 and hardware MediaCodec
Computer{computerSupport}
NetworkSame LAN; guest networks may block discovery