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 修改配置
- echo “” > nginx-rtmp.conf
- vi nginx-rtmp.conf
- 粘贴如下内容:
#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.3.6 推流&播放
. 推流
ffmpeg -re -i example.mp4 -vcodec copy -acodec copy -f flv rtmp://www.apegeek.com:7989/livestream/123456
(可借助手机+腾讯视频云公众号实现推流测试)
. 播放
https://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; }
- 将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":"https://www.apegeek.com:1988/stat.xml", "rtmp_server_stream_url":"rtmp://www.apegeek.com:1935/live/", "rtmp_server_control_url":"https://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" }
2.7 启动服务
node server.js &
2.8 验证
打开浏览器访问http://ip:9991地址,输入用户名密码登录。(admin/123123)
3. FlvJS
3.1 Flv Lib
3.2 Flv Demo
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 };
3.3.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(); }
3.4销毁
/** * 销毁 */ destroy(player) { try { if (player) { player.pause(); player.unload(); player.detachMediaElement(); player.destroy(); player = null; } } catch (err) {} }
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 切片较小,会造成海量小文件,对存储和缓存都有一定的挑战