Home Blog Stream IP Cameras to a Website
Tutorial

How to Stream IP Cameras to a Website (RTSP → HLS, WebRTC, RTMP)

📅 March 13, 2026 ⏱️ 7 min read 🏷️ HLS, WebRTC, Website Integration, RTSP

You have IP cameras on your network and you want to display them on a website — your company's monitoring dashboard, a public webcam page, a construction site feed, or a property management portal. The problem: IP cameras output RTSP, and RTSP is completely incompatible with HTML and web browsers.

This guide covers the three practical methods for getting a live camera feed into a webpage: HLS (maximum compatibility), WebRTC (minimum latency), and RTMP to a streaming platform (for public broadcasts). For each method, you'll see real working code.

The Core Challenge: RTSP Is Not Browser-Compatible

RTSP (Real Time Streaming Protocol) is a TCP-based control protocol that cameras use to negotiate and stream video. It runs on port 554, uses RTP for the actual video data, and requires a client that can speak the RTSP handshake. Browsers do not have this ability — they expose only HTTP-based networking APIs to web pages.

This means you cannot put an RTSP URL directly into a <video src="..."> tag and expect it to work. The URL will either be blocked by browser security policies or fail outright because the browser has no RTSP client built in.

To embed a camera on a webpage, you need a server-side conversion layer that:

  1. Connects to the camera via RTSP
  2. Re-packages the video into a browser-compatible format (HLS, WebRTC, or RTMP)
  3. Serves that format to the browser over HTTP/HTTPS or WebRTC signaling

There is no way around this conversion step. The three methods below differ in what format the conversion produces and the trade-offs involved.

Method 1: HLS with HLS.js (Most Compatible)

HLS (HTTP Live Streaming) is Apple's adaptive streaming protocol. Video is encoded and sliced into short .ts segments (typically 2–6 seconds each), and a .m3u8 playlist file is updated to point to the latest segments. The browser downloads segments over plain HTTP — no special protocol required.

Why HLS is the most compatible option

  • Safari plays HLS natively using the <video> element with no JavaScript library
  • Chrome, Firefox, and Edge support HLS via the HLS.js library, which uses the Media Source Extensions (MSE) browser API
  • HLS works through CDNs, firewalls, and reverse proxies — it's just HTTP GET requests for files
  • It handles variable network conditions gracefully through adaptive bitrate

Trade-off: latency

Standard HLS latency is 15–30 seconds because the browser must wait for at least one full segment to download before playback begins, and the server writes segments in real time. Low-Latency HLS (LL-HLS) can reduce this to 2–5 seconds with compatible servers and clients, but requires additional server-side configuration. For security monitoring where near-real-time awareness matters, HLS may be too slow — see WebRTC below.

Embedding HLS with HLS.js

The HLS.js library is a small (~300 KB) open-source script. Include it from a CDN or host it yourself:

<!DOCTYPE html>
<html>
<head>
  <title>Live Camera Feed</title>
  <style>
    #camera { width: 100%; max-width: 1280px; height: auto; background: #000; }
  </style>
</head>
<body>

<video id="camera" controls autoplay muted playsinline></video>

<!-- HLS.js from CDN -->
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
  const video = document.getElementById('camera');
  // Replace with your actual HLS endpoint URL
  const hlsUrl = 'https://your-server.example.com/live/front_door/index.m3u8';

  if (Hls.isSupported()) {
    // Chrome, Firefox, Edge: use HLS.js
    const hls = new Hls({
      lowLatencyMode: false,  // set true for LL-HLS servers
      liveSyncDurationCount: 3
    });
    hls.loadSource(hlsUrl);
    hls.attachMedia(video);
  } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    // Safari: native HLS support
    video.src = hlsUrl;
  } else {
    console.error('HLS is not supported in this browser');
  }
</script>

</body>
</html>

The playsinline attribute is important for iOS Safari — without it, the video may open in the system fullscreen player instead of playing inline on the page. The muted attribute is required for autoplay in most browsers.

Method 2: WebRTC (Lowest Latency)

WebRTC delivers camera video to the browser with 100–500 ms latency. It does this by streaming encrypted RTP packets directly from the server to the browser over UDP, bypassing the segment-based model of HLS entirely.

What you need on the server side

A WebRTC server that can ingest your RTSP stream and serve WebRTC to browsers. Open-source options include go2rtc and MediaMTX. The server handles ICE negotiation, DTLS handshake, and SRTP encryption — the browser's RTCPeerConnection API handles the receiving end.

Embedding via iframe (simplest approach)

If you're using a service like TheRelay or a self-hosted go2rtc instance, the easiest embed is an iframe pointing to the built-in player:

<!-- WebRTC player iframe -->
<iframe
  src="https://app.therelay.net/embed/webrtc/YOUR_STREAM_ID"
  width="1280"
  height="720"
  frameborder="0"
  allow="autoplay; fullscreen"
  allowfullscreen
></iframe>

Custom RTCPeerConnection (advanced)

If you're running go2rtc yourself, it exposes a /api/ws?src=STREAM_NAME WebSocket endpoint for WebRTC signaling. The go2rtc repository includes a reference JavaScript implementation. In summary, the browser creates an RTCPeerConnection, calls addTransceiver('video', {direction:'recvonly'}), creates an SDP offer, sends it to the server, receives the answer, and then media flows:

// Simplified WebRTC signaling with go2rtc
const pc = new RTCPeerConnection();
pc.addTransceiver('video', { direction: 'recvonly' });
pc.addTransceiver('audio', { direction: 'recvonly' });

// Display video when track arrives
pc.ontrack = (event) => {
  if (event.track.kind === 'video') {
    document.getElementById('camera').srcObject = event.streams[0];
  }
};

// Exchange SDP with go2rtc via WebSocket
const ws = new WebSocket('wss://your-go2rtc-server:1984/api/ws?src=front_door');
ws.onmessage = async (msg) => {
  const data = JSON.parse(msg.data);
  if (data.type === 'offer') {
    await pc.setRemoteDescription(new RTCSessionDescription(data));
    const answer = await pc.createAnswer();
    await pc.setLocalDescription(answer);
    ws.send(JSON.stringify(answer));
  }
};

This requires your go2rtc server to be reachable over HTTPS/WSS from the browser. A self-signed certificate will cause browser errors — you need a valid TLS certificate (Let's Encrypt works).

Method 3: RTMP to YouTube or Twitch (Public Streams)

If your use case is a public stream — a city webcam, a live event, a public construction feed — pushing via RTMP to YouTube Live or Twitch is the path of least resistance. Viewers can watch in any browser through YouTube's or Twitch's player without you hosting any infrastructure.

Use FFmpeg to pull the RTSP stream from your camera and push it to the RTMP ingest endpoint:

# Pull RTSP from camera, push to YouTube Live via RTMP
ffmpeg \
  -rtsp_transport tcp \
  -i "rtsp://admin:password@192.168.1.100:554/stream1" \
  -c:v libx264 \
  -preset veryfast \
  -maxrate 3000k \
  -bufsize 6000k \
  -pix_fmt yuv420p \
  -g 60 \
  -c:a aac \
  -b:a 128k \
  -f flv \
  "rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY"

The -c:v libx264 flag re-encodes the video, which is CPU-intensive. If your camera outputs H.264 already, you can use -c:v copy to avoid re-encoding — but only if the bitrate and keyframe interval are compatible with the RTMP ingest.

Important limitation: RTMP to YouTube/Twitch makes your stream publicly accessible on that platform. It is not suitable for private monitoring dashboards, access-controlled camera feeds, or any stream that should not be public.

Using TheRelay for HLS and WebRTC Endpoints

TheRelay eliminates the need to set up and maintain a conversion server. Install the agent on any machine on your LAN, add your camera's RTSP URL in the dashboard, and TheRelay automatically provides both an HLS endpoint and a WebRTC endpoint for each stream — accessible from anywhere, with no port forwarding.

Getting your endpoint URLs

After adding a camera in your TheRelay dashboard at app.therelay.net, the stream detail page shows your endpoint URLs. They follow this pattern:

# HLS endpoint (for HLS.js embed)
https://stream.therelay.net/hls/YOUR_STREAM_ID/index.m3u8

# WebRTC embed URL (for iframe)
https://app.therelay.net/embed/webrtc/YOUR_STREAM_ID

Full HLS embed using TheRelay

Copy the HLS URL from your dashboard and drop it into the HLS.js template:

<video id="cam" controls autoplay muted playsinline style="width:100%;max-width:1280px"></video>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
<script>
  const video = document.getElementById('cam');
  const src = 'https://stream.therelay.net/hls/YOUR_STREAM_ID/index.m3u8';

  if (Hls.isSupported()) {
    const hls = new Hls();
    hls.loadSource(src);
    hls.attachMedia(video);
  } else if (video.canPlayType('application/vnd.apple.mpegurl')) {
    video.src = src;  // Safari native HLS
  }
</script>

No server infrastructure, no TLS certificates to manage, no camera credentials exposed to the browser. The HLS endpoint is served over HTTPS from TheRelay's CDN-backed infrastructure.

Pricing: TheRelay costs $2/stream/month. Each stream subscription includes HLS, WebRTC, RTSP, RTMP, and SRT cloud endpoints simultaneously.

Protocol Comparison

Protocol Latency Browser Support Server Needed Best Use Case
HLS 5–30 seconds All (Safari native, others via HLS.js) Yes (or cloud relay) Dashboards, VOD-like monitoring
LL-HLS 2–5 seconds Modern browsers + LL-HLS server Yes (or cloud relay) Near-real-time with broad compatibility
WebRTC < 500 ms All modern browsers Yes (or cloud relay) Real-time monitoring, intercom, security
RTMP (YouTube/Twitch) 10–30 seconds All (via platform player) FFmpeg encoder required Public broadcasts only
RTSP (direct) < 1 second Not supported Native clients (VLC, NVR) only

Recommendation: For private camera dashboards where a few seconds of delay is acceptable, use HLS with HLS.js — it's the most reliable and works on every device. For real-time security monitoring where latency matters, use WebRTC. For one-to-many public broadcasts, use RTMP to YouTube or Twitch.

Frequently Asked Questions

What is the best protocol to stream an IP camera to a website?

It depends on your latency requirement. HLS is the most browser-compatible — it works natively in Safari and with HLS.js in Chrome/Firefox/Edge — but adds 5–30 seconds of latency. WebRTC achieves sub-second latency but requires a WebRTC server or cloud relay. For most monitoring dashboards where a few seconds of delay is acceptable, HLS is the easiest and most reliable choice.

How do I embed a live camera feed in HTML?

You cannot embed an RTSP URL directly in HTML. You need to convert it first. With HLS, use the HLS.js library to play an .m3u8 URL in a standard <video> element. With WebRTC, use an iframe from a provider like TheRelay, or build your own player using RTCPeerConnection. The code examples in this article show both approaches.

Does HLS work in all browsers?

HLS works natively in Safari on macOS and iOS. In Chrome, Firefox, and Edge, you need the HLS.js JavaScript library. HLS.js is a well-maintained open-source project that uses the browser's Media Source Extensions (MSE) API to decode HLS segments — it does not require any browser plugin. With HLS.js included on your page, HLS playback works in all modern browsers.

What is the latency of HLS vs WebRTC?

Standard HLS latency is 15–30 seconds because the browser must download complete video segments before playback. Low-Latency HLS (LL-HLS) reduces this to 2–5 seconds with compatible server and player configuration. WebRTC achieves 100–500 ms latency because it streams RTP packets continuously rather than packaging them into file segments.

Can I stream an RTSP camera to YouTube or Twitch?

Yes, via RTMP. FFmpeg can pull RTSP from a camera and push it to a YouTube or Twitch RTMP ingest URL. The stream then becomes accessible on that platform via their standard player. Keep in mind this makes the stream public on that platform — it is not suitable for private or access-controlled monitoring pages.

Get HLS and WebRTC Endpoints for Your Cameras — Instantly

TheRelay converts your RTSP cameras to browser-ready HLS and WebRTC streams with no server setup. Install the agent, add your camera, get the embed URL. $2/stream/month.

Start Free Trial