流媒体服务器解决方案
需求说明:
这里主要采用开源项目SRS流媒体服务来搭建一个流媒体服务器,通过推流服务器将摄像头的实时视频流推送到SRS流媒体服务器,然后客户端可以拉取SRS流媒体服务器的rtmp或者http流数据,实现摄像头的视频流转换成rtmp流,实时显示视频监控画面。
项目开源地址:https://github.com/ossrs/srs
软硬件环境准备 | ||
CPU |
双核及以上 |
|
内存 |
4G及以上 |
|
硬盘 |
100G及以上 |
|
网络 |
千兆网络(192.168.8.26) |
|
操作系统 |
Centos7 minal或ubuntu 16.04 server lts |
|
操作系统的选择,这里需要说明的是,centos是企业中使用比较多的操作系统,其稳定性较好,不容易出现问题,但是某些软件需要编译使用,依赖关系比较复杂的软件相对比较麻烦,而Ubuntu是更新最快的操作系统之一,很多软件包更新速度很快,大多数都可以使用包管理工具进行安装,这点对于依赖关系复杂的软件具有一定的优势,但是由于更新很快,系统稳定性较差。这里主要是搭建srs流媒体服务器,推流服务器分离,若服务器既要提供流媒体服务,又要推流,建议选择ubuntu系统,因此我这里选择使用centos 7 最小化系统来实现srs流媒体服务器,其中大部分内容也可做为ubuntu系统搭建部署的参考。
SRS支持rtmp\hls\webrtc\srt\GB28181多种协议,稳定性较好、使用简单方便,这也是为什么选择这款开源软件的主要原因。
基础系统环境准备:
#安装所需的工具
yum install vim lrzsz wget curl gcc gcc-c++ make unzip patch git
#拉取代码
git clone https://gitee.com/winlinvip/srs.oschina.git srs &&
cd srs/trunk && git remote set-url origin https://github.com/ossrs/srs.git && git pull
#构建并编译
./configure && make
#运行服务
./objs/srs -c conf/srs.conf
#注册到系统,使用systemctl管理服务
make install
sudo ln -sf /usr/local/srs/etc/init.d/srs /etc/init.d/srs &&
sudo cp -f /usr/local/srs/usr/lib/systemd/system/srs.service /usr/lib/systemd/system/srs.service && sudo systemctl daemon-reload && sudo systemctl enable srs &&
sudo systemctl start srs
#检查服务状态
systemctl status srs
#常用操作命令
systemctl stop srs
systemctl restart srs
此时的推流地址:rtmp://192.168.8.26:1935/app/stream
此时的拉流地址:rtmp://192.168.8.26:1935/app/stream
各种配置实例:
- rtmp配置实例
#最小配置
listen 1935; #监听端口
max_connections 1000; #最大连接数
vhost __defaultVhosts__ { #默认虚拟主机
}
此时的推流地址:rtmp://192.168.8.26/live/livestream
此时的拉流地址:rtmp://192.168.8.26/live/livestream
#URL规则说明
https://github.com/ossrs/srs/wiki/v1_CN_RtmpUrlVhost
应用场景:
- 一个分发网络支持多个客户:比如cdn,一个分发网络中,N个客户共用一套流媒体系统,如何区别用户、计费、监控等等问题,最好的方式是通过各自的域名。
- 不同的应用配置:比如fmle推流h264+mp3,可以将音频转码后放到其他的vhost分发hls,这样接入h264+mp3的vhost就不用切hls.
标准rtmp URL:
标准rtmp URL指的是最大兼容的rtmp url,基本上所有的服务器和播放器都能识别,例如:
HTTP |
Schema |
Host |
Port |
App |
Stream |
http://192.168.8.26:80/players/srs_player.htm |
http |
192.168.8.26 |
80 |
players |
Srs_player.html |
rtmp://192.168.8.26:1935/live/livestream |
rtmp |
192.168.8.26 |
1935 |
live |
livestream |
其中:
- Schema:协议头,HTTP为HTTP或HTTPS,RTMP为RTMP/RTMPS/RTMPE/RTMPT等众多协议,还有新出的RTMFP。
- Host:主机,表示要连接的主机,可以为主机DNS名称或者IP地址。商用时,一般不会用IP地址,而是DNS名称,这样可以用CDN分发内容(CDN一般使用DNS调度,即不同网络和地理位置的用户,通过DNS解析到的IP不一样,实现用户的就近访问)。
- Port:端口,HTTP默认为80,RTMP默认为1935。当端口没有指定时,使用默认端口。
- Path:路径,HTTP访问的文件路径。
- App:RTMP的Application(应用)名称,可以类比为文件夹。以文件夹来分类不同的流,没有特殊约定,可以任意划分。
- Stream:RTMP的Stream(流)名称,可以类比为文件。
无vhost:
rtmp://192.168.8.26/app/stream
举例:
rtmp://192.168.8.26/reader/red_mansion
vhost应用:
RTMP的Vhost和HTTP的Vhost概念是一样的:虚拟主机。详见下表(假设域名demo.srs.com被解析到IP为192.168.8.26的服务器):
http |
host |
port |
vhost |
192.168.8.26 |
80 |
demo.srs.com |
|
rtmp://demo.srs.com:1935/live/livestream |
192.168.8.26 |
1935 |
demo.srs.com |
Vhost主要的作用是:
- 支持多用户:当一台服务器需要服务多个客户,譬如CDN有cctv(央视)和wasu(华数传媒)两个客户时,如何隔离他们两个的资源?相当于不同的用户共用一台计算机,他们可以在自己的文件系统建立同样的文件目录结构,但是彼此不会冲突。
- 域名调度:CDN分发内容时,需要让用户访问离自己最近的边缘节点,边缘节点再从源站或上层节点获取数据,达到加速访问的效果。一般的做法就是Host是DNS域名,这样可以根据用户的信息解析到不同的节点。
- 支持多配置:有时候需要使用不同的配置,考虑一个支持多终端(PC/Apple/Android)的应用,PC上RTMP分发,Apple和Android是HLS分发,如何让PC延迟最低,同时HLS也能支持,而且终端播放时尽量地址一致(降低终端开发难度)?可以使用两个Vhost,PC和HLS;PC配置为最低延迟的RTMP,并且将流转发给HLS的Vhost,可以对音频转码(可能不是H264/AAC)后切片为HLS。PC和HLS这两个Vhost的配置肯定是不一样的,播放时,流名称是一样,只需要使用不同的Host就可以。
vhost多用户:
假设cctv和wasu都运行在一台边缘节点(192.168.8.26)上,用户访问这两个媒体的流时,Vhost的作用见下表:
Rtmp |
host |
port |
vhost |
app |
stream |
rtmp://show.cctv.cn/live/livestream |
192.168.8.26 |
1935 |
Show.cctv.cn |
live |
livestream |
rtmp://show.cctv.cn/live/livestream |
192.168.8.26 |
1935 |
Show.wasu.cn |
live |
livestream |
配置如下:
listen 1935;
vhost show.cctv.cn {
}
vhost show.wasu.cn {
}
vhost支持多配置
现在有个需求:
cctv延迟最低(启动时只有声音,画面是黑屏)
wasu需要快速启动(打开就能看到视频,服务器cache了最后一个gop,延迟会比较大)
配置如下:
listen 1935;
vhost show.cctv.cn {
chunk_size 128;
}
vhost show.wasu.cn {
chunk_size 4096;
}
互不影响。相互独立。
默认vhost:
FMS的__defaultVhost__是默认的vhost,当用户请求的vhost没有匹配成功时,若配置了defaultVhost,则使用它来提供服务。若匹配失败,也没有defaultVhost,则返回错误。
譬如,服务器192.168.8.26上的SRS配置如下:
listen 1935;
vhost demo.srs.com {
enabled on;
}
那么,当用户访问以下vhost时:
- rtmp://demo.srs.com/live/livestream:成功,匹配vhost为demo.srs.com
- rtmp://192.168.8.26/live/livestream:失败,没有找到vhost,也没有defaultVhost。
defaultVhost和其他vhost的规则一样,只是用来匹配那些没有匹配成功的vhost的请求的
访问指定的vhost:
如何访问某台服务器上的Vhost?有两个方法:
- 配置hosts:因为Vhost实际上就是DNS解析,所以可以配置客户端的hosts,将域名(Vhost)解析到指定的服务器,就可以访问这台服务器上的指定的vhost。
- 使用app的参数:需要服务器支持。在app后面带参数指定要访问的Vhost。SRS支持?vhost=VHOST和...vhost...VHOST这两种方式,后面的方式是避免一些播放器不识别?和=等特殊字符。
普通用户不用这么麻烦,直接访问RTMP地址就好了,有时候运维需要看某台机器上的Vhost的流是否有问题,就需要这种特殊的访问方式。考虑下面的例子:
RTMP URL: rtmp://demo.srs.com/live/livestream
边缘节点数目:50台
边缘节点IP:192.168.1.100 至 192.168.1.150
边缘节点SRS配置:
listen 1935;
vhost demo.srs.com {
mode remote;
origin: xxxxxxx;
}
各种访问方式见下表:
用户 |
RTMP URL |
hosts设置 |
目标 |
普通用户 |
rtmp://demo.srs.com/live/livestream |
无 |
由DNS |
运维 |
rtmp://demo.srs.com/live/livestream |
192.168.8.26 demo.srs.com |
查看192.168.1.100上的流 |
运维 |
rtmp://192.168.8.26/live? |
无 |
查看192.168.1.100上的流 |
运维 |
rtmp://192.168.8.26/live |
无 |
查看192.168.1.100上的流 |
延时配置rtmp:
https://github.com/ossrs/srs/wiki/v1_CN_LowLatency
gop_cache配置项,on就会马上播放,off就低延迟
queue_length 10; 累积延迟,队列长度
低延时配置案例:
listen 1935;
vhost __defaultVhost__ {
gop_cache off;
queue_length 10;
}
案例:
推流服务器在北京内网,观看直播在浙江杭州,流媒体服务器为阿里云
listen 1935;
vhost __defaultVhost__ {
enabled on;
gop_cache off;
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 5;
hls_window 20;
}
}
- hls配置实例
conf/hls.conf
listen 1935;
max_connections 1000;
http_server {
enabled on;
listen 8080;
dir ./objs/nginx/html;
}
vhost __defaultVhost__ {
hls {
enabled on;
hls_path ./objs/nginx/html;
hls_fragment 10;
hls_window 60;
}
}
https://github.com/ossrs/srs/wiki/v3_CN_DeliveryHLS
HLS指Apple的HLS(Http Live Streaming),本身就是Live(直播)的,不过Vod(点播)也能支持。HLS是Apple平台的标准流媒体协议,和RTMP在PC上一样支持得天衣无缝。
HLS主要的应用场景包括:
- 跨平台:PC主要的直播方案是RTMP,也有一些库能播放HLS,譬如jwplayer,基于osmf的hls插件也一大堆。所以实际上如果选一种协议能跨PC/Android/IOS,那就是HLS。
- IOS上苛刻的稳定性要求:IOS上最稳定的当然是HLS,稳定性不差于RTMP在PC-flash上的表现。
- 友好的CDN分发方式:目前CDN对于RTMP也是基本协议,但是HLS分发的基础是HTTP,所以CDN的接入和分发会比RTMP更加完善。能在各种CDN之间切换,RTMP也能,只是可能需要对接测试。
- 简单:HLS作为流媒体协议非常简单,apple支持得也很完善。Android对HLS的支持也会越来越完善。至于DASH/HDS,好像没有什么特别的理由,就像linux已经大行其道而且开放,其他的系统很难再广泛应用。
总之,SRS支持HLS主要是作为输出的分发协议,直播以RTMP+HLS分发,满足各种应用场景。点播以HLS为主。
Delivering Streams
详见下表:
分发 |
平台 |
协议 |
公司 |
说明 |
RTMP |
Windows Flash |
RTMP |
Adobe |
主流的低延时分发方式, |
HLS |
Apple/ |
HTTP |
Apple/ |
延时一个切片以上(一般10秒以上), |
HDS |
- |
HTTP |
Adobe |
Adobe自己的HLS, |
- |
HTTP |
- |
Dynamic Adaptive Streaming over HTTP (DASH), |
hls地址:http://demo.srs.com/live/livestream.m3u8
H5页面引入:
<!-- livestream.html -->
<video width="640" height="360"
autoplay controls autobuffer
src="http://demo.srs.com/live/livestream.m3u8"
type="application/vnd.apple.mpegurl">
</video>
HLS的主要流程是:
- FFMPEG或FMLE或编码器,推送RTMP流到SRS,编码为H264/AAC(其他编码需要SRS转码)
- SRS将RTMP切片成TS,并生成M3U8。若流非H264和AAC,则停止输出HLS(可使用SRS转码到SRS其他vhost或流,然后再切HLS)。
- 访问m3u8,srs内置的http服务器(或者通用http服务器)提供HTTP服务。
注意:SRS只需要在Vhost上配置HLS,会自动根据流的app创建目录,但是配置的hls_path必须自己创
推流地址:rtmp://192.168.8.26:1935/live/livestream
播放地址:http://192.168.8.26:8080/live/livestream.m3u8