polite-oil-10264
05/11/2026, 4:07 PMtall-airline-16756
05/11/2026, 4:07 PMtall-airline-16756
05/11/2026, 4:08 PMEgressClient, and important notes.
What I’m responding to: how to use egress with HLS in JavaScript.
Setup
• Egress must be started from a trusted backend (not from browser JS).
• Install the LiveKit server SDK for Node.js: npm install livekit-server-sdk
• Have your LiveKit URL, API key, and API secret ready.
• Decide where HLS files will be stored (S3, GCS, Azure, or local storage supported).
Minimal example (start Room Composite egress to HLS)
1. Create a Node.js file and require the SDK.
2. Start egress with an output configured for HLS (HLS produces an .m3u8 manifest + .ts segments uploaded to your storage).
const { EgressClient } = require('livekit-server-sdk');
const url = 'wss://your-project.livekit.cloud';
const apiKey = 'API_KEY';
const apiSecret = 'API_SECRET';
const client = new EgressClient(url, apiKey, apiSecret);
async function startHlsEgress() {
const request = {
room_name: 'my-room',
// Room composite uses a template page to render layout; omit or provide template options as needed
output: {
file: {
// file.path or filepath can include variables; e.g. "hls/my-room"
filepath: 'hls/my-room',
filename_suffix: 'ts', // segments use .ts
// specify storage type and credentials below (example: s3)
storage: 's3',
s3: {
access_key: 'S3_ACCESS_KEY',
secret: 'S3_SECRET',
region: 'us-west-2',
bucket: 'my-bucket'
},
// indicate you want HLS output (HLS is a supported output format)
// exact field names can vary by SDK version — include protocol/hls-related fields if present
protocol: 'hls'
}
}
};
const res = await client.startRoomCompositeEgress(request);
console.log('Egress started, egressId:', res.egressId);
return res;
}
startHlsEgress().catch(console.error);
Important notes
• HLS egress is supported by Room Composite egress (generates .m3u8 and .ts files).
• LiveKit renders the room via a headless browser template; you can customize layout with the Egress Template SDK if you need custom positioning or overlays.
• Use webhooks to get notified when egress starts, progresses, or ends; the egress_ended event includes output locations (manifest/file info).
• Ensure your storage credentials and permissions allow LiveKit to write the manifest and segments.
If you want, tell me:
• Which storage provider you’ll use (S3/GCS/Azure/local) so I can show the exact request fields for that provider.
• Whether you need a custom layout/template for the HLS output so I can include template setup steps. Sources: Universal Egress | LiveKit | Backup Egress Recordings, with interactive elementspolite-oil-10264
05/11/2026, 4:09 PMtall-airline-16756
05/11/2026, 4:10 PMIngressType_WHIP via a server SDK (Node.js/Go/CLI). The Ingress will give you an endpoint to which a WHIP-capable publisher can POST SDP offers.
• Once the WHIP stream is in the room, you can use normal LiveKit workflows (e.g., Room Composite + egress to HLS/MP4/RTMP).
Quick guidance I can provide
• Server-side Node.js example to create a WHIP ingress (I’ll show code if you want).
• How to connect a WHIP publisher to the generated WHIP endpoint.
• How to route the ingested stream to egress (HLS) or mix it with other room participants.
• Storage/permission and webhook considerations.
Which of these would you like next?
• Show a Node.js example to create WHIP ingress?
• Show how a WHIP publisher posts to the endpoint?
• Show how to combine WHIP ingestion with HLS egress? Sources: Universal Egress | LiveKit | Pricing | LiveKit | Pricing | LiveKit, with interactive elementspolite-oil-10264
05/11/2026, 4:11 PMtall-airline-16756
05/11/2026, 4:11 PMnpm install livekit-server-sdk
• Have your LiveKit URL, API key, and API secret.
• Run this code on a trusted server (Ingress creation must be server-side).
Example: create a WHIP ingress (Node.js)
// server.js
const express = require('express');
const bodyParser = require('body-parser');
const { IngressClient } = require('livekit-server-sdk'); // server SDK
const app = express();
app.use(bodyParser.json());
const LIVEKIT_WS = 'https://your-project.livekit.cloud'; // or wss:// depending on environment
const API_KEY = process.env.LK_API_KEY;
const API_SECRET = process.env.LK_API_SECRET;
const ingressClient = new IngressClient(LIVEKIT_WS, API_KEY, API_SECRET);
// Create WHIP ingress and return the WHIP endpoint info
app.post('/create-whip', async (req, res) => {
try {
const { roomName, name } = req.body; // e.g., { roomName: 'my-room', name: 'camera-1' }
const createReq = {
ingress_type: 'WHIP', // indicate WHIP ingress
name,
room_name: roomName,
// optional: set video/audio track configurations, input_url not used for WHIP
};
const resp = await ingressClient.createIngress(createReq);
// resp should include an `ingress` object with an `ingress_url` (the WHIP endpoint)
res.json({ success: true, ingress: resp.ingress });
} catch (err) {
console.error(err);
res.status(500).json({ success: false, error: err.message });
}
});
app.listen(3000, () => console.log('Listening on :3000'));
What the response contains
• The created ingress object includes the WHIP endpoint URL (often called ingress_url or similar). That URL is where a WHIP-capable publisher posts an SDP offer (HTTP POST) to establish a WebRTC session that publishes into the LiveKit room.
How a WHIP publisher connects (overview)
• The publisher performs an HTTP POST to the WHIP endpoint with a SDP offer and receives a SDP answer in response (standard WHIP flow).
• The WHIP publisher can be any WHIP-capable client or server (camera gateway, media server, or custom client implementing WHIP).
Security notes
• Keep API key/secret and Ingress creation endpoints on the server only.
• Protect the endpoint that returns the WHIP URL (e.g., require auth) so only authorized callers can create ingresses.
• You may generate short-lived ingresses or revoke them when not needed.
If you want next
• I can provide a concrete Node.js example showing the HTTP POST a WHIP publisher would send (SDP exchange).
• I can show how to start HLS egress for the room once the WHIP stream is ingested. Which would you like?, with interactive elementspolite-oil-10264
05/11/2026, 4:12 PMtall-airline-16756
05/11/2026, 4:13 PMimport { IngressClient } from 'livekit-server-sdk';
const LIVEKIT_WS = process.env.LIVEKIT_WS; // e.g. "https://your-project.livekit.cloud"
const API_KEY = process.env.LIVEKIT_API_KEY;
const API_SECRET = process.env.LIVEKIT_API_SECRET;
const client = new IngressClient(LIVEKIT_WS, API_KEY, API_SECRET);
export default async function handler(req, res) {
if (req.method !== 'POST') return res.status(405).end();
const { roomName, name } = req.body || {};
if (!roomName || !name) return res.status(400).json({ error: 'roomName and name required' });
try {
const createReq = {
ingress_type: 'WHIP', // specify WHIP ingress
name,
room_name: roomName,
// optional: configure audio/video track params, and/or participant identity
};
const resp = await client.createIngress(createReq);
// resp.ingress should include the WHIP endpoint (egress/ingress URL)
return res.status(200).json({ ingress: resp.ingress });
} catch (err) {
console.error(err);
return res.status(500).json({ error: err.message });
}
}
What the response contains
• The returned ingress object includes an ingestion URL (the WHIP endpoint). Give that URL to your WHIP publisher to POST an SDP offer and start streaming into the room.
Publisher overview (what the publisher does)
• The publisher makes an HTTP POST to the WHIP endpoint with an SDP offer and receives an SDP answer in the response — standard WHIP flow. That publisher then sends media; LiveKit injects it into the room as a participant.
Combining WHIP + HLS
• After ingress is active, start Room Composite egress (server-side) to output HLS for that room. WHIP alone does not create HLS; egress does.
Security notes
• Keep API key/secret and ingress-creation endpoints on server only.
• Protect the create-whip API (auth) and consider short-lived ingresses or revocation.
• Ensure storage credentials for HLS egress are secured when you start egress.
If you want next:
• I can provide a concrete example showing the WHIP publisher HTTP POST exchange (SDP offer/answer).
• Or show how to start HLS egress from Next.js after creating the WHIP ingress. Which one would you like?, with interactive elementspolite-oil-10264
05/11/2026, 4:15 PMtall-airline-16756
05/11/2026, 4:15 PMpolite-oil-10264
05/11/2026, 4:50 PMtall-airline-16756
05/11/2026, 4:50 PMpolite-oil-10264
05/11/2026, 4:52 PMtall-airline-16756
05/11/2026, 4:53 PMpolite-oil-10264
05/11/2026, 4:55 PMtall-airline-16756
05/11/2026, 4:56 PMkubectl top / host metrics).
• Any logs showing encode latency or dropped frames, and whether viewers experience buffering or constant offset.
Tell me those details and I’ll give an actionable plan (specific config changes, sample egress request or k8s hints) to get latency back under a few seconds.
, with interactive elementspolite-oil-10264
05/11/2026, 5:18 PMtall-airline-16756
05/11/2026, 5:18 PMconst { EgressClient } = require('livekit-server-sdk');
const client = new EgressClient('https://your-livekit-host', process.env.API_KEY, process.env.API_SECRET);
async function startRtmpEgress(roomName, rtmpUrl) {
const req = {
room_name: roomName,
layout: 'speaker', // or template
output: {
stream: {
protocol: 'rtmp',
urls: [rtmpUrl],
}
}
};
const res = await client.startRoomCompositeEgress(req);
return res.egressId;
}
What I need if you want a tailored plan
• Are you using RTMP or HLS right now for egress?
• Is egress on the same host as the SFU or separate (k8s or VM)?
• CPU/RAM on egress host and observed CPU during streams (or kubectl top).
• Network RTT between publisher, SFU, and egress host.
Send those details and I’ll give exact config values (CPU counts, encoder settings, k8s resource YAML) to target <3s or sub-second latency.
, with interactive elements