基于Nginx Rtmp流媒体服务器搭建

# 1. 安装

# 1.1. 安装Pcre

# 1.1.1 下载

点击这里 (opens new window)下载Pcre。

# 1.1.2 解压&重命名

将压缩包上传至/opt目录下,并执行以下命令:

tar zvxf pcre-8.38.tar.gz

mv pcre-8.38 pcre

# 1.2. 安装ZLib

# 1.2.1 下载

点击这里 (opens new window)下载ZLib。

# 1.2.2 解压&重命名

将压缩包上传至/opt目录下,并执行以下命令:

tar zvxf zlib-1.2.11.tar.gz

mv zlib-1.2.11 zlib

# 1.3. 安装&配置

# 1.3.1 下载Nginx

点击这里 (opens new window)下载Nginx。

# 1.3.2 解压并重命名

将压缩包上传至/opt目录下,并执行以下命令:

tar zvxf nginx-1.17.6.tar.gz

mv nginx-1.17.6 nginx-rtmp

# 1.3.3 下载RTMP模块

点击这里 (opens new window)下载Nginx RTMP模块,将压缩包上传至/opt目录下。

进入nginx-rtmp目录,并创建子目录module目录。

cd nginx-rtmp

mkdir module

将/opt目录下的nginx-http-flv-module移动到/opt/nginx-rtmp/module目录下并重名名。

mv nginx-http-flv-module-1.2.8 nginx-http-flv-module

# 1.3.4 编译安装

进入/opt/nginx-rtmp目录,执行以下命令:

./configure --prefix=/opt/nginx-rtmp --sbin-path=/opt/nginx-rtmp/nginx --conf-path=/opt/nginx-rtmp/nginx-rtmp.conf --pid-path=/opt/nginx-rtmp/nginx-rtmp.pid --with-http_ssl_module --with-pcre=../pcre --with-zlib=../zlib --add-module=/opt/nginx-rtmp/module/nginx-http-flv-module

make & make install

如果没有gcc环境,先安装gcc,如下: yum -y install openssl openssl-devel

# 1.3.5 修改配置

  1. echo "" > nginx-rtmp.conf

  2. vi nginx-rtmp.conf

  3. 粘贴如下内容:


#user  nobody;
worker_processes  1;
error_log  logs/error.log;
error_log  logs/error.log  notice;
error_log  logs/error.log  info;
pid        logs/nginx-rtmp.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    access_log  logs/access.log;
    sendfile        on;
    #tcp_nopush     on;
    #keepalive_timeout  0;
    keepalive_timeout  65;
    gzip  on;

    server {
        listen       8888;
        server_name  localhost;
        charset utf-8;
        access_log  logs/host.access.log;

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

        # 播放路径
        location /livestream {
            flv_live on;
            chunked_transfer_encoding on;
            add_header 'Access-Control-Allow-Origin' '*';
            add_header 'Access-Control-Allow-Credentials' 'true';
        }

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

        location /stat.xsl {
            root /opt/nginx-rtmp/stat;
        }

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

rtmp_auto_push on;
rtmp_auto_push_reconnect 1s;
rtmp_socket_dir /tmp;

rtmp {
    out_queue           4096;
    out_cork            8;
    max_streams         128;
    timeout             15s;
    drop_idle_publisher 30s;
    server {
        listen 7989;
        server_name localhost;
        application livestream {
            live on;
            gop_cache on;
        }
    }
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77

# 1.3.6 推流&播放

. 推流

ffmpeg -re -i example.mp4 -vcodec copy -acodec copy -f flv rtmp://www.apegeek.com:7989/livestream/123456

(可借助手机+腾讯视频云公众号实现推流测试)

. 播放

http://www.apegeek.com:9000/live?app=livestream&port=7989&stream=123456

# 2. 监控

# 2.1 下载

点击这里下载监控程序。

# 2.2 上传

将压缩包上传至opt目录下。

# 2.3 配置

  • 进入/opt/nginx-rtmp目录,编辑nginx-rtmp.conf文件。调整server节点配置。
# 修改此处
location /stat.xsl {
   # root /opt/nginx-rtmp/stat;
   root html;
}
# 添加此处
location /control {
  rtmp_control all;
  # Enable CORS
  add_header Access-Control-Allow-Origin * always;
}

1
2
3
4
5
6
7
8
9
10
11
12
  • 将stat.xsl文件上传至nginx-rtmp/html目录下。

# 2.4 安装Node

yum install nodejs

# 2.5 编译程序

进入**/opt/nginx-rtmp-monitoring**目录,执行命令: npm install

# 2.6 监控配置

修改config.json文件,调整对应的服务地址。

{
  "http_server_port":9991,
  "rtmp_server_refresh":3000,
  "rtmp_server_timeout":15000,
  "rtmp_server_url":"http://www.apegeek.com:1988/stat.xml",
  "rtmp_server_stream_url":"rtmp://www.apegeek.com:1935/live/",
  "rtmp_server_control_url":"http://www.apegeek.com:1988/control",
  "session_secret_key":"change_me_random",
  "username":"admin",
  "password":"123123",
  "language":"zh",
  "template":"default",
  "login_template":"login",
  "version":"1.0.2"
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

# 2.7 启动服务

node server.js &

# 2.8 验证

打开浏览器访问http://ip:9991地址,输入用户名密码登录。(admin/123123)

# 3. FlvJS

# 3.1 Flv Lib

GitHub (opens new window)

# 3.2 Flv Demo

点击这里 (opens new window)

# 3.3 代码实例

# 3.3.1 配置

let config = {
    enableWorker: false,
    enableStashBuffer: true,
    isLive: false,
    lazyLoad: true,
    lazyLoadMaxDuration: 180,
    lazyLoadRecoverDuration: 30,
    deferLoadAfterSourceOpen: true,
    autoCleanupMaxBackwardDuration: 180,
    autoCleanupMinBackwardDuration: 120,
    fixAudioTimestampGap: true,
    accurateSeek: false,
    seekType: 'range',
    seekParamStart: 'bstart',
    seekParamEnd: 'bend',
    rangeLoadZeroStart: false,
    reuseRedirectedURL: false
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

# 33.2 构建与播放


/**
 * 创建播放器对象
 */
createFlvPlayer(url, config) {
  let that = this;
  let mediaDataSource = {
    url: url,
    type: 'flv',
    isLive: that.isLive,
    duration: 0
  };
  let player = flvjs.createPlayer(mediaDataSource, config);
  return player;
}

/**
 * 加载并播放
 */
loadVideo(player, videoDom) {
  player.attachMediaElement(videoDom);
  player.load();
  player.play();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24

# 3.4销毁

/**
 * 销毁
 */
destroy(player) {
  try {
    if (player) {
      player.pause();
      player.unload();
      player.detachMediaElement();
      player.destroy();
      player = null;
    }
  } catch (err) {}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

# 4. 基础知识

# 4.1 流程

# 4.2 视频流传输协议

# 4.2.1 RTP / RTCP

# 4.2.1.1 RTP

RTP:实时传输协议(Real-time Transport Protocol)。

RTP数据协议负责对流媒体数据进行封包并实现媒体流的实时传输,每一个RTP数据报都由头部(Header)和负载(Payload)两个部分组成,其中头部前12个字节的含义是固定的,而负载则可以是音频或者视频数据。

RTP传输音频/视频数据,如果是PLAY,Server发送到Client端,如果是RECORD,可以由Client发送到Server 。

整个RTP协议由两个密切相关的部分组成:RTP数据协议和RTP控制协议(即RTCP)。

# 4.2.1.2 RTCP

RTCP包括Sender Report和Receiver Report,用来进行音频/视频的同步以及其他用途,是一种控制协议 。

RTCP控制协议需要与RTP数据协议一起配合使用,当应用程序启动一个RTP会话时将同时占用两个端口,分别供RTP和RTCP使用。RTP本身并不能为按序传输数据包提供可靠的保证,也不提供流量控制和拥塞控制,这些都由RTCP来负责完成。通常RTCP会采用与RTP相同的分发机制,向会话中的所有成员周期性地发送控制信息,应用程序通过接收这些数据,从中获取会话参与者的相关资料,以及网络状况、分组丢失概率等反馈信息,从而能够对服务质量进行控制或者对网络状况进行诊断。

RTCP协议的功能是通过不同的RTCP数据报来实现的,主要有如下几种类型:

  • SR:发送端报告,所谓发送端是指发出RTP数据报的应用程序或者终端,发送端同时也可以是接收端。

  • RR:接收端报告,所谓接收端是指仅接收但不发送RTP数据报的应用程序或者终端。

  • SDES:源描述,主要功能是作为会话成员有关标识信息的载体,如用户名、邮件地址、电话号码等,此外还具有向会话成员传达会话控制信息的功能。

  • BYE:通知离开,主要功能是指示某一个或者几个源不再有效,即通知会话中的其他成员自己将退出会话。

  • APP:由应用程序自己定义,解决了RTCP的扩展性问题,并且为协议的实现者提供了很大的灵活性。

# 4.2.3 RTSP

RTSP:实时流协议(Real Time Streaming Protocol,RTSP)。 RTSP的请求主要有DESCRIBE,SETUP,PLAY,PAUSE,TEARDOWN,OPTIONS等,顾名思义可以知道起对话和控制作用 。 RTSP的对话过程中SETUP可以确定RTP/RTCP使用的端口,PLAY/PAUSE/TEARDOWN可以开始或者停止RTP的发送,等等。

# 4.2.4 HTTP

# 4.3 常见直播协议

# 4.3.1 RTMP

RTMP,全称 Real Time Messaging Protocol,即实时消息传送协议。Adobe 公司为 Flash 播放器和服务器之间音视频数据传输开发的私有协议。工作在 TCP 之上的明文协议,默认使用端口 1935。协议中的基本数据单元成为消息(Message),传输的过程中消息会被拆分为更小的消息块(Chunk)单元。最后将分割后的消息块通过 TCP 协议传输,接收端再反解接收的消息块恢复成流媒体数据。

RTMP 主要有以下几个优点:RTMP 是专为流媒体开发的协议,对底层的优化比其它协议更加优秀,同时它 Adobe Flash 支持好,基本上所有的编码器(摄像头之类)都支持 RTMP 输出。现在 PC 市场巨大,PC 主要是 Windows,Windows 的浏览器基本上都支持 Flash。另外RTMP适合长时间播放,曾经有过测试,联系 100 万秒,即 10 天多连续播放没有出现问题。最后 RTMP 的延迟相对较低,一般延时在 1-3s 之间,一般的视频会议,互动式直播,完全是够用的。

当然 RTMP 并没有尽善尽美,它也有不足的地方。一方面是它是基于 TCP 传输,非公共端口,可能会被防火墙阻拦;另一方面,也是比较坑的一方面是 RTMP 为 Adobe 私有协议,很多设备无法播放,特别是在 iOS 端,需要使用第三方解码器才能播放。

# 4.3.2 HLS

FLV (Flash Video) 是 Adobe 公司推出的另一种视频格式,是一种在网络上传输的流媒体数据存储容器格式。其格式相对简单轻量,不需要很大的媒体头部信息。整个 FLV 由 The FLV Header, The FLV Body 以及其它 Tag 组成。因此加载速度极快。采用 FLV 格式封装的文件后缀为 .flv。

而我们所说的 HTTP-FLV 即将流媒体数据封装成 FLV 格式,然后通过 HTTP 协议传输给客户端。

HTTP-FLV 依靠 MIME 的特性,根据协议中的 Content-Type 来选择相应的程序去处理相应的内容,使得流媒体可以通过 HTTP 传输。相较于 RTMP 协议,HTTP-FLV 能够好的穿透防火墙,它是基于 HTTP/80 传输,有效避免被防火墙拦截。除此之外,它可以通过 HTTP 302 跳转灵活调度/负载均衡,支持使用 HTTPS 加密传输,也能够兼容支持 Android,iOS 的移动端。

说了这么多优点,也来顺便说下 HTTP-FLV 的缺点,由于它的传输特性,会让流媒体资源缓存在本地客户端,在保密性方面不够好。因为网络流量较大,它也不适合做拉流协议。

相对于常见的流媒体协议,HLS 最大的不同在于它并不是一下请求完整的数据流。它会在服务器端将流媒体数据切割成连续的时长较短的 ts 小文件,并通过 M3U8 索引文件按序访问 ts 文件。客户端只要不停的按序播放从服务器获取到的文件,从而实现播放音视频。

# 4.3.2.1 优势
  • Apple 的全系列产品支持:由于 HLS 是苹果提出的,所以在 Apple 的全系列产品包括 iPhone、 iPad、safari 都不需要安装任何插件就可以原生支持播放 HLS, 现在 Android 也加入了对 HLS 的支持。
  • 穿透防火墙。基于 HTTP/80 传输,有效避免防火墙拦截
  • 性能高。通过 HTTP 传输, 支持网络分发,CDN 支持良好,且自带多码率自适应,Apple 在提出 HLS 时,就已经考虑了码流自适应的问题。
# 4.3.2.2 劣势
  • 实时性差,延迟高。HLS 的延迟基本在 10s+ 以上
  • 文件碎片。特性的双刃剑,ts 切片较小,会造成海量小文件,对存储和缓存都有一定的挑战

# 4.3.3比较

更新时间: 12/13/2022, 7:50:55 PM