Skip to main content

Live Audio Streaming

Connect to WebRTC streams to receive live audio from emergency calls. We recommend using LiveKit's SDKs for the easiest integration.

Prerequisites

How to Connect

  1. Obtain an incident ID (usually provided via a webhook)
  2. Retrieve a stream token
  3. Connect to the WebRTC stream using LiveKit

Example: Connect with LiveKit

import { Room } from "livekit-client";

// Create a room
const room = new Room({
/* options */
});

// Connect using your stream token
await room.connect(API_STREAM_URL, token);

Full implementation details are in LiveKit's documentation.

Live Scrubbing

Control playback during a live session using WebRTC data channels.

Command Messages

Send commands to control the audio stream:

type CommandMessage = {
cmd: 'scrub' | 'pause' | 'resume' | 'scrub-to-end' | 'set-gain';
position?: number; // milliseconds from call start
gain?: number; // gain in dB
callerType?: 'caller' | 'callTaker';
};

Examples:

// Pause playback
{ "cmd": "pause" }

// Resume playback
{ "cmd": "resume" }

// Scrub to position (10ms from start)
{ "cmd": "scrub", "position": 10 }

// Jump to live position
{ "cmd": "scrub-to-end" }

// Adjust volume
{ "cmd": "set-gain", "gain": 11.2, "callerType": "caller" }

Sending commands with LiveKit:

const strData = JSON.stringify({ cmd: "scrub", position: 10 });
const encoder = new TextEncoder();
const data = encoder.encode(strData);
room.localParticipant.publishData(data, DataPacket_Kind.RELIABLE);

Data Messages

Receive status updates about the stream:

type DataMessage = {
kind: 'status';
position: number; // milliseconds from call start
duration: number; // call duration (updates for live calls)
paused: boolean; // whether playback is paused
atEnd: boolean; // whether cursor is at call end
callOver: boolean; // whether the 911 call has ended
};

Receiving data messages:

room.on(RoomEvent.DataReceived, (payload: Uint8Array) => {
const decoder = new TextDecoder();
const strData = decoder.decode(payload);
const data = JSON.parse(strData);

console.log(`Position: ${data.position}ms, Duration: ${data.duration}ms`);
});

See LiveKit data messages documentation for more details.

Playback (Recorded Calls)

For recorded calls, join the WebRTC session the same way as live calls. The differences are:

  1. Playback cursor starts at position 0
  2. Playback is paused by default

All commands and APIs work identically.

AutoPlay Option

Configure autoplay when creating the stream token:

SettingBehavior
autoplay: true (default)Audio starts at the most recent position
autoplay: falseAudio pauses at the beginning; send resume to start

Set autoplay: false to ensure important audio at the start of a call isn't missed.