Skip to main content

FFmpeg + NGINX HTTPS HLS Streaming Server Ubuntu 24.04

Update system & install dependencies

sudo apt update && sudo apt upgrade -y
sudo apt install -y ffmpeg nginx openssl

Create self-signed SSL cert for HTTPS
Please change domain with your own domain

sudo mkdir -p /etc/ssl/private /etc/ssl/certs
sudo openssl req -x509 -nodes -days 3650 -newkey rsa:2048 \
  -keyout /etc/ssl/private/stream-selfsigned.key \
  -out /etc/ssl/certs/stream-selfsigned.crt \
  -subj "/CN=stream.local"

Create web root for HLS

sudo mkdir -p /var/www/html/{cam1,cam2,cam3}
sudo chmod -R 777 /var/www/html

Configure NGINX for HTTPS + CORS

sudo nano /etc/nginx/sites-available/stream.conf

Paste this:

server {
    listen 443 ssl;
    server_name stream.local;

    ssl_certificate     /etc/ssl/certs/stream-selfsigned.crt;
    ssl_certificate_key /etc/ssl/private/stream-selfsigned.key;

    root /var/www/html;

    location / {
        autoindex on;
        add_header Access-Control-Allow-Origin *;
    }
}

Enable and restart:

sudo ln -s /etc/nginx/sites-available/stream.conf /etc/nginx/sites-enabled/
sudo rm /etc/nginx/sites-enabled/default
sudo systemctl restart nginx

Create FFmpeg scripts for each camera;

#!/bin/bash
# CamX - Keep 10 minutes of video (stable + low disk usage)

while true; do
  ffmpeg -hide_banner -loglevel warning \
    -rtsp_transport tcp \
    -i #change-this-with-camera-rtsp-url \
    -fflags +genpts -use_wallclock_as_timestamps 1 \
    -an -c:v copy \
    -f hls \
    -hls_time 10 \
    -hls_list_size 60 \
    -hls_flags delete_segments+append_list+program_date_time \
    -hls_segment_filename /var/www/html/camX/segment_%05d.ts \
    /var/www/html/camX/index.m3u8

  echo "CamX disconnected or FFmpeg crashed, restarting in 5s..."
  sleep 5
done

Change file permision

sudo chmod +x /usr/local/bin/cam*-stream.sh

Create systemd services (auto start & restart)

sudo tee /etc/systemd/system/camX.service <<'EOF'
[Unit]
Description=FFmpeg HLS Stream - Camera X
After=network.target

[Service]
ExecStart=/usr/local/bin/camX-stream.sh
Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

Enable all systemd services

sudo systemctl daemon-reload
sudo systemctl enable --now cam1 cam2 cam3

Verify cam services is running

sudo systemctl status camX

You should see them active. Then in browser:

https://<yourip-or-yourdomain>/cam1/index.m3u8
https://<yourip-or-yourdomain>/cam2/index.m3u8
https://<yourip-or-yourdomain>/cam3/index.m3u8