Real-Time Messaging Protocol for legacy and platform streaming
RTMP (Real-Time Messaging Protocol) was originally developed by Macromedia (now Adobe) for Flash-based streaming. Despite Flash's deprecation, RTMP remains the de facto standard for ingest streaming to platforms like YouTube, Facebook, and Twitch due to its reliability and universal encoder support.
Technical details and evolution of RTMP
When to use RTMP and platform-specific considerations
| Platform | Server URL | Keyframe | Max Bitrate | Recommended |
|---|---|---|---|---|
| YouTube Live | rtmp://a.rtmp.youtube.com/live2 | 2s | 9,000 Kbps | 1080p60 |
| Facebook Live | rtmps://live-api-s.facebook.com:443/rtmp/ | 2s | 8,000 Kbps | 1080p30 |
| Twitch | rtmp://live.twitch.tv/app/ | 2s | 6,000 Kbps | 1080p60 |
| LinkedIn Live | rtmps://fa.linkedin.com:443/rtmp/ | 2s | 5,000 Kbps | 720p30 |
| WAVE Platform | rtmp://ingest.wave.inc/live/ | 2s | Unlimited | 1080p60 |
| Resolution | Video Bitrate | Audio Bitrate | Total Bandwidth | Keyframe |
|---|---|---|---|---|
| 480p30 | 500 - 1,000 Kbps | 64 Kbps | 600 - 1,100 Kbps | 2s |
| 720p30 | 1,500 - 3,000 Kbps | 128 Kbps | 1,700 - 3,200 Kbps | 2s |
| 720p60 | 2,500 - 5,000 Kbps | 128 Kbps | 2,700 - 5,200 Kbps | 2s |
| 1080p30 | 3,000 - 6,000 Kbps | 160 Kbps | 3,200 - 6,200 Kbps | 2s |
| 1080p60 | 4,500 - 9,000 Kbps | 160 Kbps | 4,700 - 9,200 Kbps | 2s |
RTMP adds approximately 8-13% overhead to your stream due to protocol headers, TCP/IP overhead, and metadata:
Example: For 6,000 Kbps video bitrate, plan for ~7,000 Kbps total uplink bandwidth.
Detailed configuration guide for professional RTMP streaming
Navigate to Settings → Stream and configure your RTMP endpoint:
rtmp://ingest.wave.inc/live/)Configure advanced output settings for professional quality:
Settings → Output → Output Mode: "Advanced" Streaming Tab: - Audio Track: 1 - Encoder: Select based on your hardware (see Step 3) - Rescale Output: Unchecked (unless downscaling needed) - Rate Control: CBR (Constant Bitrate) - Bitrate: 6000 Kbps (adjust based on resolution) - Keyframe Interval: 2 (2 seconds, required by most platforms) - CPU Usage Preset: veryfast (CPU) or Quality (GPU) - Profile: high - Tune: none - x264 Options: (leave blank unless advanced user)
Choose the best encoder for your system:
Configure resolution and frame rate settings:
Settings → Video Base (Canvas) Resolution: 1920x1080 - This is your source resolution (match your display or capture) Output (Scaled) Resolution: 1920x1080 - This is the resolution sent to the stream - Can downscale if needed (e.g., 1280x720 for lower bitrate) Downscale Filter: Lanczos (Sharpened scaling, 36 samples) - Best quality for downscaling - Use Bilinear if CPU constrained Common FPS Values: 60 or 30 - 60 FPS: Gaming, fast motion (requires higher bitrate) - 30 FPS: Presentations, interviews (lower bitrate)
Optimize audio settings for professional quality:
Settings → Audio Sample Rate: 48 kHz (professional standard) - Do NOT use 44.1 kHz (may cause sync issues) Channels: Stereo Global Audio Devices: - Desktop Audio: Select your system audio output - Mic/Auxiliary Audio: Select your microphone Advanced Settings (Settings → Output → Audio Tab): - Audio Bitrate: 160 Kbps (Track 1) - Encoder: AAC Audio Mixer (Main OBS Window): - Set levels to peak around -6dB to -12dB - Avoid red (clipping) - Use filters for noise suppression, gain, compression
Fine-tune advanced settings for optimal performance:
Settings → Advanced Process Priority: High (if dedicated streaming PC) or Above Normal - Gives OBS higher priority for CPU resources Renderer: Direct3D 11 (Windows) / Metal (Mac) / OpenGL (Linux) Color Format: NV12 (best for H.264 encoding) Color Space: 709 (HD standard) Color Range: Limited (required for proper color on most platforms) Network Settings: - Bind to IP: (leave as Default unless multiple network adapters) - Enable Dynamic Bitrate: Unchecked (for RTMP) - Network Buffering: Unchecked Recording Settings: - Filename Formatting: Keep default or customize - Automatic File Splitting: Can enable if recording long streams
Create scenes and add sources for your stream:
Start streaming and monitor performance metrics:
Bitrate ladders, GOP settings, and professional optimizations
While RTMP itself doesn't support adaptive bitrate (ABR), you can configure OBS to output multiple streams at different bitrates for server-side transcoding:
# Bitrate Ladder Configuration (for multi-stream setups) Source Stream (1080p60): - Resolution: 1920x1080 - Bitrate: 6,000 Kbps - Keyframe: 2s High Quality (720p60): - Resolution: 1280x720 - Bitrate: 4,500 Kbps - Keyframe: 2s (must match source) Medium Quality (720p30): - Resolution: 1280x720 - Bitrate: 2,500 Kbps - Keyframe: 2s (must match source) Low Quality (480p30): - Resolution: 854x480 - Bitrate: 1,000 Kbps - Keyframe: 2s (must match source) # All streams MUST have identical keyframe intervals for seamless ABR switching
# OBS Settings → Output → Streaming → x264 Options field # Low latency streaming (sacrifice some quality for speed): tune=zerolatency bframes=0 # High quality streaming (dedicated streaming PC): tune=film crf=18 preset=slow # Gaming with good motion (fast movement games): tune=film ref=3 bframes=2 # Screen sharing / presentation (static content): tune=stillimage crf=20 # Disable x264 CPU optimizations (troubleshooting): threads=4 no-mbtree=1 # Note: Only add these if you understand the impact on encoding
RTMP support across professional encoding software
| Encoder | RTMP Support | Latency | Quality | CPU Usage | Difficulty |
|---|---|---|---|---|---|
| OBS Studio | Native | 5-10s | Excellent | Medium | Easy |
| Streamlabs Desktop | Native | 6-12s | Good | Medium | Easy |
| vMix | Native | 5-8s | Excellent | Low | Medium |
| Wirecast | Native | 5-9s | Excellent | Low | Medium |
| XSplit | Native | 6-10s | Good | Medium | Easy |
| FFmpeg | Native | 4-8s | Excellent | Variable | Advanced |
Real-world RTMP streaming performance metrics
| Scenario | Video Bitrate | Actual Network Usage | Overhead |
|---|---|---|---|
| 720p30 Stream | 2,500 Kbps | 2,820 Kbps | 12.8% |
| 1080p60 Stream | 6,000 Kbps | 6,720 Kbps | 12.0% |
| 4K30 Stream | 13,000 Kbps | 14,560 Kbps | 12.0% |
Cause: Firewall blocking TCP port 1935, incorrect server URL, or invalid stream key
Solution: Verify server URL format (rtmp://domain/app/), check stream key, open TCP port 1935 in firewall, try RTMPS (port 443) if standard RTMP is blocked.
Cause: Platform buffer settings, network congestion, or encoder buffering
Solution: RTMP latency is platform-controlled. Use lower-latency protocols (SRT, WebRTC, OMT) if <5s latency required. Reduce encoder buffer size. Enable low-latency mode on platform if available.
Cause: Insufficient CPU (encoding dropped frames) or network bandwidth (network dropped frames)
Solution: Encoding dropped: Switch to hardware encoder (NVENC/QuickSync), lower output resolution, or use faster x264 preset. Network dropped: Reduce video bitrate, check for bandwidth congestion, use wired connection instead of WiFi.
Cause: Variable bitrate (VBR), keyframe interval issues, or network instability
Solution: Use CBR (Constant Bitrate) rate control. Set keyframe interval to exactly 2 seconds. Increase bitrate slightly for headroom. Check for ISP throttling or upload speed limitations.
Cause: Platform requires 2-second keyframe interval, but OBS is configured differently
Solution: Set keyframe interval to exactly 2 in OBS Settings → Output → Streaming. This is required by YouTube, Facebook, Twitch. Never use "auto" or 0.
Cause: Incorrect sample rate (44.1 kHz instead of 48 kHz), audio buffer issues
Solution: Set audio sample rate to 48 kHz in Settings → Audio. Restart OBS after changing. Add audio delay offset if needed (Settings → Advanced → Audio → Sync Offset). Check for variable framerate sources (use CBR video sources).
Comparison with SRT, WebRTC, and OMT
| Feature | RTMP | SRT | WebRTC | OMT |
|---|---|---|---|---|
| Latency | 5-15s | 2-4s | <500ms | <16ms |
| Transport | TCP | UDP | UDP | UDP |
| Packet Loss Recovery | Automatic (TCP) | Up to 15% | Limited | Minimal |
| Encryption | RTMPS (optional) | AES-128/256 | DTLS/SRTP | TLS 1.3 |
| Encoder Support | Universal | Excellent | Growing | Limited |
| Best Use Case | Platform streaming | Unreliable networks | Interactive streaming | Ultra-low latency |
| Firewall Friendliness | Excellent | Good | Excellent | Good |
Production-ready code for RTMP streaming
import { WaveClient } from '@wave/api-client';
import { DesignTokens, getContainer, getSection } from '@/lib/design-tokens';
const wave = new WaveClient({ apiKey: 'wave_live_xxxxx' });
// Create RTMP stream with custom configuration
const stream = await wave.streams.create({
title: 'Professional RTMP Broadcast',
protocol: 'rtmp',
rtmp: {
// Encoder will connect to this URL
chunkSize: 4096, // Larger chunks for better performance
// Platform-specific settings
platform: 'custom', // 'youtube' | 'facebook' | 'twitch' | 'custom'
// Recording options
recording: {
enabled: true,
format: 'mp4',
quality: 'source' // Record at source quality
},
// Transcoding options (server-side ABR)
transcoding: {
enabled: true,
profiles: [
{ resolution: '1080p', bitrate: 6000, fps: 60 },
{ resolution: '720p', bitrate: 4500, fps: 60 },
{ resolution: '720p', bitrate: 2500, fps: 30 },
{ resolution: '480p', bitrate: 1000, fps: 30 }
]
}
}
});
console.log('RTMP URL:', stream.ingest.rtmp.url);
console.log('Stream Key:', stream.ingest.rtmp.streamKey);
console.log('Full URL for OBS:', `${stream.ingest.rtmp.url}${stream.ingest.rtmp.streamKey}`);
// Monitor stream health
const health = await wave.streams.getHealth(stream.id);
console.log('Stream Status:', health.status); // 'live' | 'idle' | 'error'
console.log('Current Bitrate:', health.rtmp.bitrate); // Kbps
console.log('Dropped Frames:', health.rtmp.droppedFrames);
console.log('FPS:', health.rtmp.fps);
console.log('Resolution:', health.rtmp.resolution);
console.log('Codec:', health.rtmp.codec); // 'h264' | 'hevc'
// Get stream analytics
const analytics = await wave.streams.getAnalytics(stream.id, {
period: '1h',
metrics: ['bitrate', 'fps', 'viewers', 'dropped_frames']
});
console.log('Average Bitrate:', analytics.bitrate.avg);
console.log('Peak Viewers:', analytics.viewers.max);
console.log('Total Dropped Frames:', analytics.dropped_frames.total);
// Multi-platform simulcast
const simulcast = await wave.streams.createSimulcast({
sourceStream: stream.id,
destinations: [
{
platform: 'youtube',
rtmpUrl: 'rtmp://a.rtmp.youtube.com/live2',
streamKey: 'your-youtube-key'
},
{
platform: 'facebook',
rtmpUrl: 'rtmps://live-api-s.facebook.com:443/rtmp/',
streamKey: 'your-facebook-key'
},
{
platform: 'twitch',
rtmpUrl: 'rtmp://live.twitch.tv/app/',
streamKey: 'your-twitch-key'
}
]
});
console.log('Simulcast Active:', simulcast.destinations.map(d => d.platform));
// Handle stream events via webhook
wave.webhooks.on('stream.started', (event) => {
console.log('Stream started:', event.stream.id);
console.log('Encoder:', event.stream.rtmp.encoder);
console.log('Resolution:', event.stream.rtmp.resolution);
});
wave.webhooks.on('stream.health.warning', (event) => {
console.warn('Stream health warning:', event.message);
console.warn('Dropped frames:', event.rtmp.droppedFrames);
// Send alert to streamer
});
wave.webhooks.on('stream.ended', (event) => {
console.log('Stream ended:', event.stream.id);
console.log('Duration:', event.duration);
console.log('Recording URL:', event.recording.url);
});Backup streams, failover, and professional workflows