音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器

前言

前一篇我们知道了如何配置FFmpeg开发环境,接下来,就开始简单的推流吧。说到推流前,我们要知道常用的几个直播推流协议。

直播推流协议

在搭建服务之前先了解下目前主流的几个直播协议:

  1. RTMP:

实时消息传输协议,Real Time Messaging Protocol,是 Adobe Systems 公司为 Flash 播放器和服务器之间音频、视频和数据传输开发的开放协议。协议基于 TCP,是一个协议族,包括 RTMP 基本协议及 RTMPT/RTMPS/RTMPE 等多种变种。RTMP 是一种设计用来进行实时数据通信的网络协议,主要用来在 Flash/AIR 平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。这种方式的实时性比较强,基本能保证延迟在1-2s内,是现在国内直播主要采用的方式之一;不过使用这种协议,就必须安装flash,而H5、IOS、Android并不能原生支持flash,因此这种协议能流行多久,就不得而知了,毕竟移动端才是现在的主流。

  1. HLS:

hls是Apple推出的直播协议,是通过视频流切片成文件片段来直播的。客户端首先会请求一个m3u8文件,里面会有不同码率的流,或者直接是ts文件列表,通过给出的ts文件地址去依次播放。在直播的时候,客户端会不断请求m3u8文件,检查ts列表是否有新的ts切片。这种方式的实时性较差,不过优势是H5、IOS、Android都原生支持。

  1. HTTP-FLV:

HTTP-FLV就是对RTMP协议的封装,相比于RTMP,它是一个开放的协议。因此他具备了RTMP的实时性和RTMP不具备的开发性,而且随着flv.js出现(感谢B站),使得浏览器在不依赖flash的情况下,播放flv视频,从而兼容了移动端,所以现在很多直播平台,尤其是手机直播平台,都会选择它

今天,我们就讲解一下,如何利用RTMP协议实现推流。

推流环境的搭建

今天,我们采用的是nginx-rtmp流媒体服务器实现实时推流,因此我们需要安装Nginx。

Nginx本身是一个非常出色的HTTP服务器,ffmpeg是非常好的音视频解决方案.这两个东西通过一个nginx的模块nginx-rtmp-module,组合在一起即可以搭建一个功能相对比较完善的流媒体服务器.这个流媒体服务器可以支持RTMP和HLS(Live Http Stream)。

nginx配合ffmpeg做流媒体服务器的原理是:

nginx通过rtmp模块提供rtmp服务, ffmpeg推送一个rtmp流到nginx, 然后客户端通过访问nginx来收看实时视频流. HLS也是差不多的原理,只是最终客户端是通过HTTP协议来访问的,但是ffmpeg推送流仍然是rtmp的.

  1. 下载nginx
    nginx的下载地址是:http://nginx-win.ecsds.eu/,进入首页下载对应版本的Nginx。(注意我这里是nginx-win,对应的是window版本)
    音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第1张图片
    我的下载的版本是: http://nginx-win.ecsds.eu/download/nginx 1.7.11.3 Gryphon.zip,下载完毕后,解压缩到指定的位置。为了方便,我把解压在c盘nginx-1.7.11.3文件夹下:
    音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第2张图片

  2. 下载nginx-rtmp-module插件
    这里推流,我们需要用到nginx-rtmp-module插件,这是Nginx给我提供好的一个。
    nginx-rtmp-module插件地址:https://github.com/arut/nginx-rtmp-module/,这是一个非常强大的插件,start已经有8.8k,他主要有以下特性。

  • RTMP / HLS / MPEG-DASH实时流
  • RTMP视频点播FLV / MP4,可从本地文件系统或HTTP播放
  • 流中继支持分布式流:推拉模型
  • 在多个FLV中记录流
  • H264 / AAC支持
  • FFmpeg在线转码
  • HTTP回调(发布/播放/记录/更新等)
  • 在某些事件上运行外部程序(exec)
  • HTTP控制模块,用于记录音频/视频和丢弃客户端
  • 先进的缓冲技术可将内存分配保持在最低水平,以实现更快的流传输和较低的内存占用
  • 事实证明可以与Wirecast,FMS,Wowza,JWPlayer,FlowPlayer,StrobeMediaPlayback,ffmpeg,avconv,rtmpdump,flvstreamer等一起使用
  • XML / XSL中机器和人类可读形式的统计信息
  • 完美支持 Linux / FreeBSD / MacOS / Windows

因此,这是很值得我们学习的推流插件。

下载完nginx-rtmp-module插件后,解压到刚刚解压的nginx-1.7.11.3目录中,如下图所示:
音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第3张图片
好了,下面测试Nginx是否可以使用,打开window终端命令行,进入Nginx的安装目录,输入以下命令启动Nginx:

start nginx   或者 nginx.exe

看到下图,说明Nginx安装成功:
音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第4张图片
然后打开浏览器,访问http://localhost/
音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第5张图片

  1. 配置nginx-1.7.11.3文件下 conf\nginx.conf
    打开conf\nginx.conf文件,原配置文件如下:

#user  nobody;
# multiple workers works !
worker_processes  2;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;


events {
    worker_connections  8192;
    # max value 32768, nginx recycling connections+registry optimization = 
    #   this.value * 20 = max concurrent connections currently tested with one worker
    #   C1000K should be possible depending there is enough ram/cpu power
    # multi_accept on;
}


http {
    #include      /nginx/conf/naxsi_core.rules;
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr:$remote_port - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

#     # loadbalancing PHP
#     upstream myLoadBalancer {
#         server 127.0.0.1:9001 weight=1 fail_timeout=5;
#         server 127.0.0.1:9002 weight=1 fail_timeout=5;
#         server 127.0.0.1:9003 weight=1 fail_timeout=5;
#         server 127.0.0.1:9004 weight=1 fail_timeout=5;
#         server 127.0.0.1:9005 weight=1 fail_timeout=5;
#         server 127.0.0.1:9006 weight=1 fail_timeout=5;
#         server 127.0.0.1:9007 weight=1 fail_timeout=5;
#         server 127.0.0.1:9008 weight=1 fail_timeout=5;
#         server 127.0.0.1:9009 weight=1 fail_timeout=5;
#         server 127.0.0.1:9010 weight=1 fail_timeout=5;
#         least_conn;
#     }

    sendfile        off;
    #tcp_nopush     on;

    server_names_hash_bucket_size 128;

## Start: Timeouts ##
    client_body_timeout   10;
    client_header_timeout 10;
    keepalive_timeout     30;
    send_timeout          10;
    keepalive_requests    10;
## End: Timeouts ##

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        ## Caching Static Files, put before first location
        #location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
        #    expires 14d;
        #    add_header Vary Accept-Encoding;
        #}

# For Naxsi remove the single # line for learn mode, or the ## lines for full WAF mode
        location / {
            #include    /nginx/conf/mysite.rules; # see also http block naxsi include line
            ##SecRulesEnabled;
        	  ##DeniedUrl "/RequestDenied";
	          ##CheckRule "$SQL >= 8" BLOCK;
	          ##CheckRule "$RFI >= 8" BLOCK;
	          ##CheckRule "$TRAVERSAL >= 4" BLOCK;
	          ##CheckRule "$XSS >= 8" BLOCK;
            root   html;
            index  index.html index.htm;
        }

# For Naxsi remove the ## lines for full WAF mode, redirect location block used by naxsi
        ##location /RequestDenied {
        ##    return 412;
        ##}

## Lua examples !
#         location /robots.txt {
#           rewrite_by_lua '
#             if ngx.var.http_host ~= "localhost" then
#               return ngx.exec("/robots_disallow.txt");
#             end
#           ';
#         }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000; # single backend process
        #    fastcgi_pass   myLoadBalancer; # or multiple, see example above
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}


    # HTTPS server
    #
    #server {
    #    listen       443 ssl spdy;
    #    server_name  localhost;

    #    ssl                  on;
    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_prefer_server_ciphers On;
    #    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
    #    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!EXP:!ADH:!LOW:!MEDIUM;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

是不是感觉像天书一样,其实我第一次接触也很抵制,但是后来学习了Nginx,就觉得没有什么,如果你比较陌生,请看我的认识nginx.conf配置文件这一篇博客。

整个conf文件分为 全局块、events块、http块、server块、location块。每个块有每个块的作用域,越外层的块作用域就包含内部块的作用域,如全局块作用域就包含events块、http块、server块和location块。而文件中的“#”代表注析,#后的代码是不会有效果的。修改nginx.conf后是必须重启nginx才会生效。这些要注意。
下面,我们精简一下默认的conf文件如下:

...                 #全局块

event{              #events块
    ...
}

http{               #http块

    server{         #server块
        ...         #server全局块

        location{   #location块
            ...
        }

        location{   #location块
            ...
        }
    }

    server{         #server块
        ...
    }
    ...             #http全局块
}

那好,我们就可以对照conf整体构造修改我们的配置文件,修改的配置文件如下:

#user  nobody;

# multiple workers works !

worker_processes  2;

 

#error_log  logs/error.log;

#error_log  logs/error.log  notice;

#error_log  logs/error.log  info;

 

#pid        logs/nginx.pid;

 
#events块
events {

    worker_connections  8192;

    # max value 32768, nginx recycling connections+registry optimization = 

    #   this.value * 20 = max concurrent connections currently tested with one worker

    #   C1000K should be possible depending there is enough ram/cpu power

    # multi_accept on;

}

#配置rtmp块
rtmp {

    server {

        listen 1935;

        chunk_size 4000;

        application live {

             live on;

 

             # record first 1K of stream

             record all;

             record_path /tmp/av;

             record_max_size 1K;

 

             # append current timestamp to each flv

             record_unique on;

 

             # publish only from localhost

             allow publish 127.0.0.1;

             deny publish all;

 

             #allow play all;

        }

    }

}

 
#配置http块
http {

    #include      /nginx/conf/naxsi_core.rules;

    include       mime.types;

    default_type  application/octet-stream;

 

    #log_format  main  '$remote_addr:$remote_port - $remote_user [$time_local] "$request" '

    #                  '$status $body_bytes_sent "$http_referer" '

    #                  '"$http_user_agent" "$http_x_forwarded_for"';

 

    #access_log  logs/access.log  main;

 

#     # loadbalancing PHP

#     upstream myLoadBalancer {

#         server 127.0.0.1:9001 weight=1 fail_timeout=5;

#         server 127.0.0.1:9002 weight=1 fail_timeout=5;

#         server 127.0.0.1:9003 weight=1 fail_timeout=5;

#         server 127.0.0.1:9004 weight=1 fail_timeout=5;

#         server 127.0.0.1:9005 weight=1 fail_timeout=5;

#         server 127.0.0.1:9006 weight=1 fail_timeout=5;

#         server 127.0.0.1:9007 weight=1 fail_timeout=5;

#         server 127.0.0.1:9008 weight=1 fail_timeout=5;

#         server 127.0.0.1:9009 weight=1 fail_timeout=5;

#         server 127.0.0.1:9010 weight=1 fail_timeout=5;

#         least_conn;

#     }

 

    sendfile        off;

    #tcp_nopush     on;

 

    server_names_hash_bucket_size 128;

 

## Start: Timeouts ##

    client_body_timeout   10;

    client_header_timeout 10;

    keepalive_timeout     30;

    send_timeout          10;

    keepalive_requests    10;

## End: Timeouts ##

 

    #gzip  on;

 
 #server块
    server {

        listen       80;

        server_name  localhost;

 

 

        location /stat {

            rtmp_stat all;

            rtmp_stat_stylesheet stat.xsl;

        }

        location /stat.xsl {

            root nginx-rtmp-module/;

        }

        location /control {

            rtmp_control all;

        }

 

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

 

        ## Caching Static Files, put before first location

        #location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {

        #    expires 14d;

        #    add_header Vary Accept-Encoding;

        #}

 

# For Naxsi remove the single # line for learn mode, or the ## lines for full WAF mode

        location / {

            #include    /nginx/conf/mysite.rules; # see also http block naxsi include line

            ##SecRulesEnabled;

         ##DeniedUrl "/RequestDenied";

         ##CheckRule "$SQL >= 8" BLOCK;

         ##CheckRule "$RFI >= 8" BLOCK;

         ##CheckRule "$TRAVERSAL >= 4" BLOCK;

         ##CheckRule "$XSS >= 8" BLOCK;

            root   html;

            index  index.html index.htm;

        }

 

# For Naxsi remove the ## lines for full WAF mode, redirect location block used by naxsi

        ##location /RequestDenied {

        ##    return 412;

        ##}

 

## Lua examples !

#         location /robots.txt {

#           rewrite_by_lua '

#             if ngx.var.http_host ~= "localhost" then

#               return ngx.exec("/robots_disallow.txt");

#             end

#           ';

#         }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html

        #

        error_page   500 502 503 504  /50x.html;

        location = /50x.html {

            root   html;

        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80

        #

        #location ~ \.php$ {

        #    proxy_pass   http://127.0.0.1;

        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000

        #

        #location ~ \.php$ {

        #    root           html;

        #    fastcgi_pass   127.0.0.1:9000; # single backend process

        #    fastcgi_pass   myLoadBalancer; # or multiple, see example above

        #    fastcgi_index  index.php;

        #    fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;

        #    include        fastcgi_params;

        #}

        # deny access to .htaccess files, if Apache's document root

        # concurs with nginx's one

        #

        #location ~ /\.ht {

        #    deny  all;

        #}

    }

    # another virtual host using mix of IP-, name-, and port-based configuration

    #

    #server {

    #    listen       8000;

    #    listen       somename:8080;

    #    server_name  somename  alias  another.alias;

    #    location / {

    #        root   html;

    #        index  index.html index.htm;

    #    }

    #}

    # HTTPS server

    #

    #server {

    #    listen       443 ssl spdy;

    #    server_name  localhost;

    #    ssl                  on;

    #    ssl_certificate      cert.pem;

    #    ssl_certificate_key  cert.key;

    #    ssl_session_timeout  5m;

    #    ssl_prefer_server_ciphers On;

    #    ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

    #    ssl_ciphers ECDH+AESGCM:ECDH+AES256:ECDH+AES128:ECDH+3DES:RSA+AESGCM:RSA+AES:RSA+3DES:!aNULL:!eNULL:!MD5:!DSS:!EXP:!ADH:!LOW:!MEDIUM;

    #    location / {

    #        root   html;

    #        index  index.html index.htm;

    #    }

    #}

}

  1. 打开cmd窗口进入nginx-1.7.11.3目录输入
nginx.exe -c conf\nginx-win.conf

启动服务器:
音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第6张图片

  1. 打开浏览器输入http://localhost出现下图就说明启动成功
    音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第7张图片
  2. nginx常用命令(需要进入到nginx安装目录执行命令)
  • 启动:start nginx或nginx.exe
  • 停止:nginx.exe -s stop或nginx.exe -s quit(注:stop是快速停止nginx,可能并不保存相关信息;quit是完整有序的停止nginx,并保存相关信息)
  • 重新载入Nginx:nginx.exe -s reload
    当配置信息修改,需要重新载入这些配置时使用此命令。
  1. 打开cmd窗口进入到到ffmpeg.exe目录下,输入ffmpeg命令进行推流
ffmpeg.exe -re -i C:\ffmpeg\bin\test.mp4 -f flv rtmp://localhost:1935/live/test

注意:

C:\ffmpeg\bin\test.mp4表示的是要推流的视屏的地址
如果出现下图,说明推流成功:
音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第8张图片

  1. 打开VLC播放器可以从你自己的流媒体服务器上拉流观看
    音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第9张图片

  2. 再打开一个cmd窗口,进入ffmpeg目录,使用ffplay命令进行拉流
    音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第10张图片
    音视频之——FFmpeg教程(二)——Windows10下搭建nginx-rtmp流媒体服务器_第11张图片
    好了,至此rtmp流媒体服务器及ffmpeg搭建完成,推流和拉流也就告一段落。

如果,觉得对你有帮助,不防给我一个小红心吧,您的鼓励是我坚持不懈的动力。

你可能感兴趣的:(图形图像与音视频,Linux,Nginx)