Live-Streaming Arendalsuka 2024 to Facebook & LinkedIn Simultaneously

Challenge

Arendalsuka (Norway's largest political week) 2024 needed:

  • 4 cameras (Logitech Brio 4K)
  • Simultaneous stream to Facebook & LinkedIn
  • 6 hours/day streaming for 5 days
  • Automatic scene switching based on speaker
  • Zero budget for commercial streaming platforms

Solution

Repository: Arendalsuka-Multicam-Stream documents the full setup.

Stack

ComponentTechnology
Video MixerOBS Studio 29.x
Multi-outputnginx-rtmp (Docker)
Scene AutomationCustom Python script
Cameras4 Γ— Logitech Brio via USB 3.0 hub
AudioBehringer X32 mixer β†’ OBS

Architecture

[4Γ— Logitech Brio] β†’ [USB 3.0 Hub] β†’ [OBS Studio]
                                                      ↓
                         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
                         β–Ό                                                         β–Ό
                  [nginx-rtmp]                                                 [nginx-rtmp]
                    (Facebook)                                                   (LinkedIn)
                         β”‚                                                         β”‚
                         β–Ό                                                         β–Ό
                   rtmp://live-api-s.fb...                                  rtmp://linkedin...

Key Components

1. nginx-rtmp for Multi-Output

# nginx.conf
rtmp {
    server {
        listen 1935;
        chunk_size 4096;

        application live {
            live on;
            record off;
            
            # Facebook
            push rtmp://live-api-s.facebook.com/rtmp/STREAM_KEY;
            
            # LinkedIn
            push rtmp://rtmp-api.linkedin.com/rtmp/STREAM_KEY;
        }
    }
}

Run in Docker:

docker run -d \
  -p 1935:1935 \
  -v $(pwd)/nginx.conf:/etc/nginx/nginx.conf \
  tiangolo/nginx-rtmp

2. Auto Scene Switching (Python)

# auto_switch.py
# Switch scene to loudest camera based on audio levels

import obsws_python as obs
import time

client = obs.ReqClient(host='localhost', port=4455, password='secret')

SCENES = ['cam1', 'cam2', 'cam3', 'cam4']

def get_audio_levels():
    # Query OBS for input volume levels
    levels = {}
    for scene in SCENES:
        resp = client.get_input_volume(scene)
        levels[scene] = resp.input_volume_mul
    return levels

while True:
    levels = get_audio_levels()
    loudest = max(levels, key=lambda x: levels[x])
    if levels[loudest] > 0.1:  # threshold
        client.set_current_program_scene(loudest)
    time.sleep(0.5)

3. OBS Scene Collection

SceneSourcePurpose
cam1Logitech Brio #1Main speaker
cam2Logitech Brio #2Audience / wide
cam3Logitech Brio #3Presentation screen
cam4Logitech Brio #4Backup / roving
brbStatic image"Be Right Back"
starting-soonCountdown timerPre-stream

Results

MetricResult
Sessions streamed12
Total hours~36
Dropped frames0
Setup time per day<30 min
Concurrent viewers (peak)1,200+
PlatformsFacebook + LinkedIn simultaneously

Lessons Learned

  1. nginx-rtmp is rock-solid β€” handled 5 days of continuous streaming without restart
  2. Audio-based switching works β€” no manual operator needed for panel discussions
  3. USB 3.0 bandwidth β€” 4Γ— 4K@30fps needs a quality powered hub
  4. Test stream keys early β€” LinkedIn keys expire, Facebook keys persist
  5. Backup recording β€” OBS local recording saved us when LinkedIn had ingest issues

Open source streaming infrastructure β€” no vendor lock-in, no monthly fees.