BLOG POSTS
    MangoHost Blog / How to Set Up a Video Streaming Server Using Nginx RTMP on Ubuntu 24
How to Set Up a Video Streaming Server Using Nginx RTMP on Ubuntu 24

How to Set Up a Video Streaming Server Using Nginx RTMP on Ubuntu 24

Setting up a video streaming server with Nginx RTMP on Ubuntu 24 opens up powerful possibilities for live streaming, video-on-demand services, and custom streaming solutions. Whether you’re building a gaming stream platform, educational content delivery system, or corporate video distribution network, understanding how to configure and optimize an RTMP server gives you complete control over your streaming infrastructure. This guide will walk you through the entire process from installation to production deployment, covering performance optimization, security considerations, and troubleshooting common issues that trip up even experienced system administrators.

How Nginx RTMP Works

Nginx RTMP is a module that extends the standard Nginx web server to handle Real-Time Messaging Protocol streams. Unlike basic HTTP streaming, RTMP provides low-latency bidirectional communication between clients and servers, making it ideal for interactive streaming applications.

The module works by creating RTMP applications that can accept incoming streams from encoders like OBS Studio or FFmpeg, then redistribute those streams to viewers in various formats including HLS, DASH, or direct RTMP playback. The server acts as a central hub, handling stream authentication, recording, transcoding, and distribution all within a single process.

Here’s the basic flow:

  • Encoder connects to RTMP endpoint and pushes stream
  • Nginx RTMP module receives and processes the stream
  • Server can simultaneously record, transcode, and redistribute
  • Viewers connect via web players, mobile apps, or RTMP clients
  • Optional CDN integration for global distribution

Prerequisites and System Requirements

Before diving into the installation, let’s cover what you’ll need for a solid streaming server setup:

Component Minimum Requirement Recommended Notes
CPU 2 cores, 2.5GHz 4+ cores, 3.0GHz+ Transcoding is CPU-intensive
RAM 2GB 8GB+ More RAM helps with concurrent streams
Storage 20GB SSD 100GB+ NVMe Fast I/O crucial for recording
Network 100Mbps 1Gbps+ Upload bandwidth = bitrate × viewers

You’ll also need root access to your Ubuntu 24 system and a basic understanding of Linux command line operations.

Step-by-Step Installation Guide

Ubuntu 24’s default repositories don’t include the RTMP module, so we’ll need to compile Nginx from source or use a pre-compiled version with RTMP support.

Method 1: Installing via PPA (Recommended for beginners)

First, update your system and install the necessary repository:

sudo apt update && sudo apt upgrade -y
sudo apt install software-properties-common -y
sudo add-apt-repository ppa:nginx/stable
sudo apt update

Install Nginx with RTMP module:

sudo apt install nginx-full nginx-module-rtmp -y

Load the RTMP module by editing the main Nginx configuration:

sudo nano /etc/nginx/nginx.conf

Add this line at the very beginning of the file, before any other directives:

load_module modules/ngx_rtmp_module.so;

Method 2: Compiling from Source (For advanced users)

If you need the latest features or want more control, compile from source:

sudo apt install build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev -y
wget http://nginx.org/download/nginx-1.24.0.tar.gz
wget https://github.com/arut/nginx-rtmp-module/archive/master.zip
tar -zxvf nginx-1.24.0.tar.gz
unzip master.zip

cd nginx-1.24.0
./configure --with-http_ssl_module --add-module=../nginx-rtmp-module-master
make -j$(nproc)
sudo make install

Basic RTMP Configuration

Now comes the fun part – configuring your streaming server. Create a dedicated RTMP configuration file:

sudo nano /etc/nginx/nginx.conf

Add this RTMP block at the end of the main configuration file, outside the http block:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        allow publish all;
        
        application live {
            live on;
            record off;
            
            # Enable HLS
            hls on;
            hls_path /var/www/hls;
            hls_fragment 3;
            hls_playlist_length 60;
            
            # Enable DASH
            dash on;
            dash_path /var/www/dash;
            
            # Push to multiple destinations
            # push rtmp://backup-server/live;
        }
        
        application playback {
            live on;
            play /var/recordings;
        }
    }
}

Create the necessary directories:

sudo mkdir -p /var/www/hls
sudo mkdir -p /var/www/dash
sudo mkdir -p /var/recordings
sudo chown -R www-data:www-data /var/www/hls /var/www/dash /var/recordings
sudo chmod -R 755 /var/www/hls /var/www/dash /var/recordings

Configure the HTTP server to serve HLS and DASH streams:

server {
    listen 80;
    server_name your-domain.com;
    
    # Serve HLS fragments
    location /hls {
        types {
            application/vnd.apple.mpegurl m3u8;
            video/mp2t ts;
        }
        root /var/www;
        add_header Cache-Control no-cache;
        add_header Access-Control-Allow-Origin *;
    }
    
    # Serve DASH fragments  
    location /dash {
        root /var/www;
        add_header Cache-Control no-cache;
        add_header Access-Control-Allow-Origin *;
    }
    
    # RTMP statistics
    location /stat {
        rtmp_stat all;
        rtmp_stat_stylesheet stat.xsl;
    }
    
    location /stat.xsl {
        root /var/www/html;
    }
}

Test your configuration and restart Nginx:

sudo nginx -t
sudo systemctl restart nginx
sudo systemctl enable nginx

Advanced Configuration Options

Here’s a production-ready configuration with authentication, recording, and multiple quality streams:

rtmp {
    server {
        listen 1935;
        chunk_size 4096;
        
        application live {
            live on;
            
            # Authentication
            on_publish http://localhost/auth;
            on_publish_done http://localhost/auth_done;
            
            # Recording
            record all;
            record_path /var/recordings;
            record_unique on;
            record_suffix .flv;
            
            # Multiple quality streams
            exec ffmpeg -i rtmp://localhost/live/$name 
                -c:v libx264 -c:a aac -b:v 1000k -b:a 128k -vf "scale=1280:720" -f flv rtmp://localhost/hls/$name_720p
                -c:v libx264 -c:a aac -b:v 500k -b:a 96k -vf "scale=854:480" -f flv rtmp://localhost/hls/$name_480p;
            
            # HLS settings
            hls on;
            hls_path /var/www/hls;
            hls_fragment 2;
            hls_playlist_length 10;
            hls_continuous on;
            hls_cleanup on;
            hls_nested on;
            
            hls_variant _720p BANDWIDTH=1152000,RESOLUTION=1280x720;
            hls_variant _480p BANDWIDTH=596000,RESOLUTION=854x480;
        }
        
        application hls {
            live on;
            allow publish 127.0.0.1;
            deny publish all;
            
            hls on;
            hls_path /var/www/hls;
            hls_fragment 2;
            hls_playlist_length 10;
        }
    }
}

Real-World Use Cases and Examples

Let’s look at some practical applications and how to configure them:

Gaming Stream Platform

For a Twitch-like platform, you’ll want low latency and chat integration:

application gaming {
    live on;
    
    # Ultra-low latency settings
    hls_fragment 1;
    hls_playlist_length 3;
    
    # Notify your application of stream events
    on_publish http://your-app.com/api/stream/start;
    on_unpublish http://your-app.com/api/stream/end;
    on_play http://your-app.com/api/viewer/join;
    on_play_done http://your-app.com/api/viewer/leave;
    
    # Push to backup servers
    push rtmp://backup1.yoursite.com/gaming;
    push rtmp://backup2.yoursite.com/gaming;
}

Educational Content Delivery

For educational platforms, focus on reliability and recording:

application education {
    live on;
    
    # Always record lectures
    record all;
    record_path /var/recordings/lectures;
    record_append on;
    
    # Generate thumbnails every 30 seconds
    exec_record_done ffmpeg -i $path -vf fps=1/30 /var/www/thumbnails/$basename_%03d.jpg;
    
    # Higher quality HLS for better viewing experience
    hls_fragment 6;
    hls_playlist_length 30;
}

Corporate Live Events

Enterprise streaming often requires authentication and geographic distribution:

application corporate {
    live on;
    
    # JWT-based authentication
    on_publish http://auth.company.com/validate_publisher;
    on_play http://auth.company.com/validate_viewer;
    
    # Push to CDN endpoints
    push rtmp://us-east.cdn.company.com/live;
    push rtmp://eu-west.cdn.company.com/live;
    push rtmp://asia-pacific.cdn.company.com/live;
    
    # Enable secure HLS
    hls_keys on;
    hls_key_path /etc/nginx/hls_keys;
    hls_fragments_per_key 5;
}

Performance Optimization and Monitoring

Monitor your streaming server performance with these key metrics:

Metric Good Warning Critical Command to Check
CPU Usage <70% 70-85% >85% htop or top
Memory Usage <80% 80-90% >90% free -h
Disk I/O Wait <5% 5-15% >15% iostat -x 1
Network Throughput Varies 80% of capacity >90% of capacity iftop or nethogs

Add these optimizations to your Nginx configuration:

# In the main context
worker_processes auto;
worker_rlimit_nofile 65535;

events {
    worker_connections 4096;
    use epoll;
    multi_accept on;
}

# In http context
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 30;
keepalive_requests 100;

# Buffer sizes
client_body_buffer_size 128k;
client_max_body_size 10m;
client_header_buffer_size 1k;
large_client_header_buffers 4 4k;
output_buffers 1 32k;
postpone_output 1460;

Security Best Practices

Securing your streaming server is crucial, especially for public-facing deployments:

# Restrict publishing to authenticated users
application secure_live {
    live on;
    
    # Only allow publishing from your application servers
    allow publish 192.168.1.0/24;
    allow publish 10.0.0.0/8;
    deny publish all;
    
    # Rate limiting
    max_connections 1000;
    
    # Webhook-based authentication
    on_publish http://127.0.0.1:8080/rtmp/auth;
    
    # Prevent unauthorized playback
    on_play http://127.0.0.1:8080/rtmp/play_auth;
}

Implement SSL/TLS for your web interface:

server {
    listen 443 ssl http2;
    ssl_certificate /etc/letsencrypt/live/your-domain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/your-domain.com/privkey.pem;
    
    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;
    ssl_session_cache shared:SSL:10m;
}

Set up a firewall to restrict access:

sudo ufw allow 22/tcp
sudo ufw allow 80/tcp  
sudo ufw allow 443/tcp
sudo ufw allow 1935/tcp
sudo ufw enable

Troubleshooting Common Issues

Here are the most frequent problems you’ll encounter and their solutions:

Streams Won’t Start or Connect

Check if Nginx is running and listening on the correct ports:

sudo systemctl status nginx
sudo netstat -tlnp | grep :1935
sudo tail -f /var/log/nginx/error.log

Common fixes:

  • Verify RTMP module is loaded: nginx -V 2>&1 | grep -o with-rtmp
  • Check firewall settings: sudo ufw status
  • Ensure directories exist and have proper permissions
  • Validate Nginx configuration: sudo nginx -t

High CPU Usage During Transcoding

If FFmpeg processes are consuming too much CPU:

# Limit FFmpeg CPU usage in your RTMP application
exec ffmpeg -i rtmp://localhost/live/$name 
    -threads 2 -preset ultrafast -tune zerolatency
    -c:v libx264 -c:a aac -f flv rtmp://localhost/hls/$name;

HLS Playback Issues

When viewers can’t play HLS streams:

  • Check CORS headers are properly set
  • Ensure playlist files (.m3u8) are being generated
  • Verify web server can serve the HLS directory
  • Test with VLC or another HLS-compatible player first
# Debug HLS generation
ls -la /var/www/hls/
curl -I http://your-domain.com/hls/stream.m3u8

Comparison with Alternative Solutions

Solution Pros Cons Best For
Nginx RTMP Free, lightweight, highly configurable Manual setup, limited GUI Custom solutions, high control needed
Wowza Streaming Engine Enterprise features, GUI, support Expensive licensing Enterprise deployments
Simple Relay Server (SRS) Modern, WebRTC support, easier setup Newer, smaller community Modern streaming requirements
FFmpeg + Apache/Nginx Maximum flexibility Complex setup, manual scripting Specialized use cases

Integration with Popular Streaming Tools

Your RTMP server works seamlessly with various broadcasting software:

OBS Studio Configuration

  • Server: rtmp://your-server.com/live
  • Stream Key: your_stream_name
  • Recommended bitrate: 2500 kbps for 1080p30

FFmpeg Command Line

# Stream a video file
ffmpeg -re -i input.mp4 -c copy -f flv rtmp://your-server.com/live/stream_name

# Stream webcam (Linux)
ffmpeg -f v4l2 -i /dev/video0 -c:v libx264 -preset ultrafast -f flv rtmp://your-server.com/live/webcam

# Re-stream from another RTMP source
ffmpeg -i rtmp://source-server.com/live/input -c copy -f flv rtmp://your-server.com/live/restream

Mobile App Integration

For mobile applications, consider these libraries:

Scaling and Load Balancing

As your streaming platform grows, you’ll need to distribute load across multiple servers:

# Load balancer configuration
upstream rtmp_backend {
    least_conn;
    server stream1.yourdomain.com:1935 weight=3;
    server stream2.yourdomain.com:1935 weight=3;
    server stream3.yourdomain.com:1935 weight=2;
}

server {
    listen 1935;
    proxy_pass rtmp_backend;
    proxy_timeout 1s;
    proxy_responses 1;
}

For geographic distribution, implement edge servers that pull from your origin:

application edge {
    live on;
    
    # Pull from origin server
    pull rtmp://origin.yourdomain.com/live/;
    
    # Local HLS generation
    hls on;
    hls_path /var/www/hls;
    hls_fragment 2;
}

Setting up an Nginx RTMP server on Ubuntu 24 provides a solid foundation for any streaming project. The flexibility and performance make it an excellent choice for everything from small personal streams to large-scale broadcasting platforms. Remember to monitor your server performance, implement proper security measures, and test thoroughly before going live with any production streams. The official Nginx RTMP module documentation contains additional configuration options and advanced features worth exploring as your streaming requirements evolve.



This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.

This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.

Leave a reply

Your email address will not be published. Required fields are marked