准备
目前行业里直播还是以TCP占绝对份额,rtmp或者hls都是基于TCP,但是从底层UDP和TCP的特性来看,还是UDP更适合做直播。
文中测试视频:https://pan.baidu.com/s/1Cs9bULQ26zmDjbNqiIyUow 密码:q839
SRS官网:http://winlinvip.github.io/srs.release/releases/
SRS源码:https://github.com/ossrs/srs
直播方案对比
详见下表:
分发 | 平台 | 协议 | 公司 | 说明 |
---|---|---|---|---|
RTMP | Windows Flash | RTMP | Adobe | 主流的低延时分发方式, Adobe的RTMP是Flash原生支持方式, FMS(Adobe Media Server前身), 就是Flash Media Server的简写,可见Flash播放RTMP是多么“原生”, 就像浏览器打开http网页一样“原生”, 经测试,Flash播放RTMP流可以10天以上不间断播放。 |
HLS | Apple/ Android | HTTP | Apple/ Google | 延时一个切片以上(一般10秒以上), Apple平台上HLS的效果比PC的RTMP还要好, 而且Apple所有设备都支持, Android最初不支持HLS,后来也支持了, 但测试发现支持得还不如Apple, 不过观看是没有问题,稳定性稍差, 所以有些公司专门做Android上的流媒体播放器。 |
Docker安装(推荐)
默认配置
1 | docker run -d -p 1935:1935 -p 1985:1985 -p 8080:8080 --name srs3 registry.cn-hangzhou.aliyuncs.com/ossrs/srs:3 |
可用的流
rtmp://rtmp.psvmc.cn/live/livestream
自定义配置
新建配置文件
1 | mkdir -p /usr/local/srs3/conf |
配置文件/usr/local/srs3/conf/z.log
1 | # the listen ports, split by space. |
运行
1 | docker run -d -p 1935:1935 -p 1985:1985 -p 8080:8080 \ |
停止并删除
1 | docker stop srs3 &&\ |
便捷安装
当流服务器不涉及ffmpeg操作时用该方式
下面这种方式是直接安装官方编译过的,里面不包含ffmpeg库,
如果需要ffmpeg处理流的话需要自行下载ffmpeg,或者用下文编译源码的方式(推荐)
1 | cd /root |
srs安装后的目录为/usr/local/srs
abort, please install lsb_release
1 | yum install -y redhat-lsb |
RTMP URL格式:
1 | rtmp://ip:[port]/appName/streamName |
例如:1
rtmp://192.168.1.108:1935/live/xiaoming
编译安装
当流服务器涉及ffmpeg操作时用该方式
下面下载官方源码编译,Github下载太慢,我就在gitee上做了个镜像。
这里之所以编译源码是因为之前的直接安装方式并不提供三方的库,比如接下来要用的ffmpeg;
当然我们也可以自己手动安装ffmpeg,然后修改配置文件中默认的ffmpeg路径即可。
注意这里ffmpeg一定要用4.1版本 srs在4.2版本下部分语法不支持 这里坑了我好久
如果之前安装过4.2版本的一定要先删除
查看ffmpeg版本
1 | ffmpeg -version |
安装srs
1 | cd ~ |
这里没有用下面这种方式安装
1 | ./configure --prefix=/usr/local/srs2 --with-ffmpeg |
是因为这样安装后ffmpeg的文件夹并没有生成 还要手动再复制过去
我这里安装ffmpeg编译报错
build ffmpeg failed
build ffmpeg-4.1 failed, ret=1
本来srs的编译已经包含x264和ffmpeg,我这报错就只能自己手动安装了
上面安装成功的就不用再执行以下命令了
安装编译环境
1 | yum install -y automake autoconf libtool gcc gcc-c++ |
安装yasm插件
1 | wget http://www.tortall.net/projects/yasm/releases/yasm-1.3.0.tar.gz |
安装nasm
1 | cd ~ |
安装 srs
1 | yum install -y git |
测试ffmpeg
1 | ffmpeg -version |
报错:
ffmpeg: error while loading shared libraries: libx264.so.157: cannot open sh
解决方法
1 | vi /etc/ld.so.conf |
添加libx264.so所在路径
1 | /usr/local/lib |
退出后执行
1 | ldconfig |
常用配置
低延迟配置
1 | # the listen ports, split by space. |
1 | cd /usr/local/srs2 |
结束进程
1 | lsof -i:1935 |
转封装成FLV流
详细配置:https://github.com/ossrs/srs/wiki/v2_CN_SampleHttpFlv
1 | listen 1935; |
生成的流地址为:
- RTMP流地址为:
rtmp://rtmp.psvmc.cn/live/livestream
- HTTP FLV:
http://rtmp.psvmc.cn:8080/live/livestream.flv
安全策略
详细配置:https://github.com/ossrs/srs/wiki/v2_CN_Security
目前只支持基于IP的安全策略,实用性不大。
1 | vhost your_vhost { |
本地录制FLV
详细配置:https://github.com/ossrs/srs/wiki/v2_CN_DVR
直播流保存本地文件。
1 | vhost __defaultVhost__ { |
流转发
详细配置:https://github.com/ossrs/srs/wiki/v1_CN_SampleForward
1 | vhost __defaultVhost__ { |
Forward VS Edge
Forward架构和CDN架构的最大区别在于,CDN属于大规模集群,边缘节点会有成千上万台,源站2台(做热备),还需要有中间层。CDN的客户很多,流也会有很多。所以假若源站将每个流都转发给边缘,会造成巨大的浪费(有很多流只有少数节点需要)。
可见,forward只适用于所有边缘节点都需要所有的流。CDN是某些边缘节点需要某些流。
forward的瓶颈在于流的数目,假设每个SRS只侦听一个端口:
1 | 系统中流的数目 = 编码器的流数目 × 节点数目 × 端口数目 |
考虑5个节点,每个节点起4个端口,即有20个SRS边缘。编码器出5路流,则有20 * 5 = 100路流
。
同样的架构,对于CDN的边缘节点来讲,系统的流数为用户访问边缘节点的流
,假设没有用户访问,系统中就没有流量。某个区域的用户访问某个节点上的流,系统中只有一路流,而不是forward广播式的多路流。
另外,forward需要播放器随机访问多个端口,实现负载均衡,或者播放器访问api服务器,api服务器实现负载均衡,对于CDN来讲也不合适(需要客户改播放器)。
总之,forward适用于小型规模的集群,不适用于CDN大规模集群应用。
转封装成HLS流
详细配置:https://github.com/ossrs/srs/wiki/v2_CN_SampleHLS
1 | listen 1935; |
生成的流地址为:
- RTMP流地址为:
rtmp://rtmp.psvmc.cn/live/livestream
- HLS流地址为:
http://rtmp.psvmc.cn/live/livestream.m3u8
HTTP回调
详细配置:https://github.com/ossrs/srs/wiki/v2_CN_HTTPCallback
1 | vhost __defaultVhost__ { |
SRS的回调事件包括:
事件 | 数据 | 说明 |
---|---|---|
on_connect | { “action”: “on_connect”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “tcUrl”: “rtmp://x/x?key=xxx”, “pageUrl”: “http://x/x.html" } | 当客户端连接到指定的vhost和app时 |
on_close | { “action”: “on_close”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “send_bytes”: 10240, “recv_bytes”: 10240 } | 当客户端关闭连接,或者SRS主动关闭连接时 |
on_publish | { “action”: “on_publish”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “tcUrl”: “rtmp://x/x?key=xxx”, “stream”: “livestream” } | 推流到服务器时 |
on_unpublish | { “action”: “on_unpublish”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “stream”: “livestream” } | 当客户端停止发布流时 |
on_play | { “action”: “on_play”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “stream”: “livestream”, “pageUrl”: “http://a.com/i.html", “param”:”?k=v” } | 当客户端开始播放流时 |
on_stop | { “action”: “on_stop”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “stream”: “livestream” } | 当客户端停止播放时。备注:停止播放可能不会关闭连接,还能再继续播放。 |
on_dvr | { “action”: “on_dvr”, “client_id”: 1985, “ip”: “192.168.1.10”, “vhost”: “video.test.com”, “app”: “live”, “stream”: “livestream”, “cwd”: “/opt”, “file”: “./l.xxx.flv” } | 当DVR录制关闭一个flv文件时 |
其中:
- 事件:发生该事件时,即回调指定的HTTP地址。
- HTTP地址:可以支持多个,以空格分隔,SRS会依次回调这些接口。
- 数据:SRS将数据POST到HTTP接口。
- 返回值:SRS要求HTTP服务器返回HTTP200并且response内容为整数错误码(0表示成功),其他错误码会断开客户端连接。
启动自带接口服务器
1 | python research/api-server/server.py 8085 |
启动srs
1 | ./objs/srs -c conf/http.hooks.callback.conf |
测试推流
1 | ffmpeg -re -stream_loop -1 -i /data/rtmptest.mp4 -vcodec copy -acodec copy -f flv -y rtmp://127.0.0.1:1935/live/test |
FFMpeg转码
详细配置:
用于流处理或处理并转发RTMP服务器。
SRS转码的主要流程包括:
- 编码器推送RTMP流到SRS的vhost。
- SRS的vhost若配置了转码,则进行转码。
- 转码后,按照配置,推送到SRS本身或者其他RTMP服务器。
流处理
1 | listen 1935; |
处理并转发RTMP服务器
1 | vhost __defaultVhost__ { |
启动
1 | cd /usr/local/srs2 |
推流
1 | ffmpeg -re -stream_loop -1 -i /usr/local/srs2/doc/source.200kbps.768x320.flv -vcodec copy -acodec copy -f flv -y rtmp://127.0.0.1:1935/live/test |
测试服务器上ffmpeg是否能处理流成功
1 | ffmpeg -f flv -i rtmp://127.0.0.1:1935/live/test -vcodec libx264 -threads 4 -profile:v main -preset medium -acodec copy -f flv -y rtmp://127.0.0.1:1935/live/test2 |
涉及的流包括:
- 编码器推送流:rtmp://rtmp.psvmc.cn:1935/live/test
- 观看原始流:rtmp://rtmp.psvmc.cn/live/test
- 命令转码流:rtmp://rtmp.psvmc.cn/live/test2
- 观看转码流:rtmp://rtmp.psvmc.cn/live/test_ff
推流测试
1 | ffmpeg -re -stream_loop -1 -i /data/rtmptest.mp4 -vcodec copy -acodec copy -f flv -y rtmp://rtmp.psvmc.cn:1935/live/test |
低版本FFMpeg循环播放
1 | for((;;)); do \ |
播放地址
- rtmp://rtmp.psvmc.cn/live/test
- http://rtmp.psvmc.cn:8080/live/test.flv
注册服务
添加文件 /etc/init.d/srs.sh
1 |
|
赋权
1 | chmod +x /etc/init.d/srs.sh |
添加为系统服务
1 | chkconfig --add srs.sh |
开机自启动
1 | chkconfig srs.sh on |
查看
1 | chkconfig --list |
启动
1 | service srs.sh start |
停用
1 | service srs.sh stop |
查看启动情况
1 | lsof -i:1935 |
流播放
建议网页播放都用flv封装一下
flv.js:https://github.com/Bilibili/flv.js
在线测试地址:
测试Demo
链接: https://pan.baidu.com/s/1uGZNn48dRnZ09feOa8_gbQ 密码: d3n4