Apply a virtual background headlessly — no modal, no DOM of your own.
The SDK's own background support lives inside BackgroundModal, whose apply
path is bound to that component's refs (a preview <video> and a <canvas>)
and is driven by autoClickBackground / isBackgroundModalVisible. A
returnUI={false} surface therefore had no way to turn a background on
without mounting the modal off-screen and simulating a click.
This runs the same MediaPipe pipeline the modal uses — identical compositing:
draw the segmentation mask, retain the person with source-in, then paint
the replacement behind them with destination-over — against an offscreen video and
canvas it creates and owns.
It also keeps the SDK's own state honest (virtualStream, processedStream,
keepBackground), so getLocalVideoStream keeps returning the right
self-view without the caller choosing. Callers should not select the
processed stream themselves.
The camera must already be on: this processes localStreamVideo, it does not
acquire one.
Apply a virtual background headlessly — no modal, no DOM of your own.
The SDK's own background support lives inside
BackgroundModal, whose apply path is bound to that component's refs (a preview<video>and a<canvas>) and is driven byautoClickBackground/isBackgroundModalVisible. AreturnUI={false}surface therefore had no way to turn a background on without mounting the modal off-screen and simulating a click.This runs the same MediaPipe pipeline the modal uses — identical compositing: draw the segmentation mask, retain the person with
source-in, then paint the replacement behind them withdestination-over— against an offscreen video and canvas it creates and owns.It also keeps the SDK's own state honest (
virtualStream,processedStream,keepBackground), sogetLocalVideoStreamkeeps returning the right self-view without the caller choosing. Callers should not select the processed stream themselves.The camera must already be on: this processes
localStreamVideo, it does not acquire one.