Monday, April 3, 2017

Create Adaptive Streaming with NGINX RTMP



In my previous articles How to build NGINX RTMP module, Setup Live Streaming with NGINX RTMP module and Publishing Stream with Open Broadcaster Software (OBS), I have examined how to stream a video file with FFmpeg encoder without any conversion. The streaming output is the same as the input sources.


For converting live streams into several streams resolution for adaptive streaming purpose, we need to make sure server have enough CPU for the workload. This is to prevent live streaming from continuous delays and even worst, server become unresponsive and hang. To prevent this case happen then we need to think about the resolution that will be offering for adaptive streaming. Normally, there are 4 variants that we can use for adaptive streaming consist of

1. 240p Low Definition stream at 288kbps
2. 480p Standard Definition stream at 448kbps
3. 540p Standard Definition stream at 1152kbps
4. 720p High Definition stream at 2048kbps



Configure nginx.conf for Adaptive Live Streaming

Here is my own configuration (simple configuration). In this configuration, I used resolution 240p, 480p, 720p.

#user  nobody;
worker_processes  1;

error_log  logs/error.log debug;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       8080;
        server_name  localhost;
        
        # rtmp stat
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }

        location /stat.xsl {
            # you can move stat.xsl to a different location
            # in my case, i used /home/addies/build/nginx-rtmp-module
            root /home/addies/build/nginx-rtmp-module;
        }

        location /hls {
                add_header 'Cache-Control' 'no-cache';
                add_header 'Access-Control-Allow-Origin' '*' always;
                add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
                add_header 'Access-Control-Allow-Headers' 'Range';

                if ($request_method = 'OPTIONS') {
                       add_header 'Access-Control-Allow-Origin' '*';
                       add_header 'Access-Control-Allow-Headers' 'Range';
                       add_header 'Access-Control-Max-Age' 1728000;
                       add_header 'Content-Type' 'text/plain charset=UTF-8';
                       add_header 'Content-Length' 0;
                       return 204;
                }

                #serve HLS fragments
                types {
                       application/dash+xml mpd;
                       application/vnd.apple.mpegurl m3u8;
                       video/mp2t ts;
                }

                root /home/addies/live/;
                add_header Cache-Control no-cache;            
        }

        # rtmp control
        location /control {
            rtmp_control all;
        }

        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

rtmp {
    server {
        listen 1935;
        ping 30s;
        notify_method get;

        application live {
            live on;     

            exec_pull ffmpeg -re -i http://your_ip_source/$app/$name
 -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/show/${name}_720
-vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1024k -b:a 128k -vf "scale=854:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/show/${name}_480
 -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 300k -b:a 96k -vf "scale=426:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/show/${name}_240;
        }


       application show {

            live on;

            hls on;
            hls_path /home/addies/live/hls;
            hls_nested on;
            record off;
            
            # Instruct clients to adjust resolution according to bandwidth

            hls_variant _720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
            hls_variant _480 BANDWIDTH=448000; # Medium bitrate, SD resolution
            hls_variant _240 BANDWIDTH=288000; # Low bitrate, sub-SD resolution

        }

    }
}

After finished the configuration then you need to create folder for hls files that created by nginx
cd ~
mkdir live
cd ~/live
mkdir hls
cd ~
chmod -R 755 /home/addies/live

To test your configuration then you need to open linux terminal and type command

ffmpeg -re -i /home/addies/stream/any_files_for_testing.mp4 -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/live/any_name  -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1024k -b:a 128k -vf "scale=854:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/live/any_name  -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 300k -b:a 96k -vf "scale=426:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/live/any_name 



Next, you can play from vlc player by inputing the stream url:
http://your_server/hls/any_name.m3u8


12 comments:

  1. Hello, Can you please add me on skype: sritaanya

    ReplyDelete
  2. I have added. What can I do for you?

    ReplyDelete
  3. same as you write on your blog
    I done that
    same config file I paste
    I know you are very busy person
    but .... I am just worried about my setup
    after that I installed ffmpeg on same server
    and running this command
    ffmpeg -re -i http://www.mag.lttelevision.com:25461/sriknath2@gmail.com/jAa96JarmQ/62393 -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://35.246.123.245/live/bug -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1024k -b:a 128k -vf "scale=854:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://35.246.123.245/live/bug -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 300k -b:a 96k -vf "scale=426:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://35.246.123.245/live/bug
    as you wrote on your blog
    [rtmp @ 0x3ec1dc0] Cannot open connection tcp://35.246.123.245:1935
    rtmp://35.246.123.245/live/bug: Connection timed out
    this error I am getting

    ReplyDelete
    Replies
    1. Have you open/allow port 1935 in your network?

      Delete
  4. #user nobody;
    worker_processes 1;

    error_log logs/error.log debug;

    events {
    worker_connections 1024;
    }

    http {
    include mime.types;
    default_type application/octet-stream;

    sendfile on;
    keepalive_timeout 65;

    server {
    listen 8080;
    server_name localhost;

    # rtmp stat
    location /stat {
    rtmp_stat all;
    rtmp_stat_stylesheet stat.xsl;
    }

    location /stat.xsl {
    # you can move stat.xsl to a different location
    # in my case, i used /home/addies/build/nginx-rtmp-module
    root /home/addies/build/nginx-rtmp-module;
    }

    location /hls {
    add_header 'Cache-Control' 'no-cache';
    add_header 'Access-Control-Allow-Origin' '*' always;
    add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    add_header 'Access-Control-Allow-Headers' 'Range';

    if ($request_method = 'OPTIONS') {
    add_header 'Access-Control-Allow-Origin' '*';
    add_header 'Access-Control-Allow-Headers' 'Range';
    add_header 'Access-Control-Max-Age' 1728000;
    add_header 'Content-Type' 'text/plain charset=UTF-8';
    add_header 'Content-Length' 0;
    return 204;
    }

    #serve HLS fragments
    types {
    application/dash+xml mpd;
    application/vnd.apple.mpegurl m3u8;
    video/mp2t ts;
    }

    root /home/addies/live/;
    add_header Cache-Control no-cache;
    }

    # rtmp control
    location /control {
    rtmp_control all;
    }

    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }
    }
    }

    rtmp {
    server {
    listen 1935;
    ping 30s;
    notify_method get;

    application live {
    live on;

    exec_pull ffmpeg -re -i http://35.246.123.245/$app/$name
    -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1920k -b:a 128k -vf "scale=1280:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/show/${name}_720
    -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 1024k -b:a 128k -vf "scale=854:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/show/${name}_480
    -vcodec libx264 -threads 0 -vprofile baseline -acodec aac -strict -2 -b:v 300k -b:a 96k -vf "scale=426:trunc(ow/a/2)*2" -tune zerolatency -preset veryfast -crf 23 -f flv rtmp://localhost:1935/show/${name}_240;
    }


    application show {

    live on;

    hls on;
    hls_path /home/addies/live/hls;
    hls_nested on;
    record off;

    # Instruct clients to adjust resolution according to bandwidth

    hls_variant _720 BANDWIDTH=2048000; # High bitrate, HD 720p resolution
    hls_variant _480 BANDWIDTH=448000; # Medium bitrate, SD resolution
    hls_variant _240 BANDWIDTH=288000; # Low bitrate, sub-SD resolution

    }

    }
    }

    ReplyDelete
  5. this is config file. I hope here 1935 is allowed

    ReplyDelete
  6. Still its not working
    same error is displaying

    ReplyDelete
  7. I used your configuration procedure
    But i cannot play hls live stream on vlc

    I am using http://your_server/hls/test.m3u8 to play in vlc
    My live url rtmp://your_server/live/test will work in vlc
    but hls is not working

    ReplyDelete
  8. Hello addie, Please reply me on skype. I am ready to pay you for this learning

    ReplyDelete
  9. Hello Addie,
    Please talk to me on skype

    ReplyDelete


  10. Hls Streaming Server


    Get to us to find high- quality hls streaming server services and great deals. We are one of the largest service providers that help you with the best hls streaming server services. Visit us to see what we have to offer.


    https://cdn.net/how-cdns-facilitate-faster-http-live-streaming/

    ReplyDelete