0%

HLS-搭建Nginx流媒体服务器

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

这个流媒体服务器可以支持RTMP和HLS(Live Http Stream)

Nginx安装开始
源码安装

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#安装gcc,nginx底层采用c++编写,因此需要gcc环境进行编译
yum install gcc-c++
#安装pcre,一个Perl库,包括perl兼容的正则表达式,nginx的http模块使用pcre来解析正则表达式,所以需要在linux上安装pcre, pcre-devel是使用pcre开发的一个二次开发库,nginx也需要此库
yun install pcre pcre-devel
#安装zlib zlib库提供了多种压缩和解压缩方式,nginx使用zlib对http包的内容进行gzip,所以需要在linux上安装zlib库
yum install -y zlib zlib-devel
#安装openssl penssl是一个强大的安全套接字层密码库,囊括了主要的密码算法、常用的秘钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。
#nginx不仅支持http协议,还支持https(即在ssl协议上传输http),所以需要在linux上安装openssl库
yum install -y openssl openssl-devel
#下载nginx-rtmp-module
git clone https://github.com/arut/nginx-rtmp-module.git
wget http://nginx.org/download/nginx-1.19.7.tar.gz
tar -xzvf nginx-1.19.7.tar.gz
cd nginx-1.19.7
./configure --prefix=/usr/local/nginx --with-pcre=/home/user/pcre/pcre-8.32 --with-zlib=/home/user/zlib/zlib-1.2.8 --with-openssl=/home/user/openssl/openssl-1.0.1i --add-module=/home/user/nginx-rtmp-module
make && make install

nginx 配置rtmp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
rtmp {
server {
listen 1935; #端口
     RTMP 直播流配置
application rtmplive {
live on;
}       HLS 直播流配置
application hls {
live on;
hls on; #开启hls
hls_path /tmp/hls;          hls_fragment 5s #一个ts 文件的时长 5s
}
}
}
#hls_path需要可读可写的权限。

修改http中的server模块:

1
2
3
4
5
6
7
8
location /hls {
types {
application/vnd.apple.mpegurl m3u8;
video/mp2t ts;
}
root /tmp;
add_header Cache-Control no-cache;
}

修改nginx.conf之后,需重启nginx服务,才会生效:$nginx -s reload。
再次在浏览器中测试:http://localhost,以确认nginx开启的状态。

保存完配置文件后,启动nginx,通过netstat -ltn命令可以看到增加了一个1935端口的监听.80是nginx默认的http监听端口。

ffmpeg安装
从ffmpeg官网:http://ffmpeg.org/download.html下载最新的ffmpeg安装包,然后通过如下命令解压:

1
2
3
4
5
6
7
tar jxf ffmpeg-2.5.3.tar.bz2
./configure --enable-shared --prefix=/usr/local/ffmpeg --disable-yasm
make && make install
#--prefix表示程序安装的目录,这里设为/usr/local/ffmpeg。
#--enable-shared表示生成动态链接库,可以供以后编程使用,同时生成的可执行程序也依赖这些动态库。
#--disable-yasm表示禁用yasm。
#如果不禁用yasm 就会报错

然后用ffmpeg推流到nginx:
RTMP流,推流至rtmplive:

1
ffmpeg -re -i "D:\download\film\aqgy\02.mp4" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://server:1935/rtmplive/test1

HLS流,推流至hls:

1
ffmpeg -re -i "D:\download\film\aqgy\02.mp4" -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://ip:1935/hls/test2

其中,HLS流表现较明显,在nginx的临时目录下,直观的可看到m3u8索引文件和N多个.ts文件。m3u8列表会实时更新,且会动态更改当前播放索引切片(.ts)。这种实时更新的机制,不会使得.ts文件长时间存在于Nginx服务器上,且当推流结束之后,该目录下的内容会被全部清除,这样无形中减缓了nginx服务器的压力。HLS协议在服务器端将直播数据流存储为连续的、很短时长的媒体文件(MPEG-TS格式),而客户端则不断的下载并播放这些小文件,因为服务器端总是会将最新的直播数据生成新的小文件,这样客户端只要不停的按顺序播放从服务器获取到的文件,就实现了直播。由此可见,基本上可以认为,HLS是以点播的技术方式来实现直播。由于数据通过HTTP协议传输,所以完全不用考虑防火墙或者代理的问题,而且分段文件的时长很短,客户端可以很快的选择和切换码率,以适应不同带宽条件下的播放。不过HLS的这种技术特点,决定了它的延迟一般总是会高于普通的流媒体直播协议。
m3u8索引文件

1
2
3
4
5
6
#EXTM3U                     m3u文件头,必须放在第一行
#EXT-X-MEDIA-SEQUENCE 第一个TS分片的序列号 #当前索引
#EXT-X-TARGETDURATION 每个分片TS的最大的时长
#EXT-X-ALLOW-CACHE 是否允许cache
#EXT-X-ENDLIST m3u8文件结束符
#EXTINF extra info,分片TS的信息,如时长,带宽等

现在我们的流媒体服务器有两个实时流了,一个是rtmp的,另一个是hls的,用流媒体播放器播放一下,流媒体播放器可以用vlc也可以用ffmpeg带的ffplay.手机也是可以播放的。

第一个就是推送的地址: rtmp://localhost:1935/myapp/test1

第二个是HTTP地址: http://localhost/hls/test2.m3u8

播放rtmp流或hls流
最简单的测试,可通过VLC播放器,建立网络任务实现播放。所谓的播放,就是从Nginx服务器取到视频流并播放,也称之为“拉流”。需注意的是,HLS是基于HTTP的流媒体传输协议,端口为8080 ,hls的话用hls on开启hls,并且为hls设置一个临时文件目录hls_path /tmp/hls;其它更高级的配置可以参看nginx-rtmp-module的readme;而RTMP本身即为实时消息传输协议,端口为1935。由此决定了客户端访问直播流的方式
拉流地址:

1
2
RTMP流:rtmp://localhost:1935/rtmplive/test
HLS流:http://localhost:8080/hls/test.m3u8