流媒体服务解决方案——筑梦之路

流媒体服务器解决方案

 

需求说明:

这里主要采用开源项目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

 

 

各种配置实例:

  1. 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

 

应用场景:

  1. 一个分发网络支持多个客户:比如cdn,一个分发网络中,N个客户共用一套流媒体系统,如何区别用户、计费、监控等等问题,最好的方式是通过各自的域名。
  2. 不同的应用配置:比如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

http://demo.srs.com:80/players/srs_player.html

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?
vhost=demo.srs.com/livestream

查看192.168.1.100上的流

运维

rtmp://192.168.8.26/live
...vhost...demo.srs.com/livestream

查看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;
    }
}

 

 

  1. 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

主流的低延时分发方式,
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上的流媒体播放器。

HDS

-

HTTP

Adobe

Adobe自己的HLS,
协议方面做得是复杂而且没有什么好处,
国内没有什么应用,传说国外有,
SRS2已经支持。

DASH

-

HTTP

-

Dynamic Adaptive Streaming over HTTP (DASH),
一些公司提出的HLS,
国内还没有应用,国外据说有用了,
nginx-rtmp好像已经支持了,
明显这个还不成熟,SRS是不会支持的。

 

 

 

        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的主要流程是:

  1. FFMPEG或FMLE或编码器,推送RTMP流到SRS,编码为H264/AAC(其他编码需要SRS转码)
  2. SRS将RTMP切片成TS,并生成M3U8。若流非H264和AAC,则停止输出HLS(可使用SRS转码到SRS其他vhost或流,然后再切HLS)。
  3. 访问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

 

 

 

上一篇:2021-06-04


下一篇:2021-07-17