obs-r2-uploader/streaming/STREAMING-SETUP.md

242 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Live Streaming Setup Guide
This guide will help you set up hybrid live streaming with HLS + automatic VOD archiving to R2.
## Architecture
```
OBS → RTMP → nginx-rtmp → HLS chunks → Real-time uploader → R2 → Cloudflare Worker → Viewers
VOD Archive
```
## Quick Start
### 1. Start the Streaming Stack
```bash
cd streaming
./start-streaming.sh
```
This will:
- Start nginx-rtmp server (Docker)
- Start HLS chunk uploader to R2
- Display connection info
### 2. Configure OBS
#### Settings → Stream
1. **Service**: Custom
2. **Server**: `rtmp://localhost/live`
3. **Stream Key**: `my-stream` (or choose your own name like `gaming`, `podcast`, etc.)
#### Settings → Output
**Recommended Settings for 1080p60:**
- **Output Mode**: Advanced
- **Encoder**: x264 or Hardware (NVENC/AMD/QuickSync)
- **Rate Control**: CBR
- **Bitrate**: 6000 Kbps (adjust based on upload speed)
- **Keyframe Interval**: 2 seconds
- **CPU Usage Preset**: veryfast (or faster for lower-end CPUs)
- **Profile**: high
- **Tune**: zerolatency
**For 720p60:**
- **Bitrate**: 4500 Kbps
**For 1080p30:**
- **Bitrate**: 4500 Kbps
#### Settings → Video
- **Base Resolution**: 1920x1080 (or your monitor resolution)
- **Output Resolution**: 1920x1080 or 1280x720
- **FPS**: 60 or 30
#### Settings → Advanced
- **Process Priority**: High (optional, for smoother streaming)
### 3. Start Streaming
1. Click "Start Streaming" in OBS
2. Wait 5-10 seconds for HLS chunks to be created
3. Access your stream at:
- Local (testing): `http://localhost:8081/hls/my-stream.m3u8`
- Public: `https://videos.jeffemmett.com/live/my-stream/my-stream.m3u8`
### 4. Watch Your Stream
#### In a browser:
- Use the HLS.js player
- Or use VLC: Media → Open Network Stream → Enter URL
#### Test Player HTML:
```html
<!DOCTYPE html>
<html>
<head>
<script src="https://cdn.jsdelivr.net/npm/hls.js@latest"></script>
</head>
<body>
<video id="video" controls style="width: 100%; max-width: 1280px;"></video>
<script>
const video = document.getElementById('video');
const src = 'https://videos.jeffemmett.com/live/my-stream/my-stream.m3u8';
if (Hls.isSupported()) {
const hls = new Hls();
hls.loadSource(src);
hls.attachMedia(video);
hls.on(Hls.Events.MANIFEST_PARSED, () => {
video.play();
});
} else if (video.canPlayType('application/vnd.apple.mpegurl')) {
video.src = src;
}
</script>
</body>
</html>
```
### 5. Stop Streaming
1. Click "Stop Streaming" in OBS
2. (Optional) Stop the streaming stack:
```bash
./stop-streaming.sh
```
## How It Works
### Real-Time Streaming
1. **OBS** sends RTMP stream to `rtmp://localhost/live/my-stream`
2. **nginx-rtmp** receives the stream and segments it into HLS chunks:
- Creates `.m3u8` playlist (updated every 2 seconds)
- Creates `.ts` video chunks (2-second segments)
3. **HLS Uploader** watches the `hls/` directory:
- Detects new chunks as they're created
- Immediately uploads to R2 at `live/my-stream/`
4. **Cloudflare Worker** serves the chunks:
- Viewers request `.m3u8` playlist
- Player loads `.ts` chunks as they become available
- ~5-10 second latency end-to-end
### Automatic VOD Archiving
- All HLS chunks remain in R2 after stream ends
- Can be concatenated into full VOD recording
- Or left as is for HLS replay
## Troubleshooting
### Stream won't connect
- Check if nginx-rtmp is running: `docker ps | grep obs-streaming-server`
- Check nginx logs: `docker logs obs-streaming-server`
- Verify RTMP URL: `rtmp://localhost/live` (not `rtmp://localhost:1935/live`)
### Stream is choppy/buffering
- Lower bitrate in OBS Output settings
- Check CPU usage - try faster encoder preset
- Check upload bandwidth - run speed test
### Can't see stream on public URL
- Wait 5-10 seconds after starting stream
- Check HLS uploader logs: `tail -f streaming/hls-uploader.log`
- Verify chunks are being uploaded to R2
### High latency (>15 seconds)
- Normal for HLS - typical latency is 6-15 seconds
- Lower `hls_fragment` in nginx.conf to 1s (will increase bandwidth)
- Consider WebRTC for sub-second latency (different setup)
## Advanced Configuration
### Multiple Quality Levels
Edit `streaming/nginx/nginx.conf`:
```nginx
hls_variant _360p BANDWIDTH=800000;
hls_variant _720p BANDWIDTH=2800000;
hls_variant _1080p BANDWIDTH=5000000;
```
### Change Stream Key
Use any stream key you want - it becomes the folder name in R2:
- Stream key: `my-stream` → R2 path: `live/my-stream/` (default)
- Stream key: `gaming` → R2 path: `live/gaming/`
- Stream key: `podcast-ep-5` → R2 path: `live/podcast-ep-5/`
### Custom Domain
If using a different domain, update in `.env`:
```
PUBLIC_DOMAIN=streams.yourdomain.com
```
## Performance Notes
### Bandwidth Usage
- **720p60 @ 4500kbps**: ~2.0 GB/hour
- **1080p60 @ 6000kbps**: ~2.7 GB/hour
- **1080p30 @ 4500kbps**: ~2.0 GB/hour
### R2 Costs
- **Storage**: $0.015/GB/month
- **Class A Operations** (uploads): $4.50/million
- **Class B Operations** (downloads): $0.36/million
- **Egress**: Free to Cloudflare network
Example cost for 1 hour stream at 1080p60:
- Storage: ~2.7GB × $0.015 = $0.04/month
- Uploads: ~1800 chunks × $0.0000045 = $0.008
- **Total: ~$0.05** per hour streamed
### Viewer Bandwidth
Viewers consume:
- **720p**: ~4.5 Mbps
- **1080p**: ~6 Mbps
## File Structure
```
streaming/
├── docker-compose.yml # nginx-rtmp container config
├── nginx/
│ └── nginx.conf # nginx RTMP + HLS config
├── scripts/
│ ├── on_publish.sh # Called when stream starts
│ └── on_publish_done.sh # Called when stream ends
├── hls/ # HLS output directory (auto-created)
│ ├── my-stream.m3u8 # Playlist
│ └── my-stream-*.ts # Video chunks
├── start-streaming.sh # Start everything
├── stop-streaming.sh # Stop everything
└── STREAMING-SETUP.md # This file
```
## Next Steps
- Create a custom player page
- Set up stream notifications (when stream goes live)
- Add stream recording/VOD conversion
- Implement chat/comments
- Add stream analytics
## Support
For issues, check:
1. Docker logs: `docker logs obs-streaming-server`
2. HLS uploader logs: `tail -f streaming/hls-uploader.log`
3. Nginx stats: `http://localhost:8081/stat`