WebRTC学习笔记五SDP(SessionDescriptionProtocol)
SDP里面内容虽然很多,但是条理很清楚。SDP值为字符串,通过换行符生成一行一行的SDP报文,所有行可分为三类:全局行、音频行、视频行 v - Version,版本,版本,应等于0 o - Origin,源,包含一个唯一ID,用于重新协商 s - Session Name,会话名称,应等于- t - Timing,时间,应等于0 0 m - Media Description,媒体描述,下面有详细说明 a - Attribute,属性,一个自由文本字段,这是WebRTC中最常见的行 c - Connection Data,连接数据,应等于IN IP4 0.0.0.0 一、全局行
v=0
sdp版本号,一直为0,rfc4566规定
o=- 7017624586836067756 2 IN IP4 127.0.0.1 o=
各字段含义如下: username:发起者的用户名,不允许存在空格,如果应用不支持用户名,则为-。 sess-id:会话id,由应用自行定义,规范的建议是NTP(Network Time Protocol)时间戳。 sess-version:会话版本,用途由应用自行定义,只要会话数据发生变化时(比如编码),sess-version随着递增就行。同样的,规范的建议是NTP时间戳。 nettype:网络类型,比如IN表示Internet。 addrtype:地址类型,比如IP4、IV6 unicast-address:域名,或者IP地址。
s=
会话名,没有的话使用 - 代替
t=0 0
它给出了开始和结束时间。 当它们被设置为0时,意味着会话不受特定时间限制,换句话说,它在任何时候都是永久有效的。
a=group:BUNDLE audio video
BUNDLE分组建立了SDP中包含的几个媒体线之间的关系,通常是音频和视频。在WebRTC中,它用于在相同的RTP会话中复用多个媒体流。 在这种情况下,浏览器提供多路复用音频和视频,但另一方也必须支持和接受。 如果没有这一行,音视频,数据就会分别单独用一个udp端口来发送
a=msid-semantic: WMS h1aZ20mbQB0GSsq0YxLfJmiYWE9CBfGch97C
WMS是WebRTC Media Stream简称,这一行定义了本客户端支持同时传输多个流,一个流可以包括多个track, 一般定义了这个,后面a=ssrc这一行就会有msid,mslabel等属性 二、视频行2.1 媒体描述
m=video 60372 UDP/TLS/RTP/SAVPF 100 101 116 117 96
m=video说明本会话包含音频,60372代表视频使用端口60372来传输,但是在webrtc中一现在一般不使用,如果设置为0,代表不传输音频, UDP/TLS/RTP/SAVPF是表示用户来传输视频支持的协议,udp,tls,rtp代表使用udp来传输rtp包,并使用tls加密SAVPF代表使用srtcp的反馈机制来控制通信过程, 后台100 101 116 117 96表示本会话视频支持的编码。 m= ...
其中: media:媒体类型。包括 video、audio、text、application、message等。 port:传输媒体流的端口,具体含义取决于使用的网络类型(在c=中声明)和使用的协议(proto,在m=中声明)。 proto:传输协议,具体含义取决于c=中定义的地址类型,比如c=是IP4,那么这里的传输协议运行在IP4之上。比如: UDP:传输层协议是UDP。 RTP/AVP:针对视频、音频的RTP协议,跑在UDP之上。 RTP/SAVP:针对视频、音频的SRTP协议,跑在UDP之上。 fmt:媒体格式的描述,可能有多个。根据 proto 的不同,fmt 的含义也不同。比如 proto 为 RTP/SAVP 时,fmt 表示 RTP payload 的类型。如果有多个,表示在这次会话中,多种payload类型可能会用到,且第一个为默认的payload类型。 举例,下面表示媒体类型是视频,采用SRTP传输流媒体数据,且RTP包的类型可能是122、102...119,默认是122。 m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119
对于 RTP/SAVP,需要注意的是,payload type 又分两种类型: 静态类型:参考 RTP/AVP audio and video payload types。 动态类型:在 a=fmtp: 里进行定义。( a= 为附加属性,见后面小节)
举例,下面的SDP中: 对于audio,111 是动态类型,表示 opus/48000/2 。 对于video,122 是动态类型,表示 H264/90000 。 m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 126 a=rtpmap:111 opus/48000/2 m=video 9 UDP/TLS/RTP/SAVPF 122 102 100 101 124 120 123 119 a=rtpmap:122 H264/90000
【腾讯文档】FFmpegWebRTCRTMPRTSPHLSRTP播放器-音视频流媒体高级开发-资料领取
FFmpegWebRTCRTMPRTSPHLSRTP鎾斁鍣�-闊宠棰戞祦濯掍綋楂樼骇寮€鍙�-璧勬枡棰嗗彇2.2 连接数据(c=)
c=IN IP4 217.130.243.155 c=
每个SDP至少需要包含一个会话级别的c=字段,或者在每个媒体描述后面各包含一个c=字段。(媒体描述后的c=会覆盖会话级别的c=) nettype:网络类型,比如IN,表示 Internet。 addrtype:地址类型,比如IP4、IP6。 connection-address:如果是广播,则为广播地址组;如果是单播,则为单播地址;
举例01: c=IN IP4 224.2.36.42/127
举例02: c=IN IP4 host.anywhere.com2.3 属性(a=)
a=rtcp:64891 IN IP4 217.130.243.155 a= | :
属性(attribute)是扩展SDP的主要手段,分为会话级属性和媒体级属性:
(a)会话级属性:添加在第一个媒体描述之前,传达的信息适用于整个会议而不是单个媒体。 a=group:BUNDLE audio video 通过mid标识符把多个媒体属性连接起来; a=msid-semantic: WMS ma 表示是webrtc媒体流(Webrtc Media Streams);
(b)媒体级属性:媒体描述中添加有关媒体流的信息。 a=mid:audio 上述BUNDLE中用到的媒体标识; a=msid:ma ta 连接不同的媒体描述,使用相同的MediaStreams; a=sendonly 表示媒体发送端,其他类型:recvonly,sendrecv,inactive; a=rtcp:9 IN IP4 0.0.0.0 用来传输rtcp地地址和端口; a=rtcp-mux 表示rtp,rtcp包使用同一个端口来传输; a=ice-xxx:xxx ice协商过程中的安全验证信息; a=fingerprint:xxx 表示dtls协商过程中需要的认证信息; a=setup:actpass 表示本客户端在dtls协商过程中,可以做客户端也可以做服务端; a=rtpmap:111 opus/48000/2 负载类型111,编码格式opus,48000是时钟,2是通道数; a=rtcp-fb:111 nack 支持丢包重传; a=rtcp-fb:111 nack pli 支持关键帧丢包重传; a=rtcp-fb:111 transport-cc 表示opus编码支持使用rtcp来控制拥塞; a=fmtp:111 minptime=10;useinbandfec=1;maxplaybackrate=16000 对opus编码可选的补充说明,minptime代表最小打包时长是10ms,useinbandfec=1代表使用opus编码内置fec特性; a=ssrc:1370113029 cname:NMediaAudio cname用来标识一个数据源,ssrc当发生冲突时可能会发生变化,但是cname不会发生变化,也会出现在rtcp包中SDEC中,用于音视频同步; a=candidate:1 1 udp 2013266431 x.x.x.x 43342 typ host generation 0 表示候选人的传输地址,查看详情。 2.1 ICE候选者
a=candidate:1467250027 1 udp 2122260223 192.168.0.196 56143 typ host generation 0 2.2 ICE参数
a=ice-ufrag:Oyef7uvBlwafI3hT a=ice-pwd:T0teqPLNQQOf+5W+ls+P2p16 2.3 DTLS参数
a=fingerprint:sha-256 49:66:12:17:0D:1C:91:AE:57:4C:C6:36:DD:D5:97:D2:7D:62:C9:9A:7F:B9:A3:F4:70:03:E7:43:91:73:23:5E a=setup:actpass 2.4 Codec参数
a=rtpmap:100 VP8/90000
这条线表示VP8与有效载荷类型100对齐。这意味着此会话中包含VP8视频帧的RTP数据包的有效载荷类型字段的值将为100. 现在VP8是视频的MTI编解码器,未来可能会发生变化。
a=rtcp-fb:100 ccm fir
指明使用全内帧请求(Full Intraframe Request, FIR)
a=rtcp-fb:100 nack
此行请求使用RFC 4585中指示的否定ACK(nack)。这允许另一端知道数据包丢失。
a=rtcp-fb:100 nack pli
此行表明支持PLI NACK RTCP消息。 这允许在视频包丢失时向另一端点请求新的VP8关键帧。
a=rtcp-fb:100 goog-remb
它定义了RTCP消息对Receiver Estimated Maximum Bitrate的使用。前缀goog-意味着仍然只能由Google和非标准实现。
a=rtpmap:101 VP9/90000
Chrome支持版本48的VP9。您可以在Web M项目站点了解此视频编解码器的功能。 默认情况下,它在VP8之后显示为SDP中的第二个选项。
a=rtcp-fb:101 ccm fir a=rtcp-fb:101 nack a=rtcp-fb:101 nack pli a=rtcp-fb:101 goog-remb a=rtpmap:116 red/90000
该行请求使用RFC2198,其定义有效载荷格式以编码冗余媒体数据。在WebRTC中,这用于封装有效载荷VP8(视频有效载荷本身)和FEC(Forward Error Correction)。
a=rtpmap:117 ulpfec/90000
此行请求使用ULP FEC(在RFC5109中定义)。 FEC(前向纠错)允许通过基于原始分组发送冗余信息来纠正数据传输中的某种错误。 当丢包(在RTCP-RR数据包中报告)时使用FEC。
a=rtpmap:96 rtx/90000
参数rtx和apt在RFC4588中定义。 该RFC定义了RTP有效载荷格式,仅用于执行另一方尚未接收的分组的重传。 无法使用原始有效负载重新发送数据包,因为它会破坏RTP和RTCP机制,因此它们会在具有不同有效负载的重新传输流中重新传输。 90000指的是重传流的时钟速率,其与原始VP8流相同,原始VP8流与其他视频协议90000相同。
a=fmtp:96 apt=100
该行表示具有有效载荷96的RTP分组将传输那些已经在该SDP(VP8)中对有效载荷100进行了编码的编解码器的rtx消息。 2.5 SSRC参数
a=ssrc-group:FID 2231627014 632943048
此行声明SSRC 632943048是RFC5576中指定的2231627014的rtx修复流程
a=ssrc:2231627014 cname:4TOk42mSjXCkVIa6 a=ssrc:2231627014 msid:lgsCFqt9kN2fVKw5wg3NKqGdATQoltEwOdMS daed9400-d0dd-4db3-b949-422499e96e2d a=ssrc:2231627014 mslabel:lgsCFqt9kN2fVKw5wg3NKqGdATQoltEwOdMS a=ssrc:2231627014 label:daed9400-d0dd-4db3-b949-422499e96e2d
** 注:未特别说明,则与audio一致 三、音频行
m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 106 105 13 126
m=audio说明本会话包含音频,9代表音频使用端口9来传输,但是在webrtc中一现在一般不使用,如果设置为0,代表不传输音频, UDP/TLS/RTP/SAVPF是表示用户来传输音频支持的协议,udp,tls,rtp代表使用udp来传输rtp包,并使用tls加密SAVPF代表使用srtcp的反馈机制来控制通信过程, 后台111 103 104 9 0 8 106 105 13 126表示本会话音频支持的编码。
c=IN IP4 0.0.0.0
这一行表示你要用来接收或者发送音频使用的IP地址,webrtc使用ice传输,不使用这个地址
a=rtcp:9 IN IP4 0.0.0.0
明确指定传输RTCP的IP和端口,而不是从基础媒体端口派生的。请注意,与SRTP的端口相同,因为支持RTCP Multiplex。webrtc中不使用。
a=mid:audio
在前面BUNDLE这一行中用到的媒体标识。如果我们有不同的媒体,我们每个都应该有不同的标识符。
a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level
此行定义将在RTP标头中使用的扩展,以便接收器可以正确解码并提取元数据。
a=sendrecv
上一行指出我是双向通信,另外几种类型是recvonly,sendonly,inactive。
a=rtcp-mux
指出rtp,rtcp包使用同一个端口来传输 3.1 ICE候选者
a=candidate:1467250027 1 udp 2122260223 192.168.0.196 46243 typ host generation 0
a=candidate:1467250027 2 udp 2122260222 192.168.0.196 56280 typ host generation 0
UDP上RTP的主机候选者 - 在此ICE行中,我们的浏览器为其主机候选者 - 浏览器正在计算机上监听的接口或接口的IP。 浏览器可以在该IP上接收/发送SRTP和SRTCP,以防远程对等端的候选者具有IP可见性。例如,如果另一台计算机位于同一LAN上,则将使用主机候选项。 协议(udp) - 2122260223之后的数字是候选者的优先级。请注意,宿主候选者的优先级高于其他候选者, 因为使用宿主候选者在资源使用方面更有效。第一行(component = 1)用于RTP,第二行(component = 2)用于RTCP。 请注意,浏览器不知道另一端是否支持rtcp-mux,因此它必须在要约中包含RTCP端口。
a=candidate:435653019 1 tcp 1845501695 192.168.0.196 0 typ host tcptype active generation 0
a=candidate:435653019 2 tcp 1845501695 192.168.0.196 0 typ host tcptype active generation 0
TCP上RTP的主机候选者 - 这些线路与之前的两条ICE线路相同,但是对于TCP流量。 请注意,优先级较低 - 即1845501695较大 - 因为TCP不是实时媒体传输的最佳选择。
a=candidate:1853887674 1 udp 1518280447 47.61.61.61 36768 typ srflx raddr 192.168.0.196 rport 36768 generation 0
a=candidate:1853887674 2 udp 1518280447 47.61.61.61 36768 typ srflx raddr 192.168.0.196 rport 36768 generation 0
UDP上RTP的自反性候选者(reflexive candidates) - 这里我们有服务器反身候选人。 请注意,它们的优先级低于主机候选者。 这些候选人是由STUN服务器发现的。
a=candidate:750991856 2 udp 25108222 237.30.30.30 51472 typ relay raddr 47.61.61.61 rport 54763 generation 0
a=candidate:750991856 1 udp 25108223 237.30.30.30 58779 typ relay raddr 47.61.61.61 rport 54761 generation 0
UDP上RTP的中继候选者(Relay candidates) - 接下来我们有中继候选。这些候选者是从TURN服务器获得的,必须在创建对等连接时进行配置。 请注意,此处的优先级低于主机和反射候选者(25108222更高),因此仅当主机和反射候选者之间没有IP连接时才使用中继。 3.2 ICE参数
a=ice-ufrag:khLS
a=ice-pwd:cxLzteJaJBou3DspNaPsJhlQ
以上两行是ice协商过程中的安全验证信息 3.3 DTLS参数
a=fingerprint:sha-256 FA:14:42:3B:C7:97:1B:E8:AE:0C2:71:03:05:05:16:8F:B9:C7:98:E9:60:43:4B:5B:2C:28:EE:5C:8F3:17
此指纹是DTLS-SRTP协商中使用的证书的哈希函数的结果。 此行在信令(应该是可信的)和DTLS中使用的证书之间创建绑定,如果指纹不匹配,则应拒绝会话。
a=setup:actpass
代表本客户端在dtls协商过程中,可以做客户端也可以做服务端 3.4 Codec参数
a=rtpmap:111 opus/48000/2
Opus是WebRTC的MTI音频编解码器之一。 它具有可变比特率(6kbps-510kbps),并且不受任何版税限制,因此可以在任何浏览器中自由实现。 Opus支持开始变得普遍,它已成为大多数WebRTC应用程序的关键。
a=fmtp:111 minptime=10; useinbandfec=1
此行包括Chrome支持的音频Opus编解码器的可选有效载荷格式特定参数。 minipitime = 10指定分组化时间的最低值(ptime:由单个分组传输的音频的毫秒数)。 useinbandfec = 1指定解码器能够利用Opus带内FEC(前向错误连接)。
a=rtpmap:103 ISAC/16000
ISAC(互联网语音音频编解码器)是用于高质量会议的宽带语音编解码器。 16000表示ISAC将以16kbps的速度使用。
a=rtpmap:104 ISAC/32000
32000表示ISAC将以32kbps的速度使用。
a=rtpmap:9 G722/8000
G722是一款工作频率为48,56和64 kbit/s的宽带音频编解码器,与G.711等窄带语音编码器相比,由于50-7000 Hz的语音带宽更宽,因此可提供更高的语音质量。
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
这是使用不同压扩法则的经典电信64kbps脉冲编码调制(PCM)编解码器。 0和8分别是PCMU和PCMA的静态有效载荷类型。从技术上讲,这些线路不存在,因为这些信息可以通过媒体线中的编解码器列表 - PCMU或PCMA来推断。
a=rtpmap:106 CN/32000
a=rtpmap:105 CN/16000
a=rtpmap:13 CN/8000
上面的动态RTP有效载荷类型(除了有效载荷类型13,它是静态的)表示舒适噪声(Comfort Noise, CN)将用于速率为48000,32000,16000和8000kbits/s的编解码器。
a=rtpmap:126 telephone-event/8000
此行表示浏览器支持RFC4733,允许它在RTP内发送DTMF,而不是通常的数字化正弦波,而是作为特殊有效载荷(在这种情况下,RTP数据包中有效载荷126)。 该DTMF机制确保DTMF将独立于音频编解码器和信令协议进行传输。
a=maxptime:60
maxptime指定可以封装在每个数据包中的最大媒体数量,以毫秒为单位表示。数据包的大小可能会对音频和BW的质量产生副作用。可以在SDP中修改此值。 3.5 SSRC参数
a=ssrc:3570614608 cname:4TOk42mSjXCkVIa6
cname源属性将媒体源与其Canonical端点标识符相关联,即使在发现冲突时ssrc标识符发生更改,该标准端点标识符也将保持RTP媒体流的常量。 这是媒体发送方将在其RTCP SDES数据包中放置的值。
a=ssrc:3570614608 msid:lgsCFqt9kN2fVKw5wg3NKqGdATQoltEwOdMS 35429d94-5637-4686-9ecd-7d0622261ce8
该线用于使用SDP信令通知SSRC的RTP概念与"媒体流"/"媒体流轨道"的WebRTC概念之间的关联。 第一个参数对应于媒体流(media stream)的id,第二个参数对应于媒体流轨道的if。这些ID在WebRTC API中处理。 第一个数字是SSRC标识符,它将包含在RTP数据包的SSRC字段中。
a=ssrc:3570614608 mslabel:lgsCFqt9kN2fVKw5wg3NKqGdATQoltEwOdMS
label属性指的是Media Stream对象的id。不推荐使用该参数,并将msid替换为该参数。标签是为了向后兼容而保留。
a=ssrc:3570614608 label:35429d94-5637-4686-9ecd-7d0622261ce8
label属性也被msid弃用,并在使用SDP的任意网络应用程序的上下文中携带指向RTP媒体流的指针。 此标签与WebRTC API中的Media Stream Track ID相对应,该ID包含在msid行中。 四、WebRTC实例
下面例子来自腾讯云WebRTC服务的远端offer。 // sdp版本号为0 v=0 // o= // 用户名为空,会话id是8100750360520823155,会话版本是2 //(后面如果有类似改变编码的操作,sess-version加1), // 地址类型为IP4,地址为127.0.0.1(这里可以忽略) o=- 7595655801978680453 2 IN IP4 112.90.139.105 // 会话名为空 s=- // 会话的起始时间,都为0表示没有限制 t=0 0 a=ice-lite // 音频、视频的传输的传输采取多路复用,通过同一个RTP通道传输音频、视频, // 可以参考 https://tools.ietf.org/html/draft-ietf-mmusic-sdp-bundle-negotiation-54 a=group:BUNDLE 0 1 // WMS是WebRTC Media Stram的缩写,这里给Media Stream定义了一个唯一的标识符。 // 一个Media Stream可以有多个track(video track、audio track), //这些track就是通过这个唯一标识符关联起来的,具体见下面的媒体行(m=)以及它对应的附加属性(a=ssrc:) // 可以参考这里 http://tools.ietf.org/html/draft-ietf-mmusic-msid a=msid-semantic: WMS 5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV // m= ... // 本次会话有音频,端口为9(可忽略,端口9为Discard Protocol专用), // 采用UDP传输加密的RTP包,并使用基于SRTCP的音视频反馈机制来提升传输质量 //,111、103、104等是audio可能采用的编码(参见前面m=的说明) m=audio 9 UDP/TLS/RTP/SAVPF 111 103 104 9 0 8 126 // 音频发送者的IP4地址,WebRTC采用ICE,这里的 0.0.0.0 可直接忽略 c=IN IP4 0.0.0.0 // RTCP采用的端口、IP地址(可忽略) a=rtcp:9 IN IP4 0.0.0.0 // ice-ufrag、ice-pwd 分别为ICE协商用到的认证信息 a=ice-ufrag:58142170598604946 a=ice-pwd:71696ad0528c4adb02bb40e1 // DTLS协商过程的指纹信息 a=fingerprint:sha-256 7F:98:08:AC:17:6A:34:DB:CF:3B:EC:93:ED:57:3F:5A:9E:1F:4A:F3:DB:D5:BF:66:EE:17:58:E0:57:EC:1B:19 // 当前客户端在DTLS协商过程中,既可以作为客户端,也可以作为服务端,具体可参考 RFC4572 a=setup:actpass // 当前媒体行的标识符(在a=group:BUNDLE 0 1 这行里面用到,这里0表示audio) a=mid:0 // RTP允许扩展首部,这里表示采用了RFC6464定义的针对audio的扩展首部, // 用来调节音量,比如在大型会议中,有多个音频流,就可以用这个来调整音频混流的策略 // 这里没有vad=1,表示不启用这个音量控制 a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level // 表示既可以发送音频,也可以接收音频 a=sendrecv // 表示启用多路复用,RTP、RTCP共用同个通道 a=rtcp-mux // 下面几行都是对audio媒体行的补充说明(针对111),包括rtpmap、rtcp-fb、fmtp // rtpmap:编解码器为opus,采样率是48000,2声道 a=rtpmap:111 opus/48000/2 // rtcp-fb:基于RTCP的反馈控制机制,可以参考 https://tools.ietf.org/html/rfc5124、 //https://webrtc.org/experiments/rtp-hdrext/transport-wide-cc-02/ a=rtcp-fb:111 transport-cc a=rtcp-fb:111 nack // 最小的音频打包时间 a=fmtp:111 minptime=20 // 跟前面的rtpmap类似 a=rtpmap:126 telephone-event/8000 // ssrc用来对媒体进行描述,格式为a=ssrc: :,具体可参考 RFC5576 // cname用来唯一标识媒体的数据源 a=ssrc:16864608 cname:YZcxBwerFFm6GH69 // msid后面带两个id,第一个是MediaStream的id,第二个是audio track的id(跟后面的mslabel、label对应) a=ssrc:16864608 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 128f4fa0-81dd-4c3a-bbcd-22e71e29d178 a=ssrc:16864608 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV a=ssrc:16864608 label:128f4fa0-81dd-4c3a-bbcd-22e71e29d178 // 跟audio类似,不赘述 m=video 9 UDP/TLS/RTP/SAVPF 122 102 125 107 124 120 123 119 c=IN IP4 0.0.0.0 a=rtcp:9 IN IP4 0.0.0.0 a=ice-ufrag:58142170598604946 a=ice-pwd:71696ad0528c4adb02bb40e1 a=fingerprint:sha-256 7F:98:08:AC:17:6A:34:DB:CF:3B:EC:93:ED:57:3F:5A:9E:1F:4A:F3:DB:D5:BF:66:EE:17:58:E0:57:EC:1B:19 a=setup:actpass a=mid:1 a=extmap:2 urn:ietf:params:rtp-hdrext:toffset a=extmap:3 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time a=extmap:4 urn:3gpp:video-orientation a=extmap:5 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 a=extmap:6 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay a=sendrecv a=rtcp-mux a=rtcp-rsize a=rtpmap:122 H264/90000 a=rtcp-fb:122 ccm fir a=rtcp-fb:122 nack a=rtcp-fb:122 nack pli a=rtcp-fb:122 goog-remb a=rtcp-fb:122 transport-cc a=fmtp:122 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f a=rtpmap:102 rtx/90000 a=fmtp:102 apt=122 a=rtpmap:125 H264/90000 a=rtcp-fb:125 ccm fir a=rtcp-fb:125 nack a=rtcp-fb:125 nack pli a=rtcp-fb:125 goog-remb a=rtcp-fb:125 transport-cc a=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f a=rtpmap:107 rtx/90000 a=fmtp:107 apt=125 a=rtpmap:124 H264/90000 a=rtcp-fb:124 ccm fir a=rtcp-fb:124 nack a=rtcp-fb:124 nack pli a=rtcp-fb:124 goog-remb a=rtcp-fb:124 transport-cc a=fmtp:124 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=4d0032 a=rtpmap:120 rtx/90000 a=fmtp:120 apt=124 a=rtpmap:123 H264/90000 a=rtcp-fb:123 ccm fir a=rtcp-fb:123 nack a=rtcp-fb:123 nack pli a=rtcp-fb:123 goog-remb a=rtcp-fb:123 transport-cc a=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032 a=rtpmap:119 rtx/90000 a=fmtp:119 apt=123 a=ssrc-group:FID 33718809 50483271 a=ssrc:33718809 cname:ovaCctnHP9Asci9c a=ssrc:33718809 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 1d7fc300-9889-4f94-9f35-c0bcc77a260d a=ssrc:33718809 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV a=ssrc:33718809 label:1d7fc300-9889-4f94-9f35-c0bcc77a260d a=ssrc:50483271 cname:ovaCctnHP9Asci9c a=ssrc:50483271 msid:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV 1d7fc300-9889-4f94-9f35-c0bcc77a260d a=ssrc:50483271 mslabel:5Y2wZK8nANNAoVw6dSAHVjNxrD1ObBM2kBPV a=ssrc:50483271 label:1d7fc300-9889-4f94-9f35-c0bcc77a260d五、Uncaught (in promise) DOMException: Answer tried to set recv when offer did not set send
chrome 中可以播放,firefox报错
搜索一下,参考https://stackoverflow.com/questions/35166456
RFC 3264: " If a media stream is listed as recvonly in the offer, the answer MUST be marked as sendonly or inactive in the answer. "
这里可以参考SDP模型介绍,获取更详细的知识 1.情态动词术语解释MUST必须、一定要; MUST NOT禁止; REQUIRED需要; SHALL、SHOULD应该; SHALL NOT、SHOULD NOT不应该; RECOMMENDED推荐; MAY可以
以上情态动词术语可参考RFC2119[3],这些动词要求我们在产品实现时,需要遵守或灵活变更约束。 2.初始协商的Offer请求
实体A <-> 实体B,实体首先发起Offer请求,内容如2节所示,对于作何一个媒体流/媒体通道,这时实体A必须: 如果媒体流方向标为recvonly/sendrecv,即a=recvonly或a=sendrecv,则A必须(MUST)准备好在这个IP和端口上接收实体B发来的媒体流; 如果媒体流方向标为sendonly/inactive,即a=recvonly或a=sendrecv,则A不需要进行准备。 3.Answer响应
实体B收到A的请求offer后,根据自身支持的媒体类型和编码策略,回复响应。 如果实体B回复的响应中的媒体流数量和顺序必须(MUST)和请求offer一致,以便实体A进行甄别和决策。即m行的数量和顺序必须一致,B不能(MUST NOT)擅自增加或删除媒体流。如果B不支持某个媒体流,可以在对应的端口置0,但不能不带这个m行描述。 对于某种媒体,实体B必须(MUST)从请求offer中选出A支持且自己也支持的该媒体的编码标识集,并且可以(MAY)附带自己支持的其它类型编码。 对于响应消息中各个媒体的方向: 如果请求某媒体流的方向为sendonly,那么响应中对应媒体的方向必须为recvonly; 如果请求某媒体流的方向为recvonly,那么响应中对应媒体的方向必须为sendonly; 如果请求某媒体流的方向为sendrecv,那么响应中对应媒体的方向可以为sendrecv/sendonly/recvonly/inactive中的一种; 如果请求某媒体流的方向为inactive,那么响应中对应媒体的方向必须为inactive; 响应answer里提供IP和端口,指示Offerer本端期望用于接收媒体流的IP和端口,一旦响应发出之后,Offerer必须(MUST)准备好在这个IP和端口上接收实体A发来的媒体流。 如果请求offer中带了ptime(媒体流打包间隔)的a行或带宽的a行,则响应answer也应该(SHOULD)相应的携带。 实体B Offerer应该(SHOULD)使用实体A比较期望的编码生成媒体流发送。一般来说对于m行,如m=video 0 RTP/AVP 31 34,排充越靠前的编码表示该实体越希望以这个编码作为载体,这里示例31(H261),34(H263)中H261为A更期望使用的编码类型。同理,当实体A收到响应answer后也是这样理解的。 4.实体收到响应后的处理
当实体A收到B回复的响应后,可以(MAY)开始发送媒体流,如果媒体流方向为sendonly/sendrecv, 必须(MUST)使用answer列举的媒体类型/编码生成媒体发送; 应该(SHOULD)使用answer中的ptime和bandwidth来打包发送媒体流; 可以(MAY)立即停止监听端口,该端口为offer支持answer不支持的媒体所使用的端口。 5.修改媒体流(会话)
修改媒体流的offer-answer操作必须基于之前协商的媒体形式(音频、视频等),不能(MUST NOT)对已有媒体流进行删减。
(a)删除媒体流 如果实体认定新的会话不支持之前媒商的某个媒体,新的offer只须对这种媒体所在m行的端口置0,但不能不描述这种媒体,即不带对应m行。当answerer收到响应之后,处理同初始协商一样。
(b)增加媒体流 如果实体打算新增媒体流,在offer里只须加上描述即可或者占用之前端口被置0的媒体流,即用新的媒体描述m行替换旧的。当answerer收到offer请求后,发现有新增媒体描述,或者过于端口被置0的媒体行被新的媒体描述替换,即知道当前为新增媒体流,处理同初始协商。
(c)修改媒体流 修改媒体注主要是针对初始协商结果,如果有变更即进入修改流程处理,可能的变更包括IP地址、端口,媒体格式(编码),媒体类型(音、视频),媒体属性(ptime,bandwidth,媒体流方向变更等)。 6.解决问题:
查看请求offer发送的Sdp,发现在没有设置的情况下,全是默认的recvonly。 m=audio ... ... a=recvonly ... m=video ... a=recvonly
而服务器返回的 m=audio ... ... a=recvonly ... m=video ... a=sendrecv
参照上述要求,可以将请求offer设置成sendrecv即可解决firefox中的报错 this.pc.addTransceiver("video", { "direction": "sendrecv" }); this.pc.addTransceiver("audio", { "direction": "sendrecv" });7.Transceivers
Transceivers are for sending and receiving
Transceivers is a WebRTC specific concept that you will see in the API. What it is doing is exposing the ‘Media Description’ to the JavaScript API. Each Media Description becomes a Transceiver. Every time you create a Transceiver a new Media Description is added to the local Session Description.
Each Media Description in WebRTC will have a direction attribute. This allows a WebRTC Agent to declare ‘I am going to send you this codec, but I am not willing to accept anything back’. There are four valid values: send recv sendrecv inactive
太神奇了!多项研究证实每天两杯咖啡,延长寿命还有益大脑点击关注不迷路普及科学知识,传播科学精神对于很多人来说,能够提神醒脑的咖啡,是一种续命神器当然,这本身是一种调侃的说法,但越来越多的证据告诉我们,适量的咖啡摄入真的有利于健康,甚至
黄连上清片,不仅清热解毒,巧搭配还能治这5种病,学会全家受益大家好,我是沈医生,说起清热解毒的中成药,好多朋友都能想到黄连上清片,对于上焦内热导致的很多症状,比如头晕脑胀啊,牙龈肿痛啊,口腔溃疡啊,大便干结等等,都有很好的作用。但是每个人的
世界500强发布苹果华为小米,中国科技企业有哪些每年,财富杂志都会发布世界500强排行榜。现在,2022年的财富世界500强排行榜已经正式发布,我们一起来看看吧。文章中提到,今年财富世界500强排行榜企业的营业收入总和约为37。
鼓浪屿千金下嫁寒门穷小子,却在56岁跳海自尽,是钟南山一生的痛2021年10月20日是钟南山85岁的生日,南京发布官方账号发表了一篇名为钟南山的家国情怀的文章,里面提到从非典到当下的疫情,钟南山一直站在抗疫一线。这一天,钟南山的团队也发文回应
热点势均力敌的爱情什么样?近日,中央音乐学院扬琴专业硕士毕业生情侣周婷婷叶钰昭组成的扬琴cp,在网络走红,吸引上百万人次观看。据了解,两人都是95后。叶钰昭9岁开始学习扬琴,2015年
直击要点!塔国医疗系统五大问题据亚洲快讯网报道,近日,塔吉克斯坦卫生部报告了医疗改革的实施情况,阻碍医疗系统发展的尚未解决的问题并没有减少。塔当地媒体总结了该国医疗系统的五大问题,这些问题迫使医生离开该国居民不
17月电信业务收入总量同比分别增长8。3和22。2央视网消息17月份,通信业保持良好运行态势。电信业务收入稳步增长,电信业务总量保持较快增长5G千兆光网和物联网等新型基础设施建设和应用快速推进,网络运力和感知能力持续增强云计算等新
家里常备的牛黄上清片,不仅能清热解毒,还能治疗这6种疾病大家好,我是刘医生。牛黄上清片是我们生活中很常见的药物,但是它还能治疗这五种疾病你知道吗?首先我先给大家讲解一下牛黄上清片的成分,牛黄上清片由牛黄黄连大黄连翘黄菩荆芥穗栀子桔梗蔓荆
一加AcePro玩游戏到底有多爽?硬核堆料宝藏功能,游戏体验拉满近两年来,随着技术的进步,手游越来越受欢迎。王者荣耀原神等游戏热度不断升高,游戏画面玩法也愈加精致复杂,这也对手机的性能和体验提出了更高的要求。尤其是当下手机配置同质化严重,想要在
运鲲鹏展翅奋飞万里近期运20又突破了多项重装空投纪录运20空降兵伞花多到数不清近日中部战区空军航空兵某团运20机组与空降兵部队联合展开空投空降训练面对强干扰气流多变的复杂环境机组在超
证监会重拳出击追债2。4亿!法院准予强制执行点蓝字关注,不迷路乐视的神仙日子,还能过多久?日前,北京裁判文书网公布的一份显示执行裁定书显示,北京金融法院裁定准予强制执行证监会针对被执行人乐视网2。4亿元罚款的行政处罚。证监会