Unifeed UniFi Protect Camera → YouTube Live Streaming — Deployment Guide

This document covers every method for getting a live RTSP stream from UniFi Protect cameras onto YouTube Live — from the managed webcam.io cloud service to self-hosted Docker containers running FFmpeg.

Architecture

┌──────────────┐    RTSPS     ┌─────────────────┐    RTMP     ┌──────────────┐
│  UniFi       │─────────────▶│  Relay Service   │────────────▶│  YouTube     │
│  Protect     │  :7441       │  (webcam.io /    │  :1935      │  Live        │
│  Camera      │              │   FFmpeg/Docker) │             │              │
└──────────────┘              └─────────────────┘             └──────────────┘

The camera outputs RTSPS. A relay transcodes/forwards it as RTMP to YouTube's ingest servers.

Prerequisites

Step 1 — Enable RTSP on UniFi Protect

Enable the RTSP Stream

  1. Open the UniFi Protect web UI
  2. Go to Devices → select your camera
  3. Navigate to Settings → Advanced → RTSP
  4. Toggle RTSP On
  5. Choose quality: High, Medium, or Low
  6. Copy the RTSP URL displayed — you'll need this later

RTSP URL Formats

TypeURL PatternPort
RTSPS (via Protect) rtsps://<protect_ip>:7441/<camera_id> 7441
RTSP (direct to camera) rtsp://<camera_ip>:7447/<camera_id> 7447

Create a Dedicated RTSP User

Don't use your admin account. Create a restricted local user for streaming.

  1. Go to UniFi OS → Admins & Users
  2. Create a new local user
  3. Check "Restrict to local access only"
  4. Set a strong username/password

Authenticated RTSP URL:

rtsps://streamuser:yourpassword@192.168.1.1:7441/CAMERA_ID

Test the Stream

Open in VLC: Media → Open Network Stream and paste your RTSP URL. If it plays, you're good.

Step 2 — YouTube Live Setup

  1. Go to YouTube Studio
  2. Click Create → Go Live
  3. Choose "Schedule stream" (not "Stream" tab)
    Important: For 24/7 streaming, always use Scheduled Streams. The default "Stream Tab" will cause problems with continuous streams.
  4. Set your stream title, description, and visibility
  5. Copy your Stream Key — treat this like a password

YouTube RTMP Ingest URL

ProtocolURL
RTMPrtmp://a.rtmp.youtube.com/live2
RTMPS (secure)rtmps://a.rtmp.youtube.com:443/live2

Recommended Encoding Settings

ResolutionFPSBitrate
720p301,500 – 4,000 Kbps
1080p304,500 – 9,000 Kbps
4K3013,000 – 34,000 Kbps
Rule of thumb: Your stream bitrate should not exceed 50% of your upload speed. 10 Mbps upload → max 5 Mbps bitrate.

Step 3 — webcam.io Setup Cloud

webcam.io is a cloud relay service that pulls your camera's RTSP stream and pushes it to YouTube. No local software required.

Pricing

PlanPriceCamerasFeatures
Free$0Time-lapse only
LIVE~$5/moUp to 25H.264 live streaming
LIVE+HigherUp to 25H.265, MJPEG transcoding

Each camera that streams live requires its own LIVE plan. 7-day free trial available (no CC).

Network Requirements

Because webcam.io connects to your camera from the cloud, you must expose the RTSP port to the internet.

Port Forwarding

  1. Reserve your Protect controller's LAN IP in your router's DHCP settings
  2. Forward an external port (e.g. 8554) to internal 7441 on the Protect IP
  3. Verify the forward works with an online port-check tool

Dynamic DNS (DDNS)

Your ISP likely assigns a dynamic public IP. Set up DDNS (DuckDNS, No-IP, or your router's built-in client) so webcam.io always has a valid hostname.

Connect Camera in webcam.io

  1. Sign up at webcam.io
  2. Add a new camera
  3. Enter your RTSPS URL with DDNS hostname: rtsps://user:pass@yourhost.ddns.net:8554/CAMERA_ID
  4. Link your YouTube account and enter the stream key
  5. Select "Scheduled stream" mode
  6. Start streaming
Security trade-off: Port forwarding exposes your camera to the internet. Use a strong password, non-standard port, and keep firmware updated. If this is unacceptable, use one of the self-hosted methods below instead.

Alternative: Docker + FFmpeg Recommended Self-Hosted

Run FFmpeg in a Docker container with auto-restart. No port forwarding needed — runs on your LAN.

Setup

  1. Clone this repo:
    git clone https://github.com/kjcornwell/Unifeed.git
    cd Unifeed
  2. Copy and fill in environment variables:
    cp .env.example .env
    # Edit .env with your actual values
  3. Start the stream:
    docker compose up -d

docker-compose.yml

version: '3.8'

services:
  camera1:
    image: jrottenberg/ffmpeg:latest
    container_name: unifeed-${CAMERA_1_NAME:-camera1}
    restart: unless-stopped
    network_mode: host
    logging:
      driver: "json-file"
      options:
        max-size: "10m"
        max-file: "3"
    command: >
      -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100
      -thread_queue_size 256
      -rtsp_transport tcp
      -i rtsps://${RTSP_USER}:${RTSP_PASS}@${PROTECT_IP}:7441/${CAMERA_1_ID}
      -shortest
      -vf "fps=30"
      -map 0:a:0 -c:a aac -b:a 128k
      -map 1:v:0 -c:v libx264 -preset veryfast -crf 28 -g 60
      -maxrate 4500k -bufsize 9000k
      -f flv rtmp://a.rtmp.youtube.com/live2/${YT_STREAM_KEY_1}

.env File

RTSP_USER=streamuser
RTSP_PASS=changeme
PROTECT_IP=192.168.1.1
CAMERA_1_ID=your-camera-id-here
CAMERA_1_NAME=front-beach
YT_STREAM_KEY_1=xxxx-xxxx-xxxx-xxxx-xxxx

FFmpeg Flags Explained

FlagPurpose
-f lavfi -i anullsrc=...Generate silent audio (YouTube requires an audio track)
-thread_queue_size 256Input buffer for smoother streaming
-rtsp_transport tcpUse TCP for RTSP (more reliable than UDP)
-shortestEnd when the shortest input ends
-vf "fps=30"Force 30 FPS output
-c:v libx264 -preset veryfastH.264 encoding, fast preset (low CPU)
-crf 28Quality level (lower = better, 28 is decent for webcam)
-g 60Keyframe every 60 frames (2 sec at 30fps)
-maxrate 4500k -bufsize 9000kBitrate cap for consistent upload
-f flvFLV container (required for RTMP to YouTube)

Management Commands

# View logs
docker logs -f unifeed-front-beach

# Restart
docker restart unifeed-front-beach

# Stop
docker compose down

# Start
docker compose up -d

Alternative: FFmpeg Direct Quick & Simple

Run FFmpeg straight from the command line. Good for testing, not ideal for 24/7.

Passthrough (no re-encode)

ffmpeg \
  -rtsp_transport tcp \
  -i "rtsps://user:pass@192.168.1.1:7441/CAMERA_ID" \
  -c:v copy -c:a copy \
  -f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY

With Silent Audio + Re-encode

ffmpeg \
  -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 \
  -thread_queue_size 256 -rtsp_transport tcp \
  -i "rtsps://user:pass@192.168.1.1:7441/CAMERA_ID" \
  -shortest \
  -vf "fps=30" \
  -map 0:a:0 -c:a aac -b:a 128k \
  -map 1:v:0 -c:v libx264 -preset veryfast -crf 28 -g 60 \
  -f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY

With GPU Hardware Encoding

GPUEncoder Flag
NVIDIA-c:v h264_nvenc
Intel-c:v h264_qsv
AMD-c:v h264_amf

Alternative: OBS Studio GUI

  1. Open OBS → Sources+Media Source
  2. Uncheck "Local File" → paste RTSP URL
  3. Go to Settings → Stream → Service: YouTube
  4. Paste your stream key → Start Streaming
Note: OBS is not a great RTSP client. Expect occasional disconnects. Best for temporary or preview use, not 24/7 production.

Alternative: MediaMTX Relay Advanced

MediaMTX acts as a local RTSP proxy. Useful if multiple consumers need the same camera stream.

mediamtx.yml

paths:
  camera1:
    source: rtsps://user:pass@192.168.1.1:7441/CAMERA_ID
    sourceProtocol: rtsps
    sourceOnDemand: yes

Then pipe through FFmpeg

ffmpeg \
  -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 \
  -i rtsp://localhost:8554/camera1 \
  -shortest \
  -map 0:a:0 -c:a aac -b:a 128k \
  -map 1:v:0 -c:v copy \
  -f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY

Alternative: Windows Service (NSSM) Windows

Run FFmpeg as a Windows service that starts at boot — no user login required.

Install

  1. Download NSSM and FFmpeg
  2. Create stream.bat:
    @echo off
    C:\Tools\ffmpeg\bin\ffmpeg.exe ^
      -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 ^
      -thread_queue_size 256 -rtsp_transport tcp ^
      -i rtsps://user:pass@192.168.1.1:7441/CAMERA_ID ^
      -shortest -vf "fps=30" ^
      -map 0:a:0 -c:a aac -b:a 128k ^
      -map 1:v:0 -c:v libx264 -preset veryfast -crf 28 -g 60 ^
      -f flv rtmp://a.rtmp.youtube.com/live2/YOUR_STREAM_KEY
  3. Register the service (Admin CMD):
    nssm install UnifeedStream C:\path\to\stream.bat
    nssm start UnifeedStream

Manage

nssm start UnifeedStream
nssm stop UnifeedStream
nssm restart UnifeedStream
nssm remove UnifeedStream confirm

Multi-Camera Setup

Duplicate the service block in docker-compose.yml for each camera. Each needs its own YouTube stream key.

services:
  front-beach:
    image: jrottenberg/ffmpeg:latest
    container_name: unifeed-front-beach
    restart: unless-stopped
    network_mode: host
    command: >
      -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100
      -thread_queue_size 256 -rtsp_transport tcp
      -i rtsps://${RTSP_USER}:${RTSP_PASS}@${PROTECT_IP}:7441/${CAMERA_1_ID}
      -shortest -vf "fps=30"
      -map 0:a:0 -c:a aac -b:a 128k
      -map 1:v:0 -c:v libx264 -preset veryfast -crf 28 -g 60
      -maxrate 4500k -bufsize 9000k
      -f flv rtmp://a.rtmp.youtube.com/live2/${YT_STREAM_KEY_1}

  pool-deck:
    image: jrottenberg/ffmpeg:latest
    container_name: unifeed-pool-deck
    restart: unless-stopped
    network_mode: host
    command: >
      -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100
      -thread_queue_size 256 -rtsp_transport tcp
      -i rtsps://${RTSP_USER}:${RTSP_PASS}@${PROTECT_IP}:7441/${CAMERA_2_ID}
      -shortest -vf "fps=30"
      -map 0:a:0 -c:a aac -b:a 128k
      -map 1:v:0 -c:v libx264 -preset veryfast -crf 28 -g 60
      -maxrate 4500k -bufsize 9000k
      -f flv rtmp://a.rtmp.youtube.com/live2/${YT_STREAM_KEY_2}

Troubleshooting

Can't connect to RTSP stream

Stream keeps disconnecting

YouTube rejects the stream

High CPU usage

YouTube stream dies when no viewers

Security

Never commit secrets. The .env file is in .gitignore. Keep stream keys and RTSP passwords out of version control.

Decision Matrix

MethodCostComplexityReliabilityBest For
webcam.io $5+/moLowHigh Hands-off, non-technical
Docker + FFmpeg FreeMediumHigh Production, multi-camera
FFmpeg Direct FreeMediumMedium Testing, one-off streams
OBS Studio FreeLowLow Preview, temporary use
Windows Service FreeHighHigh Windows-only servers
MediaMTX + FFmpeg FreeHighVery High Multi-consumer, advanced

Quick Reference

Test RTSP in VLC

vlc rtsps://user:pass@192.168.1.1:7441/CAMERA_ID

One-liner: RTSP → YouTube

ffmpeg -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 \
  -thread_queue_size 256 -rtsp_transport tcp \
  -i "rtsps://user:pass@192.168.1.1:7441/CAMERA_ID" \
  -shortest -vf "fps=30" \
  -map 0:a:0 -c:a aac -b:a 128k \
  -map 1:v:0 -c:v libx264 -preset veryfast -crf 28 -g 60 \
  -f flv rtmp://a.rtmp.youtube.com/live2/STREAM_KEY

Docker Quick Start

git clone https://github.com/kjcornwell/Unifeed.git && cd Unifeed
cp .env.example .env    # fill in your values
docker compose up -d    # start streaming
docker logs -f unifeed-front-beach  # watch logs

Key Ports

PortProtocolService
7441RTSPSUniFi Protect (encrypted)
7447RTSPUniFi Protect (direct)
1935RTMPYouTube ingest
443RTMPSYouTube ingest (encrypted)

Unifeed — Last updated February 2026 — github.com/kjcornwell/Unifeed