Skip to content

feat(realtime): subscribe can receive the session's input stream - #227

Merged
decartdev merged 2 commits into
mainfrom
conductor/subscribe-input-stream
Oct 25, 2026
Merged

decartdev merged 2 commits into
mainfrom
conductor/subscribe-input-stream

Conversation

@AdirAmsalem

@AdirAmsalem AdirAmsalem commented Oct 25, 2026 •

Copy link
Copy Markdown
Contributor

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.

await client.realtime.subscribe({
  token,
  onRemoteStream: (stream) => (outputVideo.srcObject = stream),
  onInputStream: (stream) => (inputVideo.srcObject = stream),
  inputVideoQuality: "low", // "low" | "medium" | "high" (default)
});

Changes

  • SubscribeOptions.onInputStream?: (stream: MediaStream) => void: a fresh MediaStream whenever the input's track set changes, same contract as onRemoteStream.
  • SubscribeOptions.inputVideoQuality?: "low" | "medium" | "high" (new exported type SubscribeVideoQuality), default "high": the highest simulcast layer of the input video to receive; the SFU still steps down under bandwidth pressure.
  • subscribe() now joins with autoSubscribe: false and subscribes per track, mirroring connect()'s media channel: the inference server's tracks always, any other participant's tracks only when onInputStream is set. Publications present at join are swept after connect, and again on Reconnected.
    • Side effect for existing subscribers: they no longer download the publisher's camera/mic only to drop them in the TrackSubscribed filter.
  • livekit-client's VideoQuality is only read when onInputStream is set, so existing callers don't depend on it.
  • README: viewer-with-input example.

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 reach onInputStream (fresh stream per change, output unaffected) at HIGH by default; inputVideoQuality: "low" requests LOW; output and input are re-subscribed after a full reconnect. Typecheck, Biome, build and test:package pass.


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 via onInputStream and inputVideoQuality (low | medium | high, default high), exported as SubscribeVideoQuality.

Subscribe now joins LiveKit with autoSubscribe: false and subscribes per publication: inference-server output always; publisher input only when onInputStream is set, with simulcast quality on input video. Existing viewers that only use onRemoteStream stop downloading publisher tracks they previously ignored. Track handling uses a shared withTrack helper (fresh MediaStream per change, ended tracks dropped); subscriptions are re-applied after connect and on Reconnected. 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.

- 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.
@pkg-pr-new

pkg-pr-new Bot commented Oct 25, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@decartai/sdk@227

commit: d3dfd82

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ 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 decartdev left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved at the author's request. CI green.

@decartdev
decartdev merged commit 3b10cfb into main Oct 25, 2026
5 checks passed
@decartdev
decartdev deleted the conductor/subscribe-input-stream branch October 25, 2026 09:08
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 -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants