Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.streampixel.io/llms.txt

Use this file to discover all available pages before exploring further.

The Streampixel SDK Example is a React application that demonstrates a complete SDK integration. This page walks through its structure and key patterns.

Project structure

Streampixel-SDK-Example/
├── public/
│   ├── index.html            # HTML entry point
│   ├── favicon.png
│   └── manifest.json         # PWA manifest
├── src/
│   ├── index.js              # React entry point
│   ├── index.css             # All styling (548 lines)
│   └── components/
│       └── App.js            # Main application component (706 lines)
├── config-overrides.js       # Webpack polyfills for the SDK
├── package.json
└── package-lock.json

Setup and running

1

Clone the repository

git clone https://github.com/infinity-void-metaverse/Streampixel-SDK-Example.git
2

Install dependencies

cd Streampixel-SDK-Example
npm install
3

Start the dev server

npm start
Open http://localhost:3000/YOUR_PROJECT_ID in your browser.

URL parameters

The example reads configuration from the URL:
ParameterSourceDescription
Project IDURL path (/PROJECT_ID)Your Streampixel project identifier
streamerIdQuery paramTarget a specific UE instance
sfuHostQuery paramSet to true for SFU host mode
sfuPlayerQuery paramSet to true for SFU viewer mode
Example URL: http://localhost:3000/abc123?sfuPlayer=true&streamerId=host1

Feature toggles

At the top of App.js:
const SHOW_DEV_TOOLS = true;  // Set to false to hide the Developer Tools panel
Set SHOW_DEV_TOOLS to false before deploying to production. The Developer Tools panel exposes console commands, JSON messaging, and mic/camera controls that are intended for development only.

LOADING_CONFIG

The LOADING_CONFIG object is the easiest way to customize the loading experience. Change text, colors, and status messages in one place without modifying any event handler logic.
The example centralizes all loading screen text and colors in a single configuration object:
const LOADING_CONFIG = {
  backgroundColor: '#18181A',
  accentColor: '#4e9cff',
  logoUrl: null,                    // Path to a logo image
  title: 'Connecting to Stream',
  subtitle: 'Please wait while we set up your experience...',
  disconnectedSubtitle: 'The stream session has ended.',
  showSpinner: true,
  queueMessage: (position) => `You are in queue at position ${position}`,

  statusMessages: {
    initializing:     'Initializing...',
    connecting:       'Connecting to server...',
    webRtcConnecting: 'Establishing WebRTC connection...',
    sdpNegotiation:   'Negotiating stream parameters...',
    webRtcConnected:  'WebRTC connected, loading stream...',
    streamLoading:    'Stream is loading...',
    playingStream:    'Starting video playback...',
    inQueue:          'Waiting in queue...',
    failed:           'Connection failed. Please try again.',
    disconnected:     'Disconnected from stream.',
    reconnecting:     'Reconnecting to stream...',
    retrying:         'Retrying connection...',
    reconnected:      'Reconnected! Loading stream...',
    reconnectFailed:  'Unable to reconnect. Please refresh the page.',
  },

  reconnectingTitle:       'Reconnecting',
  reconnectingSubtitle:    'Please wait while we restore your session...',
  reconnectedTitle:        'Reconnected',
  reconnectFailedTitle:    'Reconnection Failed',
  reconnectFailedSubtitle: 'We were unable to restore your session.',
};
Modify this object to customize the loading experience without touching event handlers.

How the example wires SDK events

SDK initialization

The app initializes inside a useEffect hook that runs when projectId is available:
useEffect(() => {
  if (!projectId) return;

  const startPlay = async () => {
    const { appStream, pixelStreaming, queueHandler, UIControl, reconnectStream } =
      await StreamPixelApplication({
        appId: projectId,
        AutoConnect: true,
        streamerId,
        sfuHost,
        sfuPlayer,
        forceTurn: true,
      });

    // Store refs for use in event handlers
    pixelStreamingRef.current = pixelStreaming;
    appStreamRef.current = appStream;
    uiControlRef.current = UIControl;

    // ... register events ...
  };

  startPlay();
}, [projectId, streamerId, sfuHost, sfuPlayer]);

Lifecycle events to loading progress

Each WebRTC event updates React state for the loading screen:
pixelStreaming.addEventListener('webRtcConnecting', () => {
  setLoadingStatus(LOADING_CONFIG.statusMessages.webRtcConnecting);
  setLoadingProgress(30);
});

// ... similar for each event ...

appStream.onVideoInitialized = () => {
  videoRef.current.append(appStream.rootElement);
  setLoadingProgress(100);
  setTimeout(() => setIsLoading(false), 300);
};

Reconnection to loading screen

The reconnection state drives the loading screen back into view:
reconnectStream.on('state', (data) => {
  switch (data.status) {
    case 'reconnecting':
      setIsLoading(true);
      setLoadingTitle(LOADING_CONFIG.reconnectingTitle);
      break;
    case 'connected':
      setLoadingTitle(LOADING_CONFIG.reconnectedTitle);
      break;
    case 'failed':
      setLoadingTitle(LOADING_CONFIG.reconnectFailedTitle);
      break;
  }
});

AFK warning to custom overlay

The example replaces the default AFK overlay with a styled card:
pixelStreaming.addEventListener('afkWarningActivate', (e) => {
  setAfkWarning(true);
  setAfkCountdown(e.data.countDown);
  dismissAfkRef.current = e.data.dismissAfk;
});

pixelStreaming.addEventListener('afkWarningUpdate', (e) => {
  setAfkCountdown(e.data.countDown);
});

pixelStreaming.addEventListener('afkWarningDeactivate', () => {
  setAfkWarning(false);
});
The dismiss button calls dismissAfkRef.current().

Developer Tools panel

When SHOW_DEV_TOOLS is true, the example shows a panel with these sections:
SectionWhat it does
Console CommandSends UE console commands (e.g., stat fps) via emitConsoleCommand()
UI Interaction (JSON)Sends custom JSON to UE via emitUIInteraction()
ConnectionDisconnect button via pixelStreaming.disconnect()
Microphone & CameraEnable mic/camera via unmuteMicrophone() / unmuteCamera()
Hovering MouseToggle hover mouse via UIControl.toggleHoveringMouse()

Stream controls toolbar

The bottom-right toolbar shows after loading completes:
  • Mute/Unmute — Toggles both video and audio elements
  • Fullscreen — Toggles browser fullscreen mode
  • Stream Info — Shows stats from UIControl.getStreamStats()
  • Settings (if resolution enabled) — Resolution selection dropdown
  • Dev Tools (if enabled) — Opens the Developer Tools panel

Key React patterns used

  • useRef for SDK instances (pixelStreamingRef, appStreamRef, uiControlRef) — avoids re-renders
  • useState for UI state (loading, controls, AFK, stats)
  • useCallback for event handlers (mute, fullscreen, dev tools actions)
  • mounted flag in useEffect to prevent state updates after unmount
  • Event handler stopPropagation on dev tools inputs to prevent keyboard events from reaching the stream

Next steps

Custom loading screen

Build a loading screen driven by SDK lifecycle events.

Troubleshooting

Resolve common SDK integration issues.