SRS

SRS服务器

1.RTMP简介

RTMP是PC-flash支持最完善的流分发方式,主要的应用场景包括:

无插件流媒体应用:十年前各种浏览器插件大行其道,最后adobe的flash一统天下,现在如何观看视频还需要用户装插件,已经是非常罕见的事情。 打开浏览器就能用,不用装插件,这是RTMP的最基本的应用方式。

适配广泛的播放器:如果没有专业的flash开发人员,那么RTMP会是个很好的选择,只要3行代码就能完成一个播放器,和html5的video标签一样方便。HDS/HLS在PC上,都需要库支持,N行代码很麻烦。

苛刻的稳定性支持:RTMP服务器能365x24提供服务,当然http服务器也可以。客户端的稳定性呢?RTMP在flash中连续播放10天没有问题, flash如果播放HTTP流就真的很难讲。如果在PC上需要客户端长时间播放,稳定播放,选择RTMP会是最佳选择。

稳定的较小延迟:RTMP延迟在0.8-3秒,能应用于交互式直播,视频会议,互动式直播等等。如果对延时有一定要求,就不要选择HLS,RTMP会是最佳选择。

通用接入标准:RTMP是编码器到服务器的实际标准协议,所有编码器都支持RTMP推送流。 选择RTMP作为直播接入协议,能适配多种编码器,不至于绑定到一种编码器。如果服务器只能接入HTTP FLV流,像某些公司做的私有协议,那么对接通用编码器就有问题。

SRS直播将RTMP作为基本协议,以各种方式转码为RTMP后输入到SRS,输出为RTMP和HLS,支持广泛的客户端和各种应用场景。

1.1.单机部署

一、获取SRS

1、获取所有源码
git clone https://github.com/ossrs/srs
cd srs/trunk
2、更新已有代码
git pull

二、编译SRS

./configure && make

三、编写配置文件

参考 conf/rtmp.conf

四、启动SRS

./objs/srs -c conf/rtmp.conf

五、启动推流编码器

ffmpeg推流

for((;;)); do \
    ./objs/ffmpeg/bin/ffmpeg -re -i ./doc/source.flv \
    -c copy \
    -f flv rtmp://192.168.1.170/live/livestream; \
    sleep 1; \
done

六、观看rtmp流

vlc播放

1.2.边缘集群部署

一、简介

边缘edge服务器,就是边缘直播缓存服务器。 配置时指定为remote模式和origin(指定一个或多个源站IP),这个边缘edge服务器就是源站的缓存了。

二、场景

譬如源站在北京BGP机房,湖南有个电信ADSL用户要推流发布自己的直播流,要是直接推流到北京BGP可能效果不是很好, 可以在湖南电信机房部署一个边缘,用户推流到湖南边缘,边缘转发给北京源站BGP,这个时候湖南本地的用户就可以直接从边缘服务器进行拉流播放了, 如果山东的用户需要观看直播就会先从山东本地的边缘服务器来获取,如果没有的话,就会从源站服务器进行获取播放。

三、大概原理

当用户播放边缘服务器的流时,边缘服务器看有没有缓存,若缓存了就直接将流发给客户端。 若没有缓存,则发起一路回源链接,从源站取数据源源不断放到自己的缓存队列。 也就是说, 多个客户端连接到边缘时,只有一路回源。这种结构在CDN是最典型的部署结构。

譬如北京源站, 在全国32个省每个省都部署了10台服务器,一共就有320台边缘, 假设每个省1台边缘服务器都有 2000用户观看,那么就有64万用户,每秒钟集群发送640Gbps数据; 而回源链接只有320个, 实现了大规模分发。

边缘edge服务器,实际上是解决大并发问题产生的分布式集群结构。SRS的边缘可以指定多个源站, 在源站出现故障时会自动切换到下一个源站,不影响用户观看,具有最佳的容错性,用户完全不会觉察。

对于边缘服务器,我们还可以支持SO_REUSEPORT,可以在服务器上启动多个Edge进程。

注意:SO_REUSEPORT功能需要Linux Kernel 3.9+,所以如果使用CentOS6你可能需要升级你的内核,推荐使用CentOS7。

首先,我们启动一个边缘服务器,侦听在1935:

./objs/srs -c conf/edge.conf

然后,在同一个服务器,再启动一个边缘服务器,也侦听在1935:

./objs/srs -c conf/edge2.conf

注意:当然这两个边缘服务器的pid文件路径要不同,否则会启动失败。

这样就启动了两个进程,都侦听在1935:

[root@bf2e88b31f9b trunk]# ps aux|grep srs
root       381  0.1  0.0  19888  5752 pts/2    S+   08:03   0:01 ./objs/srs -c conf/edge.conf
root       383  0.0  0.0  19204  5468 pts/1    S+   08:04   0:00 ./objs/srs -c conf/edge2.conf

[root@bf2e88b31f9b trunk]# lsof -p 381
srs     381 root    7u     IPv6  18835      0t0        TCP *:macromedia-fcs (LISTEN)
[root@bf2e88b31f9b trunk]# lsof -p 383
srs     383 root    7u     IPv6  17831      0t0        TCP *:macromedia-fcs (LISTEN)

接着,启动源站服务器,这两个边缘服务器从这个源站服务器取流:

./objs/srs -c conf/origin.conf 

最后,我们可以推流到源站或边缘,从任意边缘服务器拉流播放。

四、RTMP边缘集群部署的步骤。

假设服务器的IP是:192.168.1.170

1、编译完成srs程序

参照rtmp部署的步骤即可

2、编写SRS源站配置文件

将以下内容保存为文件,譬如conf/origin.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/origin.conf
listen              19350;
max_connections     1000;
pid                 objs/origin.pid;
srs_log_file        ./objs/origin.log;
vhost __defaultVhost__ {
}

3、编写SRS边缘配置文件

将以下内容保存为文件,譬如conf/edge.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/edge.conf
listen              1935;
max_connections     1000;
pid                 objs/edge.pid;
srs_log_file        ./objs/edge.log;
vhost __defaultVhost__ {
    cluster {
        mode            remote;
        origin          127.0.0.1:19350;
    }
}

4、启动SRS

./objs/srs -c conf/origin.conf &
./objs/srs -c conf/edge.conf &

5、测试验证

1.3.源站集群

一、简介

源站集群是源服务器的横向拓展,多个源站共同完成工作,适用于大批量的直播集群。

二、场景

假如现在需要在线10000个主播在线直播,此时一台源服务器最大能支持1000路直播流,还剩余了9000个流无法传输,那此时就需要将源服务器进行横向拓展来解决这个问题。

三、基本原理

为解决大量直播流的转发功能,单个服务器存在瓶颈,而边缘检测只是用于扩展本地的播放能力,不能解决流的转发能力,因此将多个源站服务器构成集群,此时边缘服务器播放拉流会在源站集群中进行跳转。

四、部署

RTMP源站集群部署的步骤,我们给出了一个例子,部署了两个源站做集群,还部署了一个边缘。 实际使用中,可以部署多个源站和多个边缘,形成源站集群。

vhost __defaultVhost__ {
    # The config for cluster.
    cluster {
        # The cluster mode, local or remote.
        #       local: It's an origin server, serve streams itself.
        #       remote: It's an edge server, fetch or push stream to origin server.
        # default: local
        mode            local;

        # For origin(mode local) cluster, turn on the cluster.
        # @remark Origin cluster only supports RTMP, use Edge to transmux RTMP to FLV.
        # default: off
        # TODO: FIXME: Support reload.
        origin_cluster      on;

        # For origin (mode local) cluster, the co-worker's HTTP APIs.
        # This origin will connect to co-workers and communicate with them.
        # please read: https://ossrs.net/lts/zh-cn/docs/v4/doc/origin-cluster
        # TODO: FIXME: Support reload.
        coworkers           127.0.0.1:9091 127.0.0.1:9092;
    }
}

mode: 集群的模式,对于源站集群,值应该是local。 origin_cluster: 是否开启源站集群。 coworkers: 源站集群中的其他源站的HTTP API地址。 Remark: 如果流不在本源站,会通过HTTP API查询其他源站是否有流。如果流其他源站,则返回RTMP302重定向请求到该源站。如果所有源站都没有流则返回错误。

Remark: 特别注意的是,如果流还没有开始推,那么服务器会返回失败,这点和源站没有在源站集群的行为不同。当源站独立工作时,会等待流推上来;当源站在源站集群中时,因为流可能不会推到本源站,所以等待流推上来没有意义。 ​
假设服务器的IP是:192.168.1.170

1、编译完成srs程序

参照rtmp部署的步骤即可

2、编写SRS源站A配置文件

将以下内容保存为文件,譬如conf/origin.cluster.serverA.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/origin.cluster.serverA.conf
listen              19350;
max_connections     1000;
daemon              off;
srs_log_tank        console;
pid                 ./objs/origin.cluster.serverA.pid;
http_api {
    enabled         on;
    listen          9090;
}
vhost __defaultVhost__ {
    cluster {
        mode            local;
        origin_cluster  on;
        coworkers       127.0.0.1:9091;
    }
}

2、编写SRS源站B配置文件

将以下内容保存为文件,譬如conf/origin.cluster.serverB.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/origin.cluster.serverB.conf
listen              19351;
max_connections     1000;
daemon              off;
srs_log_tank        console;
pid                 ./objs/origin.cluster.serverB.pid;
http_api {
    enabled         on;
    listen          9091;
}
vhost __defaultVhost__ {
    cluster {
        mode            local;
        origin_cluster  on;
        coworkers       127.0.0.1:9090;
    }
}

4、编写SRS边缘配置文件,从多个源站拉流,实现热备和负载均衡

将以下内容保存为文件,譬如conf/origin.cluster.edge.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/origin.cluster.edge.conf
listen              1935;
max_connections     1000;
pid                 objs/edge.pid;
daemon              off;
srs_log_tank        console;
vhost __defaultVhost__ {
    cluster {
        mode            remote;
        origin          127.0.0.1:19351 127.0.0.1:19350;
    }
}

Remark: 如果播放器支持RTMP302,当然可以直接播放源站的流,任意源站都能播放,如果流不在访问的源站,会返回RTMP302重定向到流所在的源站。

5、启动SRS

./objs/srs -c conf/origin.cluster.serverA.conf &
./objs/srs -c conf/origin.cluster.serverB.conf &
./objs/srs -c conf/origin.cluster.edge.conf &

6、测试验证

1.4.forward部署

一、简介 SRS可以将送到SRS的流转发给其他RTMP服务器,实现简单集群/热备功能,也可以实现一路流热备(譬如编码器由于带宽限制,只能送一路流到RTMP服务器,要求RTMP服务器能将这路流也转发给其他RTMP备用服务器,实现主备容错集群)。

二、场景

一台rtmp服务器在内网不能直接连接外网的设备,无法获取视频,但是内网播放器只能播放这台服务器的视频流,就需要一台服务器要一直推流到这台服务器中。

视频流的备份功能。

三、基本原理

利用转发的功能,将接收到的视频流从一台服务器转发到另一台。

四、部署

Forward就是SRS将流拷贝输出给其他的RTMP服务器,以SRS转发给SRS为例:

主SRS:Master, 编码器推流到主SRS,主SRS将流处理的同时,将流转发到备SRS 备SRS:Slave, 主SRS转发流到备SRS,就像编码器推送流到备用SRS一样。 我们的部署实例中,主SRS侦听1935端口,备SRS侦听19350端口。 1、编译完成srs程序

参照rtmp部署的步骤即可

2、编写主SRS配置文件

将以下内容保存为文件,譬如conf/forward.master.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/forward.master.conf
listen              1935;
max_connections     1000;
pid                 ./objs/srs.master.pid;
srs_log_tank        file;
srs_log_file        ./objs/srs.master.log;
vhost __defaultVhost__ {
    forward {
        enabled on;
        destination 127.0.0.1:19350;
    }
}

3、启动主SRS,主SRS将流转发到备SRS

./objs/srs -c conf/forward.master.conf

4、编写备SRS配置文件

将以下内容保存为文件,譬如conf/forward.slave.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/forward.slave.conf
listen              19350;
pid                 ./objs/srs.slave.pid;
srs_log_tank        file;
srs_log_file        ./objs/srs.slave.log;
vhost __defaultVhost__ {
}

5、启动备SRS,主SRS将流转发到备SRS

./objs/srs -c conf/forward.slave.conf

注意:启动srs后查看下srs是否启动成功,错误可以查看日志。

[winlin@dev6 srs]$ sudo netstat -anp|grep srs
tcp        0      0 0.0.0.0:1935                0.0.0.0:*                   LISTEN      7826/srs            
tcp        0      0 0.0.0.0:19350               0.0.0.0:*                   LISTEN      7834/srs

6、测试验证

2.HLS简介

HLS全称HTTP Live Streaming,顾名思义是一个基于HTTP的流媒体传输协议。是由苹果公司提出,附属于IPHONE软件系统的一部分。

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为主。

2.1单机部署

同RTMP部署

2.2集群部署

如何创建分发HLS的边缘集群,就像CDN一样分发HLS流。 假设服务器的IP是:192.168.1.170

1、编译完成srs程序

参照rtmp部署的步骤即可

2、编写SRS源站配置文件,生成HLS切片文件

将以下内容保存为文件,譬如conf/hls.origin.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/hls.origin.conf
listen              1935;
max_connections     1000;
daemon              off;
srs_log_tank        console;
http_server {
    enabled         on;
    listen          8080;
}
vhost __defaultVhost__ {
    hls {
        enabled         on;
    }
}

3、编写NGINX边缘配置文件,分发HLS文件

将以下内容保存为文件,譬如conf/hls.edge.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/hls.edge.conf
worker_processes  3;
events {
    worker_connections  10240;
}

http {
    # For Proxy Cache.
    proxy_cache_path  /tmp/nginx-cache levels=1:2 keys_zone=srs_cache:8m max_size=1000m inactive=600m;
    proxy_temp_path /tmp/nginx-cache/tmp; 

    server {
        listen       8081;
        # For Proxy Cache.
        proxy_cache_valid  404      10s;
        proxy_cache_lock on;
        proxy_cache_lock_age 300s;
        proxy_cache_lock_timeout 300s;
        proxy_cache_min_uses 1;

        location ~ /.+/.*\.(m3u8)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri$args;
            proxy_cache_valid  200 302  10s;
        }
        location ~ /.+/.*\.(ts)$ {
            proxy_pass http://127.0.0.1:8080$request_uri;
            # For Proxy Cache.
            proxy_cache srs_cache;
            proxy_cache_key $scheme$proxy_host$uri;
            proxy_cache_valid  200 302  60m;
        }
    }
}

4、启动SRS源站和NGINX边缘

nginx -c $(pwd)/conf/hls.edge.conf
./objs/srs -c conf/hls.origin.conf
Note: 请参考NGINX的说明下载和安装,只要是NGINX就可以,没有特别的要求。

5、测试验证

3.NGINX Edge Cluster

一、解决的问题 边缘集群(Edge Cluster)就是为了解决很多人观看的问题,可以支持非常多的人观看直播流。注意:

SRS Edge只支持直播流协议,比如RTMP或HTTP-FLV等 SRS Edge不支持HLS或DASH等切片的直播流,本质上它们不是流,就是文件分发。 SRS Edge不支持WebRTC的流分发,这不是Edge设计的目标,WebRTC有自己的集群方式,

HLS或DASH等切片的边缘集群一般基于NGINX实现,所以也叫NGINX Edge Cluster。

二、简介

NGINX边缘集群,本质上就是带有缓存的反向代理,也就是NGNIX Proxy with Cache。

+------------+          +------------+          +------------+          +------------+
+ FFmpeg/OBS +--RTMP-->-+ SRS Origin +--HLS-->--+ NGINX      +--HLS-->--+ Visitors   +
+------------+          +------------+          + Servers    +          +------------+
                                                +------------+          

4.WebRtc

1、简介

WebRTC是一个由Google发起的实时通讯解决方案,其中包含视频音频采集,编解码,数据传输,音视频展示等功能, 我们可以通过技术快速地构建出一个音视频通讯应用。 虽然其名为WebRTC,但是实际上它不光支持Web之间的音视频通讯,还支持Android以及IOS端, 此外由于该项目是开源的,我们也可以通过编译C++代码,从而达到全平台的互通。

2、场景

2、1 通过信令交换能力集和sdp,即支持哪些协议,编解码器,公网ip地址端口等基本信息。 2、2 客户端的连接方式,nat穿透,turn中继等方式。 2、3 相互发送音视频流,加不加密,网络异常的处理方案,udp等。 2、4 集群方式 mesh mcu sfu。

4.1.部署

1、配置文件

参考full.conf

rtc_server {                       # 全局的RTC服务器的配置
    enabled on;                    # 是否开启RTC服务器
    listen 8000;                   # 侦听RTC端口,注意是udp协议
    candidate $CANDIDATE;          # 服务器提供服务的ip地址,由于RTC比较特殊,必须配置这个地址
}

vhost rtc.vhost.srs.com {          # 虚拟服务器的配置
    rtc {
        enabled on;                # 是否开启RTC能力
        rtmp_to_rtc off;           # 是否开启rtmp转rtc
        rtc_to_rtmp off;           # 是否开启rtc转rtmp
        stun_timeout on;           # 会话超时时间
        nack on;                   # 丢包重传
        twcc on;                   # 拥塞控制
    }
}

Config::Candidate

Candidate 是服务器的备选地址,客户端可以连接的地址ip:por, 在sdp交换中,就有Candidate信息, 例如: 服务器回复的answer可能就是这样: type: answer, sdp: v=0 a=candidate:0 1 udp 2130706431 192.168.3.6 8000 typ hos generaion 0

上面的192.168.3.6 8000, 就是candidate listen这两个配置,即服务器的ip和端口 服务器的ip配置方式: 1、直接配置成固定的ip,比如: candidate: 192.168.3.6 2、使用ifconfig获取本机的内网ip,通过环境变量传递给srs,比如: candidate $CANDIDATE; 3、自动获取,先读取环境变量,然后获取本机网卡的ip,比如: candidate *; 支持任意ip,让服务器自己选择,先选公网ip,再先内网ip。 4、在url中通过?eip=x指定,比如: webrtc://192.168.3.6/live/livestream?eip=192.168.3.6 5、若API和SRS在同一台服务器,可以用API的hostname作为CANDIDATE。 由于webrtc推拉流之前,必须访问http api交换sdp,因此在http请求中的hostname一般就是srs的公网域名或者ip地址。

通过ifconfig获取本机ip

# For macOS
CANDIDATE=$(ifconfig en0 inet| grep 'inet '|awk '{print $2}')

# For CentOS
CANDIDATE=$(ifconfig eth0|grep 'inet '|awk '{print $2}')

# Directly set ip.
CANDIDATE="192.168.3.10"

2、设置环境变量然后启动srs

env CANDIDATE="192.168.3.10" \
    ./objs/srs -c conf/rtc.conf

用Docker方式运行SRS,设置环境变量的方法

export CANDIDATE="192.168.3.10"
    docker run --rm --env CANDIDATE=$CANDIDATE \
      -p 1935:1935 -p 8080:8080 -p 1985:1985 -p 8000:8000/udp \
      registry.cn-hangzhou.aliyuncs.com/ossrs/srs:4 \
      objs/srs -c conf/rtc.conf

export/set/env/declare 的区别 在 Linux 系统中,除了 export 之外,env、set 和 declare 这三个命令也可以显示 Shell 中的变量。那这四个命令有什么区别呢?

这个问题,我们需要从 Shell 变量说起。Shell 的变量,可以分为“环境变量”和“自定义变量”两种类型,两者的区别在于作用范围不同。环境变量可以在其进程的子进程中继续有效,而自定义变量的势力范围则无法延伸到其进程的子进程中。

好了,知道了环境变量和自定义变量的区别,我们正式开始介绍 export/env/set/declare 的区别: env:显示当前用户的环境变量,但不会显示其自定义变量。 export:功能同 env 一样,也是显示当前用户的环境变量,只不过该命令的输出是按变量名进行排序的。 declare:显示当前 Shell 中定义的所有变量,包括用户的环境变量和自定义变量,该命令的输出按变量名进行排序。 set:功能同 declare 一样,显示当前 Shell 中定义的所有变量,包括用户的环境变量和自定义变量。

根据上面的说明,我们可以得出下面的结论: env 和 export 显示的是环境变量。 set 和 declare 显示的是环境变量和自定义变量。

Mesh 多个客户端相互交互 MCU 星型,所有的业务处理都在服务端 SFU 星型,服务端只负责数据流的转发

One to One 一对一交互 Video Room 多人房间 Room to Live 多人房间让别人看到

5.HTTP-FLV

1、简介

所有的HTTP FLV流都是一个HTTP FLV地址,譬如:http://ossrs.net:8081/live/livestream.flv,但是,流的形式却至少有三种:

FLV文件,渐进式HTTP流。放一个文件到nginx目录,可以访问下载在播放器播放,这是HTTP FLV文件,也就是渐进式下载流。所谓渐进式下载,也就是用户观看时无法从未下载的地方开始看。

FLV伪流。一般说的HTTP FLV,比上面的渐进式流高级一点,譬如,一个120分钟的电影,作为渐进式流播放时,用户需要从60分钟开始看,如何支持呢? 因为nginx是当做文件下载的,无法直接跳转到第60分钟(nginx也不知道60分钟对应的字节偏移是多少呀)。 后来有人就支持这种跳着播放,通过指定时间服务器从指定的位置开始给流,这种支持flv?start=,就是http flv的伪流,本质上还是点播流。

FLV直播流。SRS所指的HTTP FLV流,是严格意义上的直播流,有RTMP的所有特征,譬如集群、低延迟、热备、GOP cache,而且有HTTP的优势,譬如302、穿墙、通用。 由于SRS内部实现了HTTP服务器,所以SRS是在边缘将RTMP流转换成HTTP流,SRS集群内部还是使用RTMP分发。 当前唯一将RTMP和HTTP协议都解析的服务器,目前只有SRS和nginx-rtmp,可惜nginx-rtmp没有实现这个流。

用一句话概括,SRS的HTTP FLV就是增强的RTMP,真正的实时流媒体分发。

2、场景

互联网流媒体实时领域,还是RTMP。HTTP-FLV和RTMP的延迟一样,因此可以满足延迟的要求。 穿墙:很多防火墙会墙掉RTMP,但是不会墙HTTP,因此HTTP FLV出现奇怪问题的概率很小。 调度:RTMP也有个302,可惜是播放器as中支持的,HTTP FLV流就支持302方便CDN纠正DNS的错误。 容错:SRS的HTTP FLV回源时可以回多个,和RTMP一样,可以支持多级热备。 通用:Flash可以播RTMP,也可以播HTTP FLV。自己做的APP,也都能支持。主流播放器也都支持http flv的播放。 简单:FLV是最简单的流媒体封装,HTTP是最广泛的协议,这两个到一起维护性很高,比RTMP简单多了。

5.1.部署

同rtmp部署

5.2.集群部署

本例子部署了三个SRS,侦听不同的端口(实际可以部署到不同的机器,侦听同一个端口),一个作为Origin源站,两个作为Edge边缘。 推RTMP流到源站或者边缘后,可以通过任何Edge观看,和RTMP的效果一样,集群的延迟在0.8-3秒。

1、编译完成srs程序

参照rtmp部署的步骤即可

2、编写SRS源站配置文件

将以下内容保存为文件,譬如conf/http.flv.live.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/http.flv.live.conf
listen              1935;
max_connections     1000;
http_server {
    enabled         on;
    listen          8080;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
        hstrs       on;
    }
}

3、编写SRS边缘配置文件

将以下内容保存为文件,譬如conf/http.flv.live.edge1.conf和conf/http.flv.live.edge2.conf,服务器启动时指定该配置文件(srs的conf文件夹有该文件)。

# conf/http.flv.live.edge1.conf
listen              19351;
max_connections     1000;
pid                 objs/srs.flv.19351.pid;
srs_log_file        objs/srs.flv.19351.log;
http_server {
    enabled         on;
    listen          8081;
    dir             ./objs/nginx/html;
}
vhost __defaultVhost__ {
    mode remote;
    origin 127.0.0.1;
    http_remux {
        enabled     on;
        mount       [vhost]/[app]/[stream].flv;
        hstrs       on;
    }
}

4、启动SRS

./objs/srs -c conf/http.flv.live.conf &
./objs/srs -c conf/http.flv.live.edge1.conf &
./objs/srs -c conf/http.flv.live.edge2.conf &

5、测试验证

6.SRT

1.简介 ​ SRT(Secure Reliable Transport,安全可靠传输)是一种用于超低(亚秒)延迟的实时音视频流及通用批量数据传输的传输协议。 SRT基于UDT协议,Haivision和Wowza合作成立了SRT联盟。SRT解决了复杂的传输时序问题,可以做到支持高吞吐量文件和超清视频的实时传输。 SRT是一种开源技术,其代码https://github.com/Haivision/srt。

2.特性

2.1.质量和高靠性

​解决网络质量问题,SRT都可以从严重的数据包丢失和抖动中恢复,确保视频流的完整性和质量。

2.2.低延迟

​为了适应用户的各种部署环境,因此SRT的流错误纠正策略是可配置的。由于SRT建立在UDP协议之上,解决了TCP协议传输延迟高的问题。

2.3.内容不敏感

​SRT在网络传输层运行,它可以传输任何类型的视频格式、编解码器、分辨率或帧速率。

2.4.使用交会模式轻松穿越防火墙

​SRT使用的握手过程支持出站连接,也就是只需要知道双方的公网IP地址,无需在防火墙中打开端口映射。

​另外,使用直接从源到目的地的连接,SRT可以减少延迟,消除中心瓶颈,并降低网络成本。

​双方发送源和目的端口完全一致,达到欺骗防火墙通过的目的,从而建立连接。存在如果在网络传输过程中端口被转换,无法连接的问题。

2.5.AES加密

​SRT使用世界各地政府和组织信任的128/192/256位AES加密,确保有价值的内容得到端到端的保护,不会被分发。

2.6.前向纠错(FEC)和包过滤器API

​包过滤器AP允许在发送网络数据包之前,在发送方对其进行自定义处理,并允许在从网络接收到网络数据包之后在接收方对其进行定制处理。

​用户可以以任何方式操作生成的数据包过滤器数据,例如用于自定义加密、数据包检查或在数据发送之前访问数据。

​创建的第一个插件是前向纠错(FEC),在某些使用情况下,它可以提供比自动重复请求(ARQ)稍低的延迟。此插件允许三种不同的模式:

​仅ARQ 重传丢失的数据包

​仅FEC 提供接收机侧FEC恢复所需的开销

​FEC和ARQ 重新传输FEC无法恢复的丢失数据包

2.7.无缝连接

​与管理网络SMPTE-2022-7类似,连接键合为SRT协议添加了无缝流保护和故障切换。该技术依赖于多个IP网络路径,以防止网络拥塞或中断导致实时视频流的故障中断,从而保持服务的连续性。

​该功能通过使用SRT v1.5中引入的套接字组来实现的。套接字组包含多个套接字,当正在使用的套接字发送一个故障信号后,组内其他套接字将接管它的操作。

目前支持两种模式:

​广播模式–在广播模式下,数据通过组中的所有成员链接冗余发送。如果其中一条链路出现故障或经历网络抖动和/或数据包丢失,则将通过组中的另一条链路接收丢失的数据。冗余分组在接收机侧被简单地丢弃。

​主/备模式–在主/备份模式下,一次仅使用一条(主)链路进行数据传输,而其他(备份)连接处于备用状态,以确保主链路出现故障时传输将继续。主/备份模式的目标是在可能的链路中断发生之前识别它,从而提供一个时间窗口,在该时间窗口内无缝切换到其中一个备份链路。

setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval)); setsockopt(sock_fd, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval));

SO_REUSEPORT 源码分析

内核为处于 LISTEN 状态的 socket 分配了大小为 32 哈希桶。监听的端口号经过哈希算法运算打散到这些哈希桶中,相同哈希的端口采用拉链法解决冲突。当收到客户端的 SYN 握手报文以后,会根据目标端口号的哈希值计算出哈希冲突链表,然后遍历这条哈希链表得到最匹配的得分最高的 Socket。对于使用 SO_REUSEPORT 选项的 socket,可能会有多个 socket 得分最高,这个时候经过随机算法选择一个进行处理。

假设有 127.0.0.1:2222、127.0.0.1:9998、10.211.55.17:9966、10.211.55.10:2222 这几个监听套接字,这几个套接字被哈希到同一个链表中,当有 127.0.0.1:2222 套接字的 SYN 包到来时,会遍历这个哈希链表,查找得分最高的两个 socket,然后通过随机选择其中的一个。

SO_REUSEPORT 与安全性

试想下面的场景,你的进程进程监听了某个端口,不怀好意的其他人也可以监听相同的端口来“窃取”流量信息,这种方式被称为端口劫持(port hijacking)。SO_REUSEPORT 在安全性方面的考虑主要是下面这两点。

1、只有第一个启动的进程启用了 SO_REUSEPORT 选项,后面启动的进程才可以绑定同一个端口。2、后启动的进程必须与第一个进程的有效用户ID(effective user ID)匹配才可以绑定成功。

SO_REUSEPORT 的应用 SO_REUSEPORT 带来了两个明显的好处:

实现了内核级的负载均衡 支持滚动升级(Rolling updates)

ss 是一个非常有用的命令,它的选项解释如下。

-t, –tcp 显示 TCP 的 socket -l, –listening 只显示 listening 状态的 socket,默认情况下是不显示的。 -n, –numeric 显示端口号而不是映射的服务名 -p, –processes 显示进程名 -e, –extended 显示 socket 的详细信息

2.8.访问控制(流ID)

​当需要向单个IP地址和UDP端口推送/拉取多个SRT流,使用流ID来区分本次推流/拉取的行为。

3.与常见传输格式比较:

目前互联网上的视频直播有两种:

​一种是基于RTMP协议的直播,这种直播方式上行推流使用RTMP协议,下行播放使用RTMP,HTTP+FLV或者HLS,直播延时一般大于3秒,广泛应用秀场、游戏、赛事和事件直播,满足了对交互要求不高的场景;

​另一种是WebRTC协议的直播,这种直播方式使用UDP的协议进行流媒体的分发,直播延时小于1秒,同时连接数一般小于10个,主要应用在视频通话、秀场连麦等应用场景。

​除了上述两种场景外,还有一种视频直播的场景,就是同时要求低延时和大并发的场景,比如赛事直播、股票信息同步、大班教育等。SRT可以很好地满足上述场景的要求。

SRT与目前市场上的大多数其他视频流传输格式(如RTMP、HLS和MPEG-DASH)。相比有几个特点:

SRT是一个开源解决方案,已经集成到多个平台和体系结构中,包括基于硬件的可移植解决方案和基于软件的云解决方案。

SRT可以在几毫秒到几秒的延时之间的连接上很好地工作。能处理长时间的网络延迟。 RT与负载无关。任何类型的视频或音频媒体,或者实际上任何可以使用UDP发送的其他数据元素,都与SRT兼容。支持多种流类型。

SRT发送支持多个并发流,多个不同的媒体流例如多个摄像机角度或可选音频轨道,可以通过在一个点对点链接上共享相同UDP端口和地址的并行SRT流发送。

SRT使用的握手过程支持出站连接,而不需要在防火墙中打开危险的永久外部端口,从而维护公司安全策略。增强防火墙遍历。

SRT端点建立了稳定的端到端延迟概要,消除了下游设备需要有自己的缓冲区来应对不断变化的信号延迟。信号时间准确。

2、部署

同rtmp部署

7.DASH

7.1.部署

同rtmp部署