Skip to content

StreamCrafter — Compositor

The compositor enables multi-source layout control — arrange camera and screen share into professional layouts with scenes, layers, and animated transitions.

If you need raw source streaming without compositing overhead:

React:

<StreamCrafter whipUrl="..." enableCompositor={false} />

Svelte:

<StreamCrafter whipUrl="..." enableCompositor={false} />

Web Components:

<!-- Disable via JS property -->
<fw-streamcrafter id="studio" whip-url="..."></fw-streamcrafter>
<script>
document.getElementById("studio").enableCompositor = false;
</script>

Vanilla:

const studio = createStreamCrafter({
whipUrl: "...",
enableCompositor: false,
});

The compositor ships with 17 built-in layout presets:

ModeLabelMin SourcesDescription
soloSolo1Single source fullscreen
pip-brPiP (bottom-right)2Main + small overlay bottom-right
pip-blPiP (bottom-left)2Main + small overlay bottom-left
pip-trPiP (top-right)2Main + small overlay top-right
pip-tlPiP (top-left)2Main + small overlay top-left
split-hSplit Horizontal2Side-by-side split
split-vSplit Vertical2Top/bottom split
focus-lFocus Left2Large left, small right
focus-rFocus Right2Small left, large right
pip-dual-brMain + 2 PiP3Main with two small overlays
pip-dual-blMain + 2 PiP Left3Main with two small left overlays
split-pip-lSplit + PiP Left3Side-by-side with left overlay
split-pip-rSplit + PiP Right3Side-by-side with right overlay
featuredFeatured3Large center, small sides
featured-rFeatured Right3Large right, small left stack
gridGrid2+Equal-size grid
stackStack2+Vertical stack

React (via hook):

const crafter = useStreamCrafterV2({ whipUrl: "..." });
const compositor = useCompositor({
controller: crafter.getController(),
autoEnable: true,
});
compositor.applyLayout({ mode: "pip-br", scalingMode: "letterbox", pipScale: 0.25 });

Vanilla:

studio.sceneManager?.applyLayout({
mode: "split-h",
scalingMode: "crop",
});

Web Components:

studio.pc
.getController()
?.getSceneManager()
?.applyLayout({ mode: "grid", scalingMode: "letterbox" });

When a layout is already active, clicking it again (or calling the same layout) cycles the source order — the first source moves to the back. Hold Shift to cycle backward.

Each layout supports three scaling modes that control how sources fill their allocated space:

ModeDescription
letterboxFit entire source, add black bars if aspect ratios don’t match
cropFill the space completely, cropping edges if needed
stretchStretch to fill exactly, ignoring aspect ratio

Scenes are named collections of layers with their own layout configurations. Switch between scenes for different broadcast segments.

// React useCompositor hook or Svelte createCompositorStore
const interview = compositor.createScene("interview");
const soloCam = compositor.createScene("solo-cam");
if (interview) {
await compositor.transitionTo(interview.id, {
type: "fade",
durationMs: 500,
easing: "ease-in-out",
});
}

When you work directly with the core SceneManager, use the returned scene ID for later calls:

const sceneManager = studio.sceneManager;
// Create a scene
const interview = sceneManager?.createScene("interview");
sceneManager?.createScene("solo-cam");
// Switch to a scene with a transition
if (interview) {
await sceneManager?.transitionTo(interview.id, {
type: "fade",
durationMs: 500,
easing: "ease-in-out",
});
}
TypeDescription
cutInstant switch (0ms)
fadeCross-fade between scenes
slide-leftNew scene slides in from right
slide-rightNew scene slides in from left
slide-upNew scene slides in from bottom
slide-downNew scene slides in from top

Each source in a scene becomes a layer with independent controls:

PropertyTypeDescription
idstringLayer identifier
sourceIdstringLinked media source
visiblebooleanShow/hide layer
zIndexnumberStack order (higher = on top)
transform.opacitynumberLayer opacity (0-1)
const sceneId = compositor.activeSceneId;
if (!sceneId) return;
// Toggle visibility
compositor.setLayerVisibility(sceneId, layerId, false);
// Change opacity
compositor.updateLayerTransform(sceneId, layerId, { opacity: 0.7 });
// Reorder layers by layer ID
compositor.reorderLayers(sceneId, ["layer-1", "layer-2", "layer-3"]);
// Remove a layer
compositor.removeLayer(sceneId, layerId);

The compositor automatically selects the best available renderer:

RendererRequirementsPerformance
webgpuWebGPU APIBest — GPU-accelerated compositing
webglWebGL 2Good — hardware-accelerated fallback
canvas2dCanvas APIBaseline — software rendering

The active renderer type and FPS are shown in the compositor controls overlay.

Each framework provides compositor UI components:

React:

import {
CompositorControls,
SceneSwitcher,
LayerList,
} from "@livepeer-frameworks/streamcrafter-react";

Svelte:

<script lang="ts">
import {
CompositorControls,
SceneSwitcher,
LayerList,
} from "@livepeer-frameworks/streamcrafter-svelte";
</script>

Web Components:

<fw-sc-compositor for="studio"></fw-sc-compositor>
<fw-sc-scene-switcher for="studio"></fw-sc-scene-switcher>
<fw-sc-layer-list for="studio"></fw-sc-layer-list>

The compositor overlay shows layout icons and scaling mode buttons. Click a layout icon to apply it; click the active layout to cycle source order.