How to use egress with hls? In javascript
# ask-ai
p
How to use egress with hls? In javascript
✅ 1
t
Thanks for reaching out, Yassine. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — I’ll help you with using LiveKit egress to produce HLS from Node.js (server-side JavaScript). I’ll cover the required setup, a minimal code example using the
EgressClient
, 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).
Copy code
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 elements
p
What about whip
t
Thanks — I’m responding to your question about WHIP. Short answer: LiveKit supports WHIP as an Ingress type to ingest external WebRTC streams into a room. Ingress (including WHIP) is created from a trusted backend (server-side), not from browser JS. What you can do next • If you want to ingest a WHIP stream into a LiveKit room, create an Ingress with
IngressType_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 elements
p
Give me example with nodejs backend
t
Thanks — I’ll show a concise Node.js backend example that creates a WHIP Ingress in LiveKit and explains how a WHIP publisher can post to the returned endpoint. What I’m responding to: creating a WHIP ingress using a Node.js backend. Prerequisites • Install the LiveKit server SDK:
npm 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)
Copy code
// 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 elements
p
Do i need whip url? And what is the whip exacly? Did he lunch a hls or what? I want example with nextjs
t
Thanks — I’ll explain what WHIP is, whether you need a WHIP URL, how WHIP relates to HLS, and give a concise Next.js server example that creates a WHIP ingress and returns the WHIP endpoint. Short answers • Do you need a WHIP URL? Yes, you need a WHIP endpoint URL if you want an external WHIP-capable publisher to send a WebRTC publish stream into your LiveKit room. • What is WHIP? WHIP (WebRTC-HTTP Ingestion Protocol) is a simple HTTP-based way for a publisher to POST an SDP offer to an ingestion endpoint and receive an SDP answer — effectively letting external devices/servers publish into a room over WebRTC without full signaling implementation. • Does WHIP launch HLS? No. WHIP ingests a live WebRTC stream into the room. HLS (egress) is a separate process: once the stream is in the room you can start egress (Room Composite) to produce HLS manifests/segments. Next steps you can take • Create a WHIP ingress from your trusted backend (Next.js API route). • Give the returned WHIP URL to the publisher (camera gateway, media server, or a WHIP client) to POST SDP and stream into the room. • Optionally start HLS egress for that room from the backend so the ingested stream is output as HLS. Next.js example (server-side API route) 1. Install: npm install livekit-server-sdk 2. Create an API route that creates a WHIP ingress and returns the ingress URL. pages/api/create-whip.js
Copy code
import { 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 elements
p
So whip is to lunch a live inside the room not publish the room live into external hls
t
Correct — that’s right. WHIP is an ingestion protocol: it lets an external publisher (camera, gateway, media server) POST an SDP offer to a WHIP endpoint so LiveKit ingests that live WebRTC stream into a room as a participant. WHIP does NOT publish the room out as HLS. To produce HLS you must start an egress (Room Composite egress) from your backend after the stream is in the room. Typical flow: • Create WHIP ingress (server-side) → returns WHIP URL • External publisher POSTs SDP to WHIP URL → media enters the LiveKit room • From your server, start egress for that room → egress outputs HLS (m3u8 + .ts) to your storage If you want, I can now: • Show the Next.js API route to create WHIP ingress (you already saw one), or • Show the WHIP publisher HTTP POST (SDP exchange) example, or • Show how to start Room Composite egress to HLS from Next.js. Which one should I provide next? , with interactive elements
p
I'm using livekit self hosted and the flux always en retard , what is the best option for egress output
t
Thanks — I hear your stream has persistent latency on your self‑hosted LiveKit. To recommend the best egress option I need a couple quick details: • Are you currently using HLS egress, RTMP, or another output? • Is the latency visible to viewers of an HLS player, to other room participants, or both? • Approximate target latency you need (e.g., <3s, <10s, <30s). • Deployment notes: single server or k8s, CPU/CPU load, and whether you run egress on the same host as the SFU. High‑level guidance (so you can act fast) • HLS adds noticeable delay by design (segments + manifest). If low latency is critical, HLS is not ideal unless you use low‑latency HLS with very short segments and specialized players. • Lowest latency paths: ◦ Direct WebRTC (keeping users in the room) — sub-second to a few hundred ms for interactive use. ◦ RTMP to a low‑latency CDN or media server (then deliver via WebRTC/low‑latency streaming) — good for sub-10s scenarios. ◦ Room Composite egress directly to WebRTC or RTMP is generally lower latency than HLS. • If you must use HLS: ◦ Reduce segment duration (e.g., 1s) and playlist length, enable low‑latency HLS features if your players and CDN support them. ◦ Ensure egress has ample CPU and network bandwidth and run egress on a dedicated host. • Self‑host tips: ◦ Run egress separate from core LiveKit SFU so encoding/upload load won’t delay packet forwarding. ◦ Ensure time sync (NTP), CPU scaling governors, and network MTU are optimized. ◦ Monitor resource usage (CPU, encode latency, disk/network IO) during egress. If you share the answers to the questions above, I’ll give a concrete recommendation and a short Node.js example for the egress method best suited to your latency target. Which option do you want to prioritize: lowest possible latency (WebRTC), streaming to CDN (RTMP), or lower‑latency HLS tuning? , with interactive elements
p
I'm using rtmp , but if i use hls will be best ?
t
You’re asking whether switching from RTMP to HLS will help latency on your self‑hosted LiveKit — short answer: no. RTMP is the better choice for low latency; HLS is inherently higher‑latency. Why RTMP is better for latency • RTMP delivers much lower end‑to‑end delay (sub-second to a few hundred ms) compared to HLS (typically 5–30s; LL‑HLS can reach ~2–5s). • RTMP keeps streams closer to real‑time and preserves sync between viewers; HLS’s segment/playlist model introduces buffering and viewer skew. When you might choose HLS • You need broad playback compatibility (very old players/devices) or built‑in VOD/replay. • You are optimizing for large-scale CDN delivery where HLS/HTTP delivery is required and higher latency is acceptable. Practical recommendations to reduce latency with your self‑hosted setup • Keep using RTMP for live, low‑latency viewers. • Run egress/encoder on a dedicated host (separate from the SFU) to avoid CPU/network contention. • Ensure sufficient CPU and network bandwidth on the egress node and use efficient codecs. • If using an intermediate media server/CDN, choose one optimized for low‑latency delivery. • Monitor encode time, network RTT, and CPU load to find bottlenecks. If you want, I can: • Show a concise Node.js example to start Room Composite egress to RTMP from your backend. • Help troubleshoot your self‑hosted bottlenecks if you share CPU/network metrics or how you’ve deployed egress (same host vs separate, k8s vs single VM). Which would you like? Sources: A tale of two protocols: comparing WebRTC against HLS for live streaming | ... | Use Case: Livestreaming | LiveKit | Universal Egress | LiveKit | How Playback built a global stadium for watching sports together | LiveKit, with interactive elements
p
Why there is a delai between the room and the stream like more than 40 seconde
t
Sorry you’re seeing ~40s delay — that’s frustrating. I’ll explain common causes and give concrete troubleshooting steps so we can narrow the problem quickly. What typically causes large room→stream delay • Egress output type: HLS/segmenting adds tens of seconds by design. RTMP should be much lower. • Encoder/segment settings: long HLS segment durations or large playlist lengths increase latency. • Egress worker placement: running egress on the same host as the SFU or far from publishers can add queuing and network RTT. • CPU or IO contention: encoding is CPU‑heavy; high CPU, disk or network saturation causes encoding/backpressure. • Buffering in downstream components: CDN, media server, or player buffer settings can add seconds. • Clock drift / time sync issues: mis‑synced servers create jitter and rebuffering. • Network path/RTR: high packet loss or routing through distant regions increases retransmits and perceived delay. Immediate checks (do these now) • Confirm output type: is egress to RTMP or HLS? (If HLS, switch to RTMP for testing.) • Check egress host CPU, memory, and network during streaming (top, iostat, ifstat). • Check encoder logs for queue/encode latency metrics and any dropped frames. • Measure RTT between publishers, SFU, and egress host (ping/traceroute). • Look at player buffer settings and CDN/ingestion latency (if using CDN). • Check HLS segment duration & playlist length (if HLS): reduce to 1s segments + short playlist for testing. Concrete fixes to reduce delay • Use RTMP or direct WebRTC for low latency rather than HLS. • Run egress/encoder on a dedicated machine close (network) to the SFU; avoid colocating with heavy SFU load. • Increase CPU (or dedicated hardware encoder) for the egress node to avoid encode backlog. • If you must use HLS, shorten segment length (1s) and playlist length, and use LL‑HLS if your players/CDN support it. • Tune player buffers (lower the start-up buffer) for consumers who can tolerate less stability. • Ensure NTP time sync on all hosts. • If using k8s, assign egress pods higher CPU limits/requests and prefer nodeAffinity for low-latency placement. To give a precise fix I need: • Are you using RTMP or HLS for the stream output? • Is egress running on the same host as the SFU or a separate host / k8s pod? • Approx CPU/RAM and encode settings for the egress host (or
kubectl 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 elements
p
Can you give me what i do for low latency ?
t
Thanks — I’ll give a short, actionable checklist and concrete steps to get low latency on your self‑hosted LiveKit setup. What to aim for • Use WebRTC (in‑room) or RTMP egress for lowest latency (<1s to a few 100s ms). HLS is high latency (seconds+). Immediate checklist (apply in order) 1. Use RTMP or direct WebRTC for viewers ◦ Keep using RTMP for external streaming; only use HLS if you accept higher latency. 1. Run egress on a dedicated host ◦ Don’t colocate egress/encoder with the SFU. Put egress on a separate machine or pod near the SFU (same region / VPC). 1. Give egress ample CPU and network ◦ Dedicated CPU cores, plenty of CPU quota in k8s (high requests/limits), and >100Mbps bandwidth per HD stream. 1. Reduce encoding latency ◦ Use low-latency encoder presets (fast/ultrafast), tune GOP/iframe intervals, and avoid re-encoding if possible. ◦ Use hardware encoders if available (NVENC/QuickSync). 1. Optimize RTMP path ◦ Send RTMP directly from egress to CDN/endpoint without extra hops. Use nearby ingest endpoints. 1. Network and timing ◦ Ensure low RTT between publisher → SFU → egress (<50ms ideal). ◦ Enable NTP time sync on all hosts. 1. Monitor and eliminate backpressure ◦ Watch CPU, enc/queue latency, dropped frames, disk IO, and network errors during streams. ◦ If encoding queues grow, increase CPU or reduce bitrate/resolution. 1. Player-side tuning ◦ Lower player buffer/startup buffer when safe. For Web players, reduce bufferLength if viewers can tolerate it. 1. If HLS is required (last resort) ◦ Use LL‑HLS with 1s segments, minimal playlist length, and players/CDN that support LL‑HLS. Expect ~2–5s latency at best. 1. Deployment tips for k8s ◦ Use nodeAffinity to place egress pod near SFU pods. ◦ Give egress pod guaranteed CPU (requests = limits) and use a fast network node pool. ◦ Avoid CPU throttling by setting appropriate QoS. Quick Node.js example: start Room Composite egress to RTMP
Copy code
const { 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