Video Controller

Control video player volume during SDK events with the videoPlayerController callback. Mute the main video during ad playback and restore volume afterward.

Video Controller

Overview

The videoPlayerController property allows you to control the volume of the main video. This feature is essential for muting the video during specific SDK events and resuming the volume afterward.

VideoPlayerData Type

type VideoPlayerData = {
  muted: boolean
};

VideoPlayerController Type

type VideoPlayerController = ({ muted }: VideoPlayerData) => void;

How It Works

The videoPlayerController callback is triggered with the following parameters:

  • muted: true when the SDK video is playing.
  • muted: false when the video ends.

Example Implementation

import { StreamLayerProvider } from '@streamlayer/react';

const toggleVideoVolume = ({ muted }: VideoPlayerData) => {
  const player = document.getElementById('video') as HTMLVideoElement;

  if (muted) {
    player.volume = 0;
  } else {
    player.volume = 1;
  }
};

const providerProps = {
  sdkKey: 'your-sdk-key',
  videoPlayerController: toggleVideoVolume,
  // Add other provider props as needed
};

export const Main = () => (
  <StreamLayerProvider {...providerProps}>
    {/* Other components */}
  </StreamLayerProvider>
);

Volume Reduction (Recommended)

Instead of fully muting the host video, you can reduce it to a low level so viewers still hear ambient audio while a StreamLayer video ad plays.

import { useRef, useCallback } from 'react'
import { StreamLayerProvider } from '@streamlayer/react'

const savedVolume = useRef(1)

const videoPlayerController = useCallback((data) => {
  if (!videoRef.current) return

  if (data.muted === true) {
    savedVolume.current = videoRef.current.volume
    videoRef.current.volume = 0.1 // reduce to 10%
  } else if (data.muted === false) {
    videoRef.current.volume = savedVolume.current
  }
}, [])

Pass this callback via the videoPlayerController prop on StreamLayerProvider:

<StreamLayerProvider {...providerProps} videoPlayerController=  {videoPlayerController}>
  {/* Other components */}
</StreamLayerProvider>

Mute StreamLayer Video

You can mute StreamLayer video content by setting the muted prop to true on the relevant SDK components.

<StreamLayerSDKAdvertisement muted />
<StreamLayerSDKReact muted />

Playback Timestamps (getVideoTimestamp)

getVideoTimestamp works in the opposite direction from videoPlayerController: it is a getter the
SDK calls to read your player's state. Units can be scheduled against a moment in the stream, so
without it a viewer who is behind the live edge — DVR, late join, catch-up — sees them fire at the
wrong moment or not at all. With it, a unit fires when that viewer's playback reaches the moment
it was scheduled for.

type VideoTimestampResult = {
  positionMs: number       // current playback position; program time in Unix ms for live streams
  durationMs?: number      // total duration, when known
  isPlaying: boolean
  isLive: boolean
  liveLatencyMs?: number   // how far behind the live edge, when known
}

type GetVideoTimestampCallback = () => VideoTimestampResult
import { useCallback, useRef } from 'react'
import { StreamLayerProvider } from '@streamlayer/react'

const videoRef = useRef<HTMLVideoElement>(null)

const getVideoTimestamp = useCallback(() => {
  const player = videoRef.current
  if (!player) return { positionMs: 0, isPlaying: false, isLive: false }

  return {
    positionMs: player.currentTime * 1000,
    durationMs: Number.isFinite(player.duration) ? player.duration * 1000 : undefined,
    isPlaying: !player.paused,
    isLive: !Number.isFinite(player.duration),
  }
}, [])

<StreamLayerProvider {...providerProps} getVideoTimestamp={getVideoTimestamp}>
  {/* Other components */}
</StreamLayerProvider>

Live streams: report positionMs as program time in Unix milliseconds — the wall-clock
moment the current frame was broadcast (EXT-X-PROGRAM-DATE-TIME in HLS) — not a seconds-since-start
offset. Wrap the callback in useCallback; the SDK registers it by identity.

StreamLayerPauseAd accepts the same prop for standalone pause ad integrations.


Related