Loading Now

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

How to Set Up a Video Streaming <a href=server Using Nginx RTMP on Ubuntu 24″ decoding=”async” fetchpriority=”high” />

Establishing a video streaming server with Nginx RTMP on Ubuntu 24 opens up exciting opportunities for live broadcasts, video-on-demand facilities, and tailored streaming solutions. Whether you’re creating a gaming stream service, an educational content delivery platform, or a corporate video sharing network, knowing how to set up and enhance an RTMP server grants you complete management over your streaming architecture. This tutorial will guide you through the entire setup process from installation all the way to production use, discussing performance enhancements, security measures, and fixing typical issues that may arise for even seasoned system admins.

Understanding Nginx RTMP

Nginx RTMP is a module that extends the capabilities of the standard Nginx server to support Real-Time Messaging Protocol streams. Unlike conventional HTTP streaming, RTMP allows for low-latency, two-way communication between clients and Servers, making it excellent for interactive streaming applications.

This module operates by establishing RTMP applications that accept incoming streams from encoders such as OBS Studio or FFmpeg, and subsequently redistributes these streams to viewers in various formats, including HLS, DASH, or straightforward RTMP playback. The server functions as a central hub, managing stream authentication, recording, transcoding, and distribution all within a unified system.

Here’s a simplified workflow:

  • Encoder connects to the RTMP endpoint and uploads the stream
  • Nginx RTMP module receives and processes the stream
  • server can concurrently record, transcode, and distribute
  • Viewers access streams via web players, mobile applications, or RTMP clients
  • Optional CDN setup for international distribution

System Requirements and Prerequisites

Before beginning the installation, let’s outline what you will need for a robust streaming server setup:

Component Minimum Requirement Recommended Notes
CPU 2 cores, 2.5GHz 4+ cores, 3.0GHz+ Transcoding demands significant CPU resources
RAM 2GB 8GB+ More RAM improves handling of concurrent streams
Storage 20GB SSD 100GB+ NVMe High I/O speeds are vital for recording
Network 100Mbps 1Gbps+ Upload bandwidth = bitrate x number of viewers

You will also require root access to your Ubuntu 24 system along with a fundamental understanding of Linux command line operations.

Detailed Installation Steps

Ubuntu 24’s default software repositories do not come with the RTMP module pre-installed, so we must either compile Nginx from the source or utilise a pre-compiled version that includes RTMP support.

Method 1: Installation via PPA (Ideal for newbies)

Start by updating your system and installing 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

Next, install Nginx with the RTMP module:

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

To enable the RTMP module, modify the main Nginx configuration:

sudo nano /etc/nginx/nginx.conf

Insert this line at the start of the file, prior to any other directives:

load_module modules/ngx_rtmp_module.so;

Method 2: Compiling from Source (For advanced users)

If you wish to access the latest features or seek greater control, you can 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 exciting part—configuring your streaming server. Create a dedicated RTMP configuration file:

sudo nano /etc/nginx/nginx.conf

Add the following 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

Set up 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;
        }
    }

Verify your configuration and restart Nginx:

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

Advanced Configuration Features

Here’s a configuration suited for production that includes 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 Applications and Scenarios

Let’s explore some practical use cases and configurations:

Gaming Stream Service

For a Twitch-like setup, low latency and chat integration are vital:

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 Distribution

For education-focused platforms, reliability and recording are key:

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 a better viewing experience
        hls_fragment 6;
        hls_playlist_length 30;
    }

Corporate Live Events

Enterprise streaming often requires authentication and global 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 Monitoring and Optimisation

Keep track of your streaming server‘s performance using these essential 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 optimisations 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 the 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;

Essential Security Measures

Securing your streaming server is essential, particularly for publicly accessible setups:

# Restrict publishing to authenticated users
application secure_live {
    live on;
    
    # Permitting only your application’s Servers to publish
    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;
    
    # Preventing unauthorized playback
    on_play http://127.0.0.1:8080/rtmp/play_auth;
}

Set up 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;
}

Establish a firewall to control 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 Problems

Here are some frequent hurdles you might encounter along with their solutions:

Streams Won’t Initiate or Connect

Verify whether Nginx is operational and listening on the appropriate ports:

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

Common solutions include:

  • Ensure the RTMP module is loaded: nginx -V 2>&1 | grep -o with-rtmp
  • Examine firewall settings: sudo ufw status
  • Confirm directory existence and permissions
  • Validate the Nginx configuration: sudo nginx -t

Excessive CPU Usage During Transcoding

If FFmpeg tasks are using too much CPU:

# Limit FFmpeg CPU usage within 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;

Issues with HLS Playback

If viewers cannot play HLS streams:

  • Ensure CORS headers are correctly configured
  • Check if playlist files (.m3u8) are being created
  • Confirm your web server can serve the HLS directory
  • Test using VLC or another HLS-compatible player first
# Debug HLS creation
ls -la /var/www/hls/
curl -I http://your-domain.com/hls/stream.m3u8

Comparison with Alternative Solutions

Solution Advantages Disadvantages Suitable For
Nginx RTMP Free, lightweight, highly configurable Manual setup, limited GUI Custom solutions, requiring high control
Wowza Streaming Engine Enterprise features, GUI, support High licensing costs Enterprise-level implementations
Simple Relay server (SRS) Modern, supports WebRTC, simpler setup Newer, smaller community Contemporary streaming requirements
FFmpeg + Apache/Nginx Maximum flexibility Complex setup, requires manual scripting Specific use cases

Integration with Popular Streaming Applications

Your RTMP server can work smoothly with several broadcasting tools:

OBS Studio Setup

  • 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 utilizing the following libraries:

Scaling and Load Distribution

As your streaming platform expands, you will need to manage load distribution across several 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, set up edge Servers that pull from your origin server:

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

Installing an Nginx RTMP server on Ubuntu 24 provides a robust base for any streaming venture. Its adaptability and performance make it an exceptional choice for everything from modest personal streams to expansive broadcasting ecosystems. Keep an eye on server performance, implement proper security protocols, and conduct thorough tests before launching any live streams. The official Nginx RTMP module documentation offers additional configuration options and advanced functionalities worth exploring as your streaming needs develop.



This article uses information and content from multiple online sources. We acknowledge and appreciate the contributions of all original authors, publishers, and websites. While every effort has been made to provide appropriate credit, any inadvertent oversight or omission does not constitute a copyright violation. All trademarks, logos, and images mentioned belong to their respective owners. If you think any content used in this article infringes upon your copyright, please reach out to us for immediate review and resolution.

This article aims to serve informational and educational purposes only and does not violate the rights of copyright holders. Any copyrighted content used without proper attribution or in violation of copyright laws was unintentional and will be quickly corrected upon notification.
Please note that the republication, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written consent from the author and website owner. For permissions or additional inquiries, please get in touch.