Repository navigation
feat(realtime): subscribe can receive the session's input stream - #227
Merged
Merged
Conversation
- subscribe() accepts onInputStream: the tracks the session's publisher sends
into the room (camera, microphone) as their own MediaStream, re-emitted when
the track set changes, like onRemoteStream.
- inputVideoQuality ("low" | "medium" | "high", default "high") picks the
highest simulcast layer of the input video to receive.
- subscribe() now joins with autoSubscribe: false and subscribes per track, as
connect() already does: the inference server's tracks always, the
publisher's only with onInputStream. Without it the publisher's tracks are no
longer downloaded only to be discarded.
commit: |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, have a team admin enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit f96f572. Configure here.
decartdev
approved these changes
Oct 25, 2026
decartdev
left a comment
There was a problem hiding this comment.
Approved at the author's request. CI green.
Merged
decartdev
pushed a commit
that referenced
this pull request
Oct 25, 2026
Version bump for the v0.2.13 release (`subscribe()` input stream, #227). Through a PR because `main` now requires reviewed changes; the `v0.2.13` tag goes on the merge commit and triggers the npm publish. <!-- CURSOR_SUMMARY --> --- > [!NOTE] > **Low Risk** > Release metadata only; no runtime or API code changes in the diff. > > **Overview** > Bumps **`@decartai/sdk`** from **0.2.12** to **0.2.13** in `packages/sdk/package.json` as the release cut for npm. > > Merging is intended to land the **v0.2.13** tag on the merge commit and trigger publish; functional work (e.g. **`subscribe()`** input stream from #227) is already on the branch—this PR only changes the version field. > > <sup>Reviewed by [Cursor Bugbot](https://cursor.com/bugbot) for commit d02093a. Bugbot is set up for automated code reviews on this repo. Configure [here](https://www.cursor.com/dashboard/bugbot).</sup> <!-- /CURSOR_SUMMARY -->
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Summary
realtime.subscribe()can now also receive the session's input: the tracks its publisher sends into the room (camera, microphone), e.g. to show the original next to the styled output.Changes
SubscribeOptions.onInputStream?: (stream: MediaStream) => void: a freshMediaStreamwhenever the input's track set changes, same contract asonRemoteStream.SubscribeOptions.inputVideoQuality?: "low" | "medium" | "high"(new exported typeSubscribeVideoQuality), default"high": the highest simulcast layer of the input video to receive; the SFU still steps down under bandwidth pressure.subscribe()now joins withautoSubscribe: falseand subscribes per track, mirroringconnect()'s media channel: the inference server's tracks always, any other participant's tracks only whenonInputStreamis set. Publications present at join are swept after connect, and again onReconnected.TrackSubscribedfilter.livekit-client'sVideoQualityis only read whenonInputStreamis set, so existing callers don't depend on it.Tests
pnpm test: 391 passed (387 before + 4 new): subscribe joins without auto-subscribe and never subscribes to the input unless asked (including late publications); input tracks reachonInputStream(fresh stream per change, output unaffected) atHIGHby default;inputVideoQuality: "low"requestsLOW; output and input are re-subscribed after a full reconnect. Typecheck, Biome, build andtest:packagepass.Note
Medium Risk
Changes LiveKit subscription behavior for all subscribers (autoSubscribe off) and adds optional publisher media download; well-tested but affects core realtime viewing paths.
Overview
realtime.subscribe()can optionally receive the publisher’s camera/mic alongside the styled output viaonInputStreamandinputVideoQuality(low|medium|high, defaulthigh), exported asSubscribeVideoQuality.Subscribe now joins LiveKit with
autoSubscribe: falseand subscribes per publication: inference-server output always; publisher input only whenonInputStreamis set, with simulcast quality on input video. Existing viewers that only useonRemoteStreamstop downloading publisher tracks they previously ignored. Track handling uses a sharedwithTrackhelper (freshMediaStreamper change, ended tracks dropped); subscriptions are re-applied after connect and onReconnected. README documents a side-by-side viewer example; unit tests cover the new behavior.Reviewed by Cursor Bugbot for commit d3dfd82. Bugbot is set up for automated code reviews on this repo. Configure here.