FFmpeg + NGINX HTTPS HLS Streaming Server Ubuntu 24.04
🧩 Step 1 — Update and install dependencies
sudo apt update
sudo apt install -y ffmpeg nginx python3-yaml openssl
🗂️ Step 2 — Directory setup
sudo mkdir -p /usr/local/ffmpeg-hls
sudo mkdir -p /var/www/html/cctv
sudo chown -R www-data:www-data /var/www/html
🧾 Step 3 — Camera configuration file
Create file /usr/local/ffmpeg-hls/cams.yml
- name: cam1
url: rtsp-url-here
- name: cam2
url: rtsp-url-here
- name: cam3
url: rtsp-url-here
# Add up to cam16 if needed...
⚙️ Step 4 — Auto FFmpeg launcher script
Create file /usr/local/ffmpeg-hls/start-all-cams.sh
#!/bin/bash
CONFIG_FILE="/usr/local/ffmpeg-hls/cams.yml"
OUTPUT_ROOT="/var/www/html/cctv"
HLS_DURATION=10 # seconds per segment
TOTAL_HISTORY_MIN=10 # total minutes to keep
SEGMENTS_TO_KEEP=$(( (TOTAL_HISTORY_MIN*60) / HLS_DURATION ))
mkdir -p "$OUTPUT_ROOT"
# 1️⃣ Generate list of active cams
python3 - <<'PYCODE' > /tmp/camlist.txt
import yaml, sys
data = yaml.safe_load(open("/usr/local/ffmpeg-hls/cams.yml"))
for cam in data:
print(f"{cam['name']}|{cam['url']}")
PYCODE
# 2️⃣ Build array of active cam names
ACTIVE_CAMS=($(awk -F'|' '{print $1}' /tmp/camlist.txt))
# 3️⃣ Clean up old folders not in YAML
for dir in "$OUTPUT_ROOT"/*/; do
[ -d "$dir" ] || continue
CAM_NAME=$(basename "$dir")
if [[ ! " ${ACTIVE_CAMS[@]} " =~ " ${CAM_NAME} " ]]; then
echo "🧹 Removing old folder: $dir"
rm -rf "$dir"
fi
done
# 4️⃣ Start each active camera
while IFS="|" read -r NAME URL; do
[ -z "$NAME" ] && continue
mkdir -p "$OUTPUT_ROOT/$NAME"
echo "🎥 Starting $NAME ..."
(
while true; do
ffmpeg -hide_banner -loglevel warning \
-rtsp_transport tcp \
-i "$URL" \
-fflags +genpts -use_wallclock_as_timestamps 1 \
-an -c:v copy \
-f hls \
-hls_time $HLS_DURATION \
-hls_list_size $SEGMENTS_TO_KEEP \
-hls_flags delete_segments+append_list+program_date_time \
-hls_segment_filename "$OUTPUT_ROOT/$NAME/segment_%05d.ts" \
"$OUTPUT_ROOT/$NAME/index.m3u8"
echo "⚠️ $NAME disconnected, retrying in 5s..."
sleep 5
done
) &
done < /tmp/camlist.txt
echo "✅ All active camera streams started!"
wait