如何在FreeSWITCH中对接SRS

SRS是一个简单、高效的优秀的开源实时音视频服务器,支持 RTMP/WebRTC/HLS/HTTP-FLV/SRT/MPEG-DASH/GB28181、Linux/Windows/macOS、X86_64/ARMv7/AARCH64/M1/RISCV/LOONGARCH/MIPS 等协议和技术。

背景

FreeSWITCH是一个开源的软交换平台和MCU,而SRS是一个开源的实时音视频服务器和SFU。很久之前通过RTMP对接过SRS。现在SRS已支持WebRTC以及WHIP协议,在SRS创始人winlin的推动下,我们开始了相关的对接工作。

为什么要对接?因为FreeSWITCH和SRS各有所长。这就像大家经常问到的问题一样——SRS是否能实现MCU呢?FreeSWITCH是否能实现SFU功能?其实答案都是一样的——能,但是为什么要实现?理论上,只要有足够的if-else,任何功能都可以实现,但任何实现都需要考虑实现成本和维护成本。其实从漫长的软件生命周期来说,开源软件的生命周期还是比较长的,相对而言,软件的维护成本比开发成本更高。SRS在级联、直播、低延迟直播等场景已经做得很好了,而且还有Janus、Kurento、MediaSoup、Poin等各种SFU,FreeSWITCH再去做意义就不是很大,同理,SRS本身也不是很有必要自己实现一个MCU。各自把自己擅长的部分做好。

架构和流程

FreeSWITCH相当于传统的软交换系统和MCU,一个SDP可以支持双向的推拉流。而SRS的推拉流是分开的,推和拉分别需要一个SDP。

SRS和FreeSWITCH都是服务器端的软件,因此,谁从谁推拉流就有两种实现方式。

FreeSWITCH从SRS推拉流

FreeSWITCH作为客户端向SRS推流,从SRS拉流。如下图。

其中,红色代表推流,蓝色代表拉流,黑色是双向流。

SRS从FreeSWITCH推拉流

SRS从FreeSWITCH推拉流 FreeSWITCH也支持WHIP协议,但SRS尚未实现客户端模式的推拉流。

启动SRS

启动镜像:

export CANDIDATE="192.168.x.x"
docker run --rm -it -d --name srs -p 1935:1935 -p 1985:1985 -p 8080:8080 --env CANDIDATE=$CANDIDATE -p 8000:8000/udp ossrs/srs:6 ./objs/srs -c conf/docker.conf

打开 http://localhost:8080/ 可以查看SRS的Web页面,上面有推拉流相关的Demo。一般使用livestream这个流进行演示。

注意: SRS在6.0.52以下的版本中有个Bug会导致Crash,参见 https://github.com/ossrs/srs/pull/3591

如果你不使用Docker,也可以使用以下命令自行编译运行SRS:

git clone -b develop https://gitee.com/ossrs/srs.git &&
cd srs/trunk && ./configure && make && ./objs/srs -c conf/srs.conf

在Windwows页面推流

如果在使用Windows页面使用localhost推流,需要在操作系统做如下配置:

查看本地设置netsh.exe interface portproxy show all

# 设置
netsh.exe interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=8080 connectaddress=x.x.0.1 connectport=8080
netsh.exe interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=1985 connectaddress=x.x.0.1 connectport=1985
netsh.exe interface portproxy add v4tov4 listenaddress=127.0.0.1 listenport=8000 connectaddress=x.x.0.1 connectport=8000

# 清除
netsh.exe interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=8080
netsh.exe interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=1985
netsh.exe interface portproxy delete v4tov4 listenaddress=127.0.0.1 listenport=8000

启动FreeSWITCH

在此,我们使用小樱桃团队维护的FreeSWITCH代码分支,官方的FreeSWITCH由于缺少对RTP Bundle的支持无法与SRS对接。SRS要求媒体流必须以Bundle形式收发。详见补丁

使用以下命令下载和编译小樱桃团队维护的FreeSWITCH代码:

git clone https://github.com/rts-cn/xswitch.git
# 或使用国内镜像
# git clone https://gitee.com/rts-cn/xswitch.git 
cd xswitch
./bootstrap.sh 
./configure 
make 
make install

在终端输入freeswitch -nc -nonat即可将FreeSWITCH运行在后台,然后输入fs_cli,即可启动客户端。

安装mod_srs

可以在这里找到mod_srs模块,里面有相关的安装步骤。

打开fs_cli后,在其终端输入load mod_srs命令,即可将该模块加载到FreeSWITCH中,出现+Ok即表示模块加载成功。

srs Endpoint

FreeSWITCH中实现了一个srs Endpoint,除FreeSWITCH标准Endpoint参数外,还支持如下参数:

  • video_use_audio_ice:在Bundle模式,视频使用音频的ICE绑定信息。
  • rtp_payload_space:指定视频的RTP载荷值,不指定有时候会有冲突。
  • absolute_codec_string:音视频编码,一般为OPUS,H264,在呼叫字符串中使用时其中的逗号要使用\转义。
  • url:SRS 推拉流 URL。

其中url为必选参数,其他参数为可选项。

FreeSWITCH推流到SRS

FreeSWITCH是一个软交换平台和MCU。SRS对接在FreeSWITCH内实现为一个Endpoint。

首先你可以使用一个简单的命令完成推流,从本地mp4文件中读取视频流:

bgapi originate {url=http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream}srs/auto_answer &playback(/tmp/test.mp4)

上面的有些参数我们进行了默认配置,如果你想对相关参数进行自定义的配置,可以参考如下的命令:

bgapi originate {video_use_audio_ice=true,rtp_payload_space=106,absolute_codec_string=OPUS\,H264,url=http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream}srs/auto_answer &playback(/tmp/test.mp4)

呼叫一个null Channel,桥接到SRS推流:

bgapi originate {null_video_codec=H264}null/1234 &bridge({video_use_audio_ice=true,rtp_payload_space=106,absolute_codec_string=OPUS\,H264,url=http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream}srs/auto_answer)

如果你手上有SIP视频话机,可以将一个视频话机(如1006)的视频流推给SRS,如:

bgapi originate user/1006 &bridge({video_use_audio_ice=true,rtp_payload_space=106,absolute_codec_string=OPUS\,H264,url=http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream}srs/auto_answer)

除上述命令外,你也可以直接在视频话机上发起呼叫。呼叫前确保FreeSWITCH中有相应的路由。如,在FreeSWITCH中,添加一个dialplan extension:

<extension name="srs">
    <condition field="destination_number" expression="^livestream$">
        <action application="bridge" data="{video_use_audio_ice=true,rtp_payload_space=106,absolute_codec_string=OPUS\,H264,url=http://localhost:1985/rtc/v1/whip/?app=live&stream=livestream}srs/auto_answer"/>
    </condition>
</extension>

直接使用视频话机呼叫livestream,可以直接推流到SRS的livestream流。

可以通过以下方法在SRS侧观看视频流:

WHEP Play:http://localhost:1985/rtc/v1/whip-play/?app=live&stream=livestream

通过RTC播放器可以查看拉流效果:webrtc://localhost/live/livestream

推流结果如下:

推流结果

FreeSWITCH拉流

  • RTC推流到: webrtc://localhost/3000/livestream
  • WHIP Publish:http://localhost:1985/rtc/v1/whip/?app=3000&stream=livestream

可以在FreeSWITCH中使用命令拉流到视频会议,其中3000是视频会议号:

conference 3000 bgdial {video_use_audio_ice=true,rtp_payload_space=106,absolute_codec_string=OPUS\,H264,url=http://localhost:1985/rtc/v1/whip-play/?app=3000&stream=livestream}srs/auto_answer

其他

以上假设你已经熟悉FreeSWITCH的各种操作,如果你还不熟悉FreeSWITCH,可以先从XSwitch上手,后者提供了Docker及Web管理界面,开箱即用,社区版是可以免费使用的。另有一篇如何在XSwitch中使用SRS 供参考。

小樱桃维护的FreeSWITCH代码分支,目前来看不大可能合并到官方的FreeSWITCH中,因此,如果你想使用开源的FreeSWITCH与SRS对接,可以使用小樱桃团队维护的FreeSWITCH代码分支,或使用XSwitch

有任何问题,欢迎给我们反馈,或与我们讨论

参考: