Skip to content

Step-by-Step Guide to Building an Nginx-RTMP Streaming Media Server (Ubuntu/Windows)

Author Introduction

👋 Hi, I'm the webmaster of EZ Media Tools, focused on multimedia online video technology and browser-based tool development.

EZ Media Tools is a tool platform centered on online video processing, providing features including M3U8 online playback, M3U8 to MP4, RTMP/HLS stream testing, FFmpeg online transcoding, and more—all usable directly in the browser without installing a client.

Introduction

With the explosion of the live streaming industry, Bilibili, Douyin, and WeChat Video have become part of our lives. But have you ever wondered about the technical principles behind these glamorous live streams? If we want to build our own private server, or set up a monitoring streaming server within an intranet, how should we do it? This article will teach you, starting from scratch with super detailed instructions, how to compile, configure, and run an Nginx-RTMP streaming media server on Ubuntu and Windows, the two mainstream platforms. You'll not only "know what it is," but also "know why it is."

Why Choose Nginx-RTMP?

In the streaming media field, there are many protocols, such as RTMP, HLS, FLV, WebRTC, etc., and servers like SRS, ZLMediaKit, Nginx-RTMP, etc. Why specifically choose Nginx-RTMP? I've summarized the following advantages:

  • High Performance: As is well known, Nginx's high concurrency capability is world-renowned.
  • Extremely Lightweight: Very low resource usage; a 1-core 1GB cloud server can handle hundreds of streams.
  • Simple Configuration: One nginx.conf rules them all.
  • Powerful Features: Supports RTMP streaming, while also supporting HTTP-FLV and HLS playback, perfectly compatible with PC and mobile.

Article Goal: Build a server that achieves the complete loop: OBS push -> Server -> VLC/Browser playback.

Prerequisites

To do good work, one must first sharpen one's tools. Please prepare the following environment:

  • A server/computer: Cloud server (recommended Ubuntu 20.04/22.04) or local Windows computer.
  • Streaming tool: OBS Studio (open source and free, the Swiss army knife of streaming).
  • Playback tool: VLC Media Player (universal player).
  • Code editor: VS Code, Notepad++, or Vim.

Ubuntu Platform Setup

For demonstration purposes, I'm using Ubuntu here. We won't use apt install here because the Nginx in the official repositories doesn't come with the RTMP module, so we need to compile from source. Sound scary? It's actually just a matter of copying and pasting a few commands. 😎

Install Compilation Dependencies

Open a terminal and execute the following commands in order:

bash
# Update software sources
sudo apt-get update

# Install compilation tools and dependency libraries
sudo apt-get install build-essential libpcre3 libpcre3-dev libssl-dev zlib1g-dev unzip wget

Download Nginx and RTMP Module

We need two compressed packages: Nginx source package, Nginx-RTMP-Module module package.

bash
# Create a working directory
mkdir ~/nginx-build && cd ~/nginx-build

# Download Nginx (recommend 1.20.x version, stable)
wget http://nginx.org/download/nginx-1.20.2.tar.gz

# Download RTMP module (original by arut)
wget https://github.com/arut/nginx-rtmp-module/archive/master.zip

Extract and Configure

bash
# Extract
tar -zxvf nginx-1.20.2.tar.gz
unzip master.zip

# Enter Nginx directory
cd nginx-1.20.2

The most critical step comes: configure compilation parameters. We need to tell Nginx: in addition to its built-in functionality, also package the nginx-rtmp-module next door.

bash
./configure \
--prefix=/usr/local/nginx \
--add-module=../nginx-rtmp-module-master \
--with-http_ssl_module \
--with-http_v2_module

Parameter Explanation:

  • --prefix: Specify installation directory for easier management.
  • --add-module: Specify RTMP module source path—note it's the master folder in the parent directory.
  • --with-http_ssl_module: Enable SSL support—note: HLS must use HTTPS.

If there's no error, "configured successfully" will be displayed at the end.

Compile and Install

bash
# Compile (make), -j4 means using 4 cores to compile, fast. Adjust core count based on machine configuration
make -j4

sudo make install

After installation is complete, your Nginx will be in the /usr/local/nginx directory.

Compiling and Installing Nginx-RTMP

Ubuntu System Service Configuration

Create a systemd service file:

bash
sudo vim /etc/systemd/system/nginx-rtmp.service

Add the following content:

ini
[Unit]
Description=nginx-rtmp server
After=network.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx
ExecReload=/usr/local/nginx/sbin/nginx -s reload
ExecStop=/usr/local/nginx/sbin/nginx -s quit
PrivateTmp=true

[Install]
WantedBy=multi-user.target

Enable the service:

bash
sudo systemctl enable nginx-rtmp
sudo systemctl start nginx-rtmp

Windows Platform Setup

The Windows compilation environment is too troublesome, but fortunately there are precompiled binary packages made by experts.

Download and Extract

  1. Visit the GitHub repository: illuspas/nginx-rtmp-win32.
  2. Download the latest nginx-rtmp-win32-1.2.1.zip.
  3. Extract to a non-Chinese path, for example D:\nginx-rtmp.

Windows Nginx RTMP

See nginx.exe? That's our protagonist.


Core Configuration: nginx.conf Explained

Whether Ubuntu or Windows, the soul is in the conf/nginx.conf file. Open it with an editor, find the http { ... } section, and at the same level outside it, add the following rtmp configuration:

nginx
rtmp {
    server {
        listen 1935; # RTMP default port
        chunk_size 4096;

        application live {
            live on;             # Enable live mode
            record off;          # Disable recording (save disk space)
            allow publish 127.0.0.1; # Allow streaming client IP—for production, recommend changing to intranet IP or password verification

            # Enable HLS slicing
            hls on;
            hls_path /tmp/hls;   # Ubuntu path
            # hls_path D:/nginx-rtmp/temp/hls; # Windows path—note forward slashes
            hls_fragment 3s;     # Each slice is 3 seconds
            hls_playlist_length 10s; # Playlist length is 10 seconds
        }
    }
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80; # HTTP default port, for HLS playback
        server_name  localhost;

        # HLS playback configuration
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /tmp; # Ubuntu
            # root D:/nginx-rtmp/temp; # Windows
            add_header Cache-Control no-cache;
        }
    }
}

After saving configuration:

  • Ubuntu: sudo /usr/local/nginx/sbin/nginx to start.
  • Windows: Double-click nginx.exe to start (a black window will flash).

Firewall Note: Must open 1935 (streaming) and 80 (playback) ports!

  • Ubuntu: sudo ufw allow 1935 && sudo ufw allow 80
  • Windows: Firewall Advanced Settings -> Inbound Rules -> New Rule -> Port -> TCP 1935, 80.

Windows Firewall Port Allow Settings


Practical Streaming: OBS Connects to Server

Replace the server below with your actual situation. My IP here is 192.168.1.3.

OBS Settings

  1. Sources: Add "Display Capture" or "Video Capture Device".

  2. Settings -> Stream:

    • Service: Custom
    • Server: rtmp://192.168.1.3/live
    • Stream Key: test—this can be customized, equivalent to a room number
  3. Settings -> Output:

    • Bitrate: 2000 Kbps (2Mbps) is sufficiently clear.
    • Output Mode -> Keyframe Interval: 2 seconds.

OBS Studio Streaming Settings

Click "Start Streaming"

If OBS shows "Streaming" in the bottom right corner and the bitrate isn't 0, congratulations! Data has been sent!


Practical Pull Streaming: Three Ways to Watch Live Stream

You've pushed it, how to watch? There are three mainstream protocols.

ProtocolURL FormatLatencyProsCons
RTMPrtmp://ip/live/test1-3 secondsExtremely low latencyBrowsers don't support, need player
HTTP-FLVhttp://ip/live/test.flv2-5 secondsLow latency, web-playableRequires flv.js support
HLShttp://ip/hls/test.m3u810-30 secondsBest compatibilityHigh latency

Method 1: VLC Playback

  1. Open VLC -> Media -> Open Network Stream.
  2. Enter: rtmp://yourIP/live/test
  3. Press Enter, the picture appears!

VLC Player Successfully Playing

Method 2: Browser Playback HLS (Safari/Edge)

Enter directly in the address bar: http://yourIP/hls/test.m3u8 Safari and Edge natively support HLS, so you can watch directly. Chrome needs a plugin.

Method 3: Web Playback HTTP-FLV

Here I recommend EZ Media Tools' FLV & RTMP Player Online, saving you development trouble. Very suitable for RTMP live stream testing, supporting RTMP and FLV formats, real-time live stream information, screenshots, and more.

If you want to write it yourself, you can refer to Bilibili's open source flv.js. Create an index.html file and paste the following code:

html
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Nginx-RTMP Live Stream</title>
    <script src="https://cdn.bootcss.com/flv.js/1.5.0/flv.min.js"></script>
</head>
<body>
    <h1>My Live Room</h1>
    <video id="videoElement" controls width="800" height="450"></video>
    <script>
        if (flvjs.isSupported()) {
            var videoElement = document.getElementById('videoElement');
            var flvPlayer = flvjs.createPlayer({
                type: 'flv',
                url: 'http://yourIP/live/test.flv' // Note: this is flv
            });
            flvPlayer.attachMediaElement(videoElement);
            flvPlayer.load();
            flvPlayer.play();
        }
    </script>
</body>
</html>

Note: The nginx.conf above doesn't enable flv by default. To enable it, add allow publish 127.0.0.1; in rtmp -> application live, then add in http server:

nginx
location /live {
    flv_live on;
    chunked_transfer_encoding on;
    add_header 'Access-Control-Allow-Origin' '*';
}

FLV/RTMP Online Player


Advanced: Intranet Penetration for External Access

If you built it on your own computer (Windows) and your friend wants to watch, what do you do? You don't have a public IP.

There are three solutions:

  1. Oray/Frp: Simple, but free version has speed limits.
  2. Zerotier/Hamachi: Build a virtual LAN, friend installs a client, accesses with intranet IP.
  3. Ngrok: Foreign tool, stable but costs money.

The simplest method (router port forwarding): If you have a public IP with optical modem dial-up:

  1. Login to router (192.168.1.1).
  2. Find "Virtual Server" or "Port Forwarding".
  3. Add two rules:
    • External port 1935 -> Internal IP (your computer's IP) -> Internal port 1935
    • External port 80 -> Internal IP (your computer's IP) -> Internal port 80
  4. Fill in your public IP for the streaming address.

Common Troubleshooting

PhenomenonCauseSolution
OBS streaming error connection refusedFirewall blocking / Nginx not startedCheck firewall, `ps -ef
OBS streaming successful, VLC black screenIncorrect encoding formatChange OBS video encoding to H.264, audio to AAC
Public network inaccessible, intranet worksNo port forwarding / No public IPDo forwarding on router, or use Frp
HLS playback 404Incorrect Nginx configuration pathCheck if hls_path and location /hls's root correspond

Checking logs is a good habit!

  • Ubuntu: tail -f /usr/local/nginx/logs/error.log
  • Windows: logs/error.log

Summary and Outlook

Congratulations! You've mastered the most core streaming media server building technology.

Let's review what we did:

  1. Completed Ubuntu / Windows Nginx-RTMP module environment setup.
  2. Configured nginx.conf for RTMP streaming.
  3. Established the OBS -> Nginx -> VLC link.

What can you play with next?

  • Recording and Playback: Configure record all; and exec_record_done scripts to implement automatic live recording and upload to VOD system.
  • Multi-bitrate: Configure ffmpeg transcoding to let users choose 720P/1080P based on network speed.
  • Authentication: Prevent others from streaming randomly, configure on_publish interface callback to verify keys.
  • WebRTC: Nginx-RTMP latency is still a bit high. Want interactive video chat? Go study ZLMediaKit or SRS—they natively support WebRTC with latency under 500ms.

References

Last updated: