webrtc(native C++)+srs(sfu)测延时200ms

关于peerconnection_client的分析参考:

邱国禄_conductor:https://blog.csdn.net/qiuguolu1108/article/details/120588302
邱国禄_PeerConnectionClient:https://blog.csdn.net/qiuguolu1108/article/details/120588283?spm=1001.2014.3001.5501
邱国禄_main window:https://blog.csdn.net/qiuguolu1108/article/details/120588257?spm=1001.2014.3001.5501
关于webrtc客户端代码编写参考:
基于WebRTC Native API实现SRS4.0客户端:https://zhuanlan.zhihu.com/p/381210049
关于srs的对sdp和lite-ice的过程参考:

srs4.0 webrtc 分析(三) 推流:https://blog.csdn.net/lcalqf/article/details/113487895
9、SRS4.0源代码分析之WebRTC服务总体介绍:https://blog.csdn.net/adkada1/article/details/120590921
10、SRS4.0源代码分析之WebRTC推流端处理:https://blog.csdn.net/adkada1/article/details/120590944
11、SRS4.0源代码分析之WebRTC拉流端处理:https://blog.csdn.net/adkada1/article/details/120590949

关于srs参考的lite-ice标准:
https://github.com/rtcdn/rtcdn-draftsrs的sdp在这个标准上又在json中加了几项key-value,下文会给出。
浏览器WebRTC的视频流怎么推流到流媒体服务器:https://www.zhihu.com/question/433069751/answers/updated这个连接中含有一个零声学院的视频《WebRTC-SRS4.0流媒体-ICE交互分析【1】》
SRS 4.0配置支持WebRTC推拉流:https://zhuanlan.zhihu.com/p/371944795分析了web端与srs交互的api,这个下文也会给出,这个也可以在srs的web端demo:http://localhost:8080/players/rtc_player.html?autostart=true界面,按f12进入console界面查看
https://segmentfault.com/a/1190000024533847这个跟上面差不多都是web端的实现。
这个标准不是srs采用的,但也是行业知名标准,WHIP:
https://blog.csdn.net/sweibd/article/details/124552793
关于lite-ice这个交互方式参考:
【网络通信 – WebRTC】WebRTC 基础知识 – ICE 交互总结:https://blog.csdn.net/qq_27788177/article/details/119456945
Webrtc ICE 框架:https://xie.infoq.cn/article/50495aca8344e5d635b3a7ae2

注意srs的webrtc流,视频编码只支持H.264和AV1两种;默认支持H.264,AV1需要在请求Url上加上参数?codec=av1,而webrtc编译时默认支持vp8,vp9,AV1,前两个是google主推的编码格式,vp8跟h264对等,但压缩率没有h264高,如果要连接srs还需在编译时启用h264,即编译时添加:

rtc_use_h264=true

webrtc默认支持opus,而srs的webrtc流仅仅支持opus,因此两者音频用opus编码。
WebRTC 使用 OpenH264 来做 encoder (见 h264_encoder_impl.cc)。使用 ffmpeg 来做 decoder,视频编码webrtc所支持的编码方式只有4种,vp8,vp9,h264,av1。如果Codec选择为H264的时候, FEC是被关闭的,因为webrtc时为vp8/9打造的,h264是后来添加的,WebRTC使用是不支持硬件加速的OpenH264。

srs,cpp_media_server,mediasoup都是lite-ice模式,何为lice-ice模式,简单说就是lite端不会作ip多类型收集,只会收集host ip也就是ifconfig会出现的ip,并且lice端不会作连同性检测,只会等待stun BIND request,然后作stun BIND response返回。何为连通信检测,stun BIND request这个请求就是连通性检测,因为在此之前full端已经通过sdp获得了lite端的host ip了(lite端如srs会把ip放在sdp中发给full端,下文有介绍),stun BIND request就是向这个ip发送,如果能接收到,说明full端已经可以访问到lite端了,这条链路就可以建立通,后面音视频传输就用这条道路。srs集成了stun服务器,所以当stun BIND request发给它时,它同时获得了webrtc客户端的公网ip+port,因此双方都拿到了对方的公网ip,可能会有小伙伴问,full端下面这几个ip还做交互吗,除了Host Candidate其他并不是必须,并且不是全部收集了再去作连同性检测,而是收集到一个就去做连通性检测,如果只有host ip那么就只使用这一类ip作连通性检测。因此若webrtc客户端与srs进行lite-ice交互时,webrtc客户端并不必要另外设置stun,和turn服务器,信令服务器。

candidate 类型
Host Candidate :由本地的物理网卡或逻辑网卡上生成的 candidate。
Srflx candidate:端发送 Binding 请求到 STUN/TURN server 经过 NAT 时,由 NAT 上分配的地址和端口生成的 candidate。
Relayed Candidate:端发送 Allocate 请求到 TURN server ,由 TURN server 用于中继的地址和端口(这个可能是本机或 NAT 地址)生成的 candidate。
Peer Reflexive Candidate:端发送 Binding 请求到对等端经过 NAT 时,由 NAT 上分配的地址和端口生成的 candidate。

srs作为webrtc的服务端是sfu模型,即可以实现一推多拉的分发模式。
首选说一下webrtc的peerconnection_client+peerconnection_server是full-ice模型
peerconnection_client+coturn+peerconnection_client是full-ice
srs+webrtc客户端是lite-ice模型
对于lite-ice模型交互是这样的
webrtc客户端发送sdp到srs
srs发送sdp到webrtc客户端
webrtc客户端发送stun BIND request到srs
srs发送stun BIND response到webrtc客户端
webrtc发送的sdp(完整的在文末):

api: "http://localhost:1985/rtc/v1/publish/"
clientip: null
sdp: "v=0\r\no=- 509389852384............"
streamurl: "webrtc://localhost/live/livestream"
tid: "4cb16d8"

srs返回的sdp:

code: 0
sdp: "v=0\r\no=SRS/5.0.28(Leo) 94199........."
server: "vid-568t833"
sessionid: "b2x9b68g:dt89"
simulator: "http://localhost:1985/rtc/v1/nack/"

srs返回的sdp,在sdp含有candidate,其中包含srs的ip和端口

candidate:1 1 udp 2130706431 192.168.50.95 8000 typ host generation 0

webrtc拿到这个ip后开始作连通信检测,也就是发送stun BIND request,srs接收到后开始返回stun BIND response,并启动与webrtc的DTLS交互,然后两者建立连接,进行音视频流的交互。

注意lite-ice模式下,lite端也就是srs端并不做多个candidate的收集,只会把host ip传送出去,因此要主动暴露公网ip,不然srs会用主机所在公网的局域网的ip,在conf/rtc.conf中,具体配置如下:

rtc_server {
    
    
    enabled on;
    listen 8000; # UDP port
    # @see https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate
    candidate 139.129.91.106;#这个地方改成公网ip,srs会把这个ip放在sdp中交给webrtc客户端,或者设置环境env CANDIDATE="192.168.3.10"
}

以上配置参考官网:
https://github.com/ossrs/srs/wiki/v4_CN_WebRTC#config-candidate

注意:用conductor类时应重写以下两个函数:
#include “rtc_base/ref_count.h”//rtc的namespace在这个文件中定义
rtc::RefCountReleaseStatus Release() const {};
void AddRef() const {};

http访问srs,笔者使用的是curl库,json使用nlohmann::json。
编译好json库后,将json.hpp放入src/rtc_base中,在头文件中引用方式:

#include "rtc_base/json.hpp"
#include "curl/curl.h"//这里引用的是/usr/include/x86_64-linux-gnu/curl/curl.h
using json = nlohmann::json;

curl库用的是:

libcurl-gnutls.so.4 => /lib/x86_64-linux-gnu/libcurl-gnutls.so.4 (0x00007fb9cb50f000)

curl的安装:
//需要执行这个,ubuntu20自带的推流出现接收不到流的问题。

sudo apt-get install curl

如何新建webrtc,将curl库添加到webrtc中参考:webrtc新建工程

方案:
本地webrtc客户端推流./srsconductor
阿里云139.129.91.106运行srs: ./objs/srs -c conf/rtc.conf
本地浏览器网页拉流:http://localhost:8080/players/rtc_player.html?autostart=true
测试得延时大概200ms
在这里插入图片描述

mediasoup附带mediasoup-client(JavaScript库)和libmediasoupclient(C ++库),用于构建使用统一API在任何浏览器或设备中运行的应用程序。
chrome浏览器打开以下网址,这个是webrtc的监控界面,有各种信息。
chrome://webrtc-internals/
firefox的webrtc控制界面:
about:webrtc
srs的控制台:
https://ossrs.net/releases/

参考:
peerconnection_client实现srs推拉流
sfu原理
webrtc博客系列:62篇

webrtc目标:使用webrtc.a api连接srs,源切换,弱网优化。
获取本地ip对应的公网ip+端口的映射。
https://webrtc.github.io/samples/src/content/peerconnection/trickle-ice/

webrtc sfu服务器 pli fec jitter已实现,simulcast未实现
https://github.com/runner365/cpp_media_server

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述在这里插入图片描述在这里插入图片描述

api: "http://localhost:1985/rtc/v1/publish/"
clientip: null
sdp: "v=0\r\no=- 5093898523842032748 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=extmap-allow-mixed\r\na=msid-semantic: WMS\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111 63 103 104 9 0 8 106 105 13 110 112 113 126\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:dt89\r\na=ice-pwd:dQfh1iNMgBD6wpH/MmZfgmQL\r\na=ice-options:trickle\r\na=fingerprint:sha-256 30:34:D0:D1:60:41:90:BC:BD:B5:2E:07:6C:2D:A6:BE:CD:2D:BC:2B:23:85:17:51:7B:E2:C0:E7:CA:AD:AD:F9\r\na=setup:actpass\r\na=mid:0\r\na=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=sendonly\r\na=msid:- 05f60539-6830-4d33-80d4-3102ad4b880f\r\na=rtcp-mux\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=rtpmap:63 red/48000/2\r\na=fmtp:63 111/111\r\na=rtpmap:103 ISAC/16000\r\na=rtpmap:104 ISAC/32000\r\na=rtpmap:9 G722/8000\r\na=rtpmap:0 PCMU/8000\r\na=rtpmap:8 PCMA/8000\r\na=rtpmap:106 CN/32000\r\na=rtpmap:105 CN/16000\r\na=rtpmap:13 CN/8000\r\na=rtpmap:110 telephone-event/48000\r\na=rtpmap:112 telephone-event/32000\r\na=rtpmap:113 telephone-event/16000\r\na=rtpmap:126 telephone-event/8000\r\na=ssrc:1319553019 cname:nj97xMw+wQSd5t1Z\r\na=ssrc:1319553019 msid:- 05f60539-6830-4d33-80d4-3102ad4b880f\r\na=ssrc:1319553019 mslabel:-\r\na=ssrc:1319553019 label:05f60539-6830-4d33-80d4-3102ad4b880f\r\nm=video 9 UDP/TLS/RTP/SAVPF 96 97 98 99 100 101 127 121 125 107 108 109 124 120 123 119 35 36 41 42 114 115 116\r\nc=IN IP4 0.0.0.0\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:dt89\r\na=ice-pwd:dQfh1iNMgBD6wpH/MmZfgmQL\r\na=ice-options:trickle\r\na=fingerprint:sha-256 30:34:D0:D1:60:41:90:BC:BD:B5:2E:07:6C:2D:A6:BE:CD:2D:BC:2B:23:85:17:51:7B:E2:C0:E7:CA:AD:AD:F9\r\na=setup:actpass\r\na=mid:1\r\na=extmap:14 urn:ietf:params:rtp-hdrext:toffset\r\na=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time\r\na=extmap:13 urn:3gpp:video-orientation\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=extmap:5 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay\r\na=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/video-content-type\r\na=extmap:7 http://www.webrtc.org/experiments/rtp-hdrext/video-timing\r\na=extmap:8 http://www.webrtc.org/experiments/rtp-hdrext/color-space\r\na=extmap:4 urn:ietf:params:rtp-hdrext:sdes:mid\r\na=extmap:10 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id\r\na=extmap:11 urn:ietf:params:rtp-hdrext:sdes:repaired-rtp-stream-id\r\na=sendonly\r\na=msid:- 41d15f84-b528-4061-9f55-f255e6be9456\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:96 VP8/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 transport-cc\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtpmap:97 rtx/90000\r\na=fmtp:97 apt=96\r\na=rtpmap:98 VP9/90000\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 transport-cc\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=fmtp:98 profile-id=0\r\na=rtpmap:99 rtx/90000\r\na=fmtp:99 apt=98\r\na=rtpmap:100 VP9/90000\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 transport-cc\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=fmtp:100 profile-id=2\r\na=rtpmap:101 rtx/90000\r\na=fmtp:101 apt=100\r\na=rtpmap:127 H264/90000\r\na=rtcp-fb:127 goog-remb\r\na=rtcp-fb:127 transport-cc\r\na=rtcp-fb:127 ccm fir\r\na=rtcp-fb:127 nack\r\na=rtcp-fb:127 nack pli\r\na=fmtp:127 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f\r\na=rtpmap:121 rtx/90000\r\na=fmtp:121 apt=127\r\na=rtpmap:125 H264/90000\r\na=rtcp-fb:125 goog-remb\r\na=rtcp-fb:125 transport-cc\r\na=rtcp-fb:125 ccm fir\r\na=rtcp-fb:125 nack\r\na=rtcp-fb:125 nack pli\r\na=fmtp:125 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtpmap:107 rtx/90000\r\na=fmtp:107 apt=125\r\na=rtpmap:108 H264/90000\r\na=rtcp-fb:108 goog-remb\r\na=rtcp-fb:108 transport-cc\r\na=rtcp-fb:108 ccm fir\r\na=rtcp-fb:108 nack\r\na=rtcp-fb:108 nack pli\r\na=fmtp:108 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:109 rtx/90000\r\na=fmtp:109 apt=108\r\na=rtpmap:124 H264/90000\r\na=rtcp-fb:124 goog-remb\r\na=rtcp-fb:124 transport-cc\r\na=rtcp-fb:124 ccm fir\r\na=rtcp-fb:124 nack\r\na=rtcp-fb:124 nack pli\r\na=fmtp:124 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtpmap:120 rtx/90000\r\na=fmtp:120 apt=124\r\na=rtpmap:123 H264/90000\r\na=rtcp-fb:123 goog-remb\r\na=rtcp-fb:123 transport-cc\r\na=rtcp-fb:123 ccm fir\r\na=rtcp-fb:123 nack\r\na=rtcp-fb:123 nack pli\r\na=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d001f\r\na=rtpmap:119 rtx/90000\r\na=fmtp:119 apt=123\r\na=rtpmap:35 H264/90000\r\na=rtcp-fb:35 goog-remb\r\na=rtcp-fb:35 transport-cc\r\na=rtcp-fb:35 ccm fir\r\na=rtcp-fb:35 nack\r\na=rtcp-fb:35 nack pli\r\na=fmtp:35 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=4d001f\r\na=rtpmap:36 rtx/90000\r\na=fmtp:36 apt=35\r\na=rtpmap:41 AV1/90000\r\na=rtcp-fb:41 goog-remb\r\na=rtcp-fb:41 transport-cc\r\na=rtcp-fb:41 ccm fir\r\na=rtcp-fb:41 nack\r\na=rtcp-fb:41 nack pli\r\na=rtpmap:42 rtx/90000\r\na=fmtp:42 apt=41\r\na=rtpmap:114 red/90000\r\na=rtpmap:115 rtx/90000\r\na=fmtp:115 apt=114\r\na=rtpmap:116 ulpfec/90000\r\na=ssrc-group:FID 3785714711 1665347706\r\na=ssrc:3785714711 cname:nj97xMw+wQSd5t1Z\r\na=ssrc:3785714711 msid:- 41d15f84-b528-4061-9f55-f255e6be9456\r\na=ssrc:3785714711 mslabel:-\r\na=ssrc:3785714711 label:41d15f84-b528-4061-9f55-f255e6be9456\r\na=ssrc:1665347706 cname:nj97xMw+wQSd5t1Z\r\na=ssrc:1665347706 msid:- 41d15f84-b528-4061-9f55-f255e6be9456\r\na=ssrc:1665347706 mslabel:-\r\na=ssrc:1665347706 label:41d15f84-b528-4061-9f55-f255e6be9456\r\n"
streamurl: "webrtc://localhost/live/livestream"
tid: "4cb16d8"

srs返回的sdp

code: 0
sdp: "v=0\r\no=SRS/5.0.28(Leo) 94199418049712 2 IN IP4 0.0.0.0\r\ns=SRSPublishSession\r\nt=0 0\r\na=ice-lite\r\na=group:BUNDLE 0 1\r\na=msid-semantic: WMS live/livestream\r\nm=audio 9 UDP/TLS/RTP/SAVPF 111\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:b2x9b68g\r\na=ice-pwd:0ox3y9tjo0g60947fcd4381655g0t650\r\na=fingerprint:sha-256 E2:D9:ED:63:92:AD:C8:4E:BE:29:06:26:00:A4:2C:AF:9E:6D:2F:BB:1E:01:7B:01:F9:C4:62:52:DE:95:6E:5F\r\na=setup:passive\r\na=mid:0\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:111 opus/48000/2\r\na=rtcp-fb:111 transport-cc\r\na=fmtp:111 minptime=10;useinbandfec=1\r\na=candidate:0 1 udp 2130706431 192.168.100.76 8000 typ host generation 0\r\na=candidate:1 1 udp 2130706431 192.168.50.95 8000 typ host generation 0\r\nm=video 9 UDP/TLS/RTP/SAVPF 108 114\r\nc=IN IP4 0.0.0.0\r\na=ice-ufrag:b2x9b68g\r\na=ice-pwd:0ox3y9tjo0g60947fcd4381655g0t650\r\na=fingerprint:sha-256 E2:D9:ED:63:92:AD:C8:4E:BE:29:06:26:00:A4:2C:AF:9E:6D:2F:BB:1E:01:7B:01:F9:C4:62:52:DE:95:6E:5F\r\na=setup:passive\r\na=mid:1\r\na=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=recvonly\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:108 H264/90000\r\na=rtcp-fb:108 transport-cc\r\na=rtcp-fb:108 nack\r\na=rtcp-fb:108 nack pli\r\na=fmtp:108 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtpmap:114 red/90000\r\na=candidate:0 1 udp 2130706431 192.168.100.76 8000 typ host generation 0\r\na=candidate:1 1 udp 2130706431 192.168.50.95 8000 typ host generation 0\r\n"
server: "vid-568t833"
sessionid: "b2x9b68g:dt89"
simulator: "http://localhost:1985/rtc/v1/nack/"

猜你喜欢

转载自blog.csdn.net/weixin_43466192/article/details/124294150