Skip to content

StreamCrafter — Web Components

NPM:

Terminal window
npm install @livepeer-frameworks/streamcrafter-wc
import "@livepeer-frameworks/streamcrafter-wc/define";

CDN (no bundler):

<!-- unpkg -->
<script src="https://unpkg.com/@livepeer-frameworks/streamcrafter-wc/fw-streamcrafter.js"></script>
<!-- or jsdelivr -->
<script src="https://cdn.jsdelivr.net/npm/@livepeer-frameworks/streamcrafter-wc/fw-streamcrafter.js"></script>

Shadow DOM encapsulates all CSS — host page styles won’t break controls.

<fw-streamcrafter
whip-url="https://edge-ingest.frameworks.network/webrtc/your-stream-key"
initial-profile="broadcast"
></fw-streamcrafter>

Gateway Resolution Mode:

<fw-streamcrafter
gateway-url="https://bridge.frameworks.network/graphql"
stream-key="<YOUR_STREAM_KEY>"
initial-profile="broadcast"
></fw-streamcrafter>

Gateway resolution calls the public resolveIngestEndpoint GraphQL field from the publisher’s browser. Use direct whip-url unless that resolver is enabled in your environment, and prefer the dashboard DNS ingest URL for backend or encoder-side publishing.

The element includes the same full UI as the React/Svelte versions: video preview, camera/screen controls, quality selection, and connection status.

Set controls="false" to hide the built-in UI. The element still manages the streaming connection — you provide your own controls:

<fw-streamcrafter
id="studio"
whip-url="https://edge-ingest.frameworks.network/webrtc/key"
controls="false"
></fw-streamcrafter>
<script>
const studio = document.getElementById("studio");
document.getElementById("go-live").addEventListener("click", () => {
studio.pc.startStreaming();
});
document.getElementById("add-camera").addEventListener("click", () => {
studio.pc.startCamera();
});
</script>

The .pc property provides direct access to the underlying IngestControllerHost:

const studio = document.querySelector("fw-streamcrafter");
// Read state
studio.pc.getState(); // "idle" | "capturing" | "streaming" | ...
studio.pc.isStreaming(); // boolean
studio.pc.getSources(); // MediaSource[]
// Actions
await studio.pc.startCamera();
await studio.pc.startScreenShare({ audio: true });
await studio.pc.startStreaming();
await studio.pc.stopStreaming();
studio.pc.removeSource("camera-1");
studio.pc.setSourceVolume("camera-1", 0.5);
// Events
studio.pc.on("stateChange", ({ state }) => console.log(state));

When you provide content in the default slot, it replaces the built-in controls while the element still manages the connection:

<fw-streamcrafter whip-url="..." controls="false">
<div class="my-controls">
<fw-sc-volume></fw-sc-volume>
<button id="go-live">Go Live</button>
</div>
</fw-streamcrafter>

All sub-components can be used outside <fw-streamcrafter> by referencing it with the for attribute:

<fw-streamcrafter id="studio" whip-url="..." controls="false"></fw-streamcrafter>
<div class="my-custom-layout">
<fw-sc-volume for="studio"></fw-sc-volume>
<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>
<fw-sc-advanced for="studio"></fw-sc-advanced>
</div>

Without for, sub-components look for the nearest ancestor <fw-streamcrafter> using closest().

ElementPurpose
<fw-sc-volume>Volume slider with mute toggle
<fw-sc-compositor>Layout and scaling mode selector overlay
<fw-sc-scene-switcher>Scene list with transition controls
<fw-sc-layer-list>Drag-to-reorder layer list with visibility toggles
<fw-sc-advanced>Advanced settings panel (WebCodecs, encoder, audio processing)
AttributeTypeDefaultDescription
whip-urlstringDirect WHIP ingest endpoint
gateway-urlstringGateway GraphQL endpoint for resolver-backed ingest environments
stream-keystringStream key used with gateway-url
initial-profilestring"broadcast"Quality preset
controlsstring""Set to "false" for headless mode
themestring"default"Theme preset name
localestring"en"UI language
enable-compositorbooleantrueEnable compositor (set el.enableCompositor = false in JS to disable)
debugbooleanfalseEnable debug logging

Listen for events on the element:

const studio = document.querySelector("fw-streamcrafter");
studio.addEventListener("fw-sc-state-change", (e) => {
console.log("State:", e.detail.state);
});
<template>
<fw-streamcrafter :whip-url="whipUrl" initial-profile="broadcast" />
</template>
<script setup>
import "@livepeer-frameworks/streamcrafter-wc/define";
import { ref } from "vue";
const whipUrl = ref("https://edge-ingest.frameworks.network/webrtc/my-key");
</script>
app.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
import "@livepeer-frameworks/streamcrafter-wc/define";
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class AppModule {}
component.html
<fw-streamcrafter [attr.whip-url]="whipUrl" initial-profile="broadcast"></fw-streamcrafter>