Skip to content

fix: Play remote audio and video through a single media element#152

Merged
AdirAmsalem merged 2 commits into
mainfrom
merge-video-element-livekit
May 31, 2026
Merged

fix: Play remote audio and video through a single media element#152
AdirAmsalem merged 2 commits into
mainfrom
merge-video-element-livekit

Conversation

@AdirAmsalem
Copy link
Copy Markdown
Contributor

@AdirAmsalem AdirAmsalem commented May 31, 2026

What

Remote realtime streams now deliver audio and video as one MediaStream that a host app can render through a single <video> element it owns and controls — both play together, with the app in full control of the playback element. The "generating" connection state is now reported reliably, driven by the server's generation signal rather than as a side effect of internal playback.

Why

Previously remote audio only played because the SDK silently spun up its own hidden media elements, leaving apps with no handle on playback (volume, sink device, muting, lifecycle), and a late-arriving audio track could be dropped entirely. Handing the app a single stream resolves both. Removing those hidden elements also meant the connected → generating transition (which had been a side effect of internal video playback) no longer fired, so it's now tied to the server's generation_started signal — the same approach used before the move to LiveKit — making the state both correct and decoupled from rendering.

No public API changed — onRemoteStream still receives a MediaStream, and onConnectionChange still reports the same states.

Emit a fresh MediaStream whenever the remote track set changes so the
consumer's element re-reads its tracks. Mutating the stream in place left
a late-arriving audio track without an output sink, since assigning the
same MediaStream reference is a no-op. This removes the need for LiveKit
to attach its own hidden elements.
@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 31, 2026

Open in StackBlitz

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

commit: 0282b92

Copy link
Copy Markdown

@cursor cursor Bot left a comment

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 665551a. Configure here.

Comment thread packages/sdk/src/realtime/media-channel.ts
@AdirAmsalem AdirAmsalem changed the title Play remote audio and video through a single media element fix: Play remote audio and video through a single media element May 31, 2026
…layback

The connected->generating transition relied on LiveKit's VideoPlaybackStarted
event, which is only emitted from track.attach(). After removing attach(), that
event never fired and the session was stuck in "connected".

Restore the pre-LiveKit websocket signal: transition on `generation_started`,
with the first `generation_tick` as a fallback. Drop the now-dead
firstFrame / VideoPlaybackStarted proxy.
@AdirAmsalem AdirAmsalem merged commit f75a82a into main May 31, 2026
5 checks passed
@AdirAmsalem AdirAmsalem deleted the merge-video-element-livekit branch May 31, 2026 14:50
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