obs-r2-uploader/SETUP.md

8.8 KiB

OBS R2 Uploader - Complete Setup Guide

Step-by-step guide to get your OBS recording upload system running.

Prerequisites

Before you begin, ensure you have:

  • Node.js 18+ installed (download)
  • Python 3.8+ installed (download)
  • OBS Studio installed (download)
  • Cloudflare account with R2 enabled (sign up)
  • Domain in Cloudflare (jeffemmett.com in your case)

Step 1: Clone and Install

# Navigate to the project directory
cd obs-r2-uploader

# Run setup script
./scripts/setup.sh

This will:

  • Check prerequisites
  • Install Python dependencies
  • Install Wrangler CLI (if needed)
  • Create .env file from template

Step 2: Authenticate with Cloudflare

# Login to Cloudflare via browser
wrangler login

This opens your browser for OAuth authentication.

Verify authentication:

wrangler whoami

Step 3: Create R2 Bucket and API Tokens

./scripts/deploy.sh

This creates the bucket and deploys the worker.

Option B: Manual Setup

# Create bucket
wrangler r2 bucket create obs-videos

# Verify creation
wrangler r2 bucket list

Generate R2 API Tokens

You need API tokens for the Python upload script:

  1. Go to Cloudflare Dashboard
  2. Navigate to R2 in the sidebar
  3. Click on your obs-videos bucket
  4. Go to SettingsR2 API Tokens
  5. Click Create API Token
  6. Configure:
    • Token name: obs-uploader
    • Permissions: Admin Read & Write
    • TTL: No expiry (or set as desired)
  7. Click Create API Token
  8. SAVE THESE CREDENTIALS - you'll need them for .env

You'll receive:

  • Access Key ID
  • Secret Access Key

Step 4: Get Your Account ID

# Get account ID from wrangler
wrangler whoami

Or from dashboard:

  1. Go to any page in Cloudflare Dashboard
  2. Look at the URL: https://dash.cloudflare.com/{ACCOUNT_ID}/...
  3. The account ID is in the URL

Step 5: Configure Environment Variables

Edit .env file with your credentials:

# Replace with your actual values
R2_ACCOUNT_ID=your_account_id_here
R2_ACCESS_KEY_ID=your_access_key_here
R2_SECRET_ACCESS_KEY=your_secret_access_key_here
R2_BUCKET_NAME=obs-videos

# Auto-generated endpoint (replace account-id)
R2_ENDPOINT=https://your_account_id_here.r2.cloudflarestorage.com

# Your public domain
PUBLIC_DOMAIN=videos.jeffemmett.com

# Optional: Set your OBS recording directory
OBS_RECORDING_DIR=/path/to/obs/recordings

# Optional: Auto-delete after upload
AUTO_DELETE_AFTER_UPLOAD=false

Step 6: Configure CORS for R2 Bucket

CORS must be configured to allow browser access to videos.

Via Cloudflare Dashboard:

  1. Go to R2obs-videos bucket
  2. Navigate to SettingsCORS Policy
  3. Click Add CORS Policy
  4. Configure:
    {
      "AllowedOrigins": ["*"],
      "AllowedMethods": ["GET", "HEAD"],
      "AllowedHeaders": ["*"],
      "MaxAgeSeconds": 3600
    }
    
  5. Click Save

Via API (Alternative):

# Using the provided CORS config
curl -X PUT \
  "https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/r2/buckets/obs-videos/cors" \
  -H "Authorization: Bearer {API_TOKEN}" \
  -H "Content-Type: application/json" \
  -d @cors-config.json

Step 7: Deploy Cloudflare Worker

cd worker
wrangler deploy
cd ..

This deploys your video server worker.

Verify deployment:

wrangler deployments list

Step 8: Configure Custom Domain

Set up videos.jeffemmett.com to point to your worker:

  1. Go to Workers & Pages in Cloudflare Dashboard
  2. Click on your obs-video-server worker
  3. Go to SettingsDomains & Routes
  4. Click Add Custom Domain
  5. Enter: videos.jeffemmett.com
  6. Click Add Domain

Cloudflare automatically:

  • Creates DNS records
  • Issues SSL certificate
  • Routes traffic to your worker

Option B: Via Wrangler

Edit worker/wrangler.toml:

[env.production]
routes = [
  { pattern = "videos.jeffemmett.com/*", custom_domain = true }
]

Then deploy:

cd worker
wrangler deploy --env production
cd ..

Step 9: Enable R2 Public Access

You need to make the bucket publicly readable via your custom domain.

Via Dashboard:

  1. Go to R2obs-videos bucket
  2. Go to SettingsPublic Access
  3. Click Connect Domain
  4. Select Custom Domain: videos.jeffemmett.com
  5. Click Connect

This creates a public URL for your bucket content.

Step 10: Test Upload

Test that everything works:

# Create and upload a test video (requires ffmpeg)
./scripts/test-upload.sh

# Or upload an existing video
./scripts/upload.sh /path/to/your/video.mp4

Expected output:

Uploading video.mp4 (52.3 MB)
Uploading video.mp4: 100%|████████| 52.3M/52.3M [00:15<00:00, 3.48MB/s]
✓ Upload successful: video.mp4

============================================================
✓ Upload successful!
============================================================

Public URL: https://videos.jeffemmett.com/video.mp4

The URL has been copied to your clipboard.
============================================================

Step 11: Test Video Access

  1. Direct video URL: Open the URL from step 10 in your browser
  2. Gallery view: Visit https://videos.jeffemmett.com/gallery
  3. JSON API: Visit https://videos.jeffemmett.com/

Step 12: Configure OBS (Optional)

Set up OBS to save recordings to a known directory:

  1. Open OBS Studio
  2. Go to SettingsOutput
  3. Note your Recording Path
  4. Add this path to .env:
    OBS_RECORDING_DIR=/path/from/obs/settings
    

Step 13: Set Up Auto-Upload (Optional)

Start the file watcher to automatically upload new recordings:

./scripts/start-watcher.sh

Or specify a directory:

./scripts/start-watcher.sh /path/to/obs/recordings

The watcher will:

  • Monitor for new video files
  • Wait until recording is complete
  • Automatically upload
  • Copy URL to clipboard
  • Optionally delete local file

Verification Checklist

  • Wrangler authenticated (wrangler whoami)
  • R2 bucket created (wrangler r2 bucket list)
  • .env configured with credentials
  • CORS configured on bucket
  • Worker deployed successfully
  • Custom domain connected (videos.jeffemmett.com)
  • Test video uploaded successfully
  • Video accessible via public URL
  • Gallery page loads correctly
  • File watcher runs (optional)

Troubleshooting

Error: "Wrangler not found"

npm install -g wrangler

Error: "Invalid R2 credentials"

  • Double-check .env values
  • Regenerate R2 API token if needed
  • Ensure endpoint URL is correct

Error: "Bucket not found"

# List buckets
wrangler r2 bucket list

# Create bucket if missing
wrangler r2 bucket create obs-videos

Error: "Worker deployment failed"

# Check logs
wrangler tail

# Redeploy
cd worker && wrangler deploy

Videos return 404

  • Verify custom domain is connected
  • Check worker binding in wrangler.toml
  • Ensure bucket name matches in config

CORS errors in browser

  • Verify CORS is configured on R2 bucket
  • Check browser console for specific CORS errors
  • May need to wait a few minutes for CORS changes to propagate

Upload fails on large files

  • Check internet connection stability
  • Multipart upload should handle large files automatically
  • Try upload with smaller test file first

Finding Your OBS Recording Directory

Windows

Default: C:\Users\{Username}\Videos

  1. Open OBS
  2. Settings → Output → Recording Path

macOS

Default: ~/Movies

  1. Open OBS
  2. Preferences → Output → Recording Path

Linux

Default: ~/Videos

  1. Open OBS
  2. Settings → Output → Recording Path

Next Steps

  • Configure OBS to record to a specific directory
  • Set up the file watcher for auto-uploads
  • Share your video links!
  • Consider setting up video thumbnails (future feature)
  • Explore the gallery customization options

Getting Help

If you encounter issues:

  1. Check the README.md troubleshooting section
  2. Verify all environment variables in .env
  3. Check Cloudflare dashboard for errors
  4. Review worker logs: wrangler tail

Security Best Practices

  1. Never commit .env - it's in .gitignore
  2. Rotate API keys periodically
  3. Use separate tokens for different environments
  4. Monitor R2 usage in Cloudflare dashboard
  5. Consider signed URLs for sensitive videos (not implemented yet)

Setup Complete! 🎉

You can now upload OBS recordings directly to R2 and share them via videos.jeffemmett.com.