diff --git a/webrtc/Sdp.cpp b/webrtc/Sdp.cpp index 60c2bad0..eca66a61 100644 --- a/webrtc/Sdp.cpp +++ b/webrtc/Sdp.cpp @@ -468,6 +468,33 @@ string SdpAttrRtcp::toString() const { return SdpItem::toString(); } +void SdpAttrIceOption::parse(const string &str){ + auto vec = split(str, " "); + for (auto &v : vec) { + if (!strcasecmp(v.data(), "trickle")) { + trickle = true; + continue; + } + if (!strcasecmp(v.data(), "renomination")) { + renomination = true; + continue; + } + } +} + +string SdpAttrIceOption::toString() const{ + if (value.empty()) { + if (trickle && renomination) { + value = "trickle renomination"; + } else if (trickle) { + value = "trickle"; + } else if (renomination) { + value = "renomination"; + } + } + return value; +} + void SdpAttrFingerprint::parse(const string &str) { auto vec = split(str, " "); if (vec.size() != 2) { @@ -751,9 +778,10 @@ void RtcSession::loadFrom(const string &str) { rtc_media.ice_pwd = media.getStringItem('a', "ice-pwd"); rtc_media.role = media.getItemClass('a', "setup").role; rtc_media.fingerprint = media.getItemClass('a', "fingerprint"); - rtc_media.ice_trickle = media.getItem('a', "ice-trickle").operator bool(); rtc_media.ice_lite = media.getItem('a', "ice-lite").operator bool(); - rtc_media.ice_renomination = media.getItem('a', "ice-renomination").operator bool(); + auto ice_options = media.getItemClass('a', "ice-options"); + rtc_media.ice_trickle = ice_options.trickle; + rtc_media.ice_renomination = ice_options.renomination; rtc_media.candidate = media.getAllItem('a', "candidate"); if (mline.type == TrackType::TrackApplication) { @@ -922,15 +950,15 @@ string RtcSession::toString() const{ sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared(m.ice_pwd))); sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared(m.fingerprint))); sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared(m.role))); - if (m.ice_trickle) { - sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared("ice-trickle"))); + if (m.ice_trickle || m.ice_renomination) { + auto attr = std::make_shared(); + attr->trickle = m.ice_trickle; + attr->renomination = m.ice_renomination; + sdp_media.items.emplace_back(wrapSdpAttr(attr)); } if (m.ice_lite) { sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared("ice-lite"))); } - if (m.ice_renomination) { - sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared("ice-renomination"))); - } for (auto &ext : m.extmap) { sdp_media.items.emplace_back(wrapSdpAttr(std::make_shared(ext))); } @@ -1215,8 +1243,8 @@ shared_ptr RtcConfigure::createAnswer(const RtcSession &offer){ ret->session_info = "zlmediakit_webrtc_session"; ret->connection.parse("IN IP4 0.0.0.0"); ret->msid_semantic.parse("WMS *"); - matchMedia(ret, TrackVideo, offer.media, video); matchMedia(ret, TrackAudio, offer.media, audio); + matchMedia(ret, TrackVideo, offer.media, video); matchMedia(ret, TrackApplication, offer.media, application); return ret; } diff --git a/webrtc/Sdp.h b/webrtc/Sdp.h index 97c5f020..fa167fbc 100644 --- a/webrtc/Sdp.h +++ b/webrtc/Sdp.h @@ -282,6 +282,10 @@ public: class SdpAttrIceOption : public SdpItem { public: //a=ice-options:trickle + bool trickle{false}; + bool renomination{false}; + void parse(const string &str) override; + string toString() const override; const char* getKey() const override { return "ice-options";} }; diff --git a/webrtc/WebRtcTransport.cpp b/webrtc/WebRtcTransport.cpp index 3c58628e..4c43f97d 100644 --- a/webrtc/WebRtcTransport.cpp +++ b/webrtc/WebRtcTransport.cpp @@ -78,7 +78,7 @@ string getFingerprint(const string &algorithm_str, const std::shared_ptr(); _offer_sdp->loadFrom(offer); diff --git a/webrtc/answer.sdp b/webrtc/answer.sdp new file mode 100644 index 00000000..82df3355 --- /dev/null +++ b/webrtc/answer.sdp @@ -0,0 +1,46 @@ + v=0 +o=- 0 0 IN IP4 0.0.0.0 +s=zlmediakit_webrtc_session +i=zlmediakit_webrtc_session +t=0 0 +c=IN IP4 0.0.0.0 +a=msid-semantic: WMS * +a=group:BUNDLE 0 1 +m=audio 0 UDP/TLS/RTP/SAVPF 111 +a=mid:0 +c=IN IP4 0.0.0.0 +a=ice-ufrag:PdK3 +a=ice-pwd:PdK31zZ1sKhPU2ACzP5av37f +a=fingerprint:sha-256 D1:4F:7B:70:86:99:BE:1E:7E:B8:C7:0F:13:BC:78:C4:6A:F9:2C:F6:F3:5E:42:11:0F:1C:74:18:F6:DD:95:75 +a=setup:passive +a=ice-options:trickle +a=extmap:1 urn:ietf:params:rtp-hdrext:ssrc-audio-level +a=recvonly +a=rtcp-mux +a=rtpmap:111 opus/48000/2 +a=rtcp-fb:111 transport-cc +a=fmtp:111 minptime=10;useinbandfec=1 +m=video 0 UDP/TLS/RTP/SAVPF 102 121 +a=mid:1 +c=IN IP4 0.0.0.0 +a=ice-ufrag:PdK3 +a=ice-pwd:PdK31zZ1sKhPU2ACzP5av37f +a=fingerprint:sha-256 D1:4F:7B:70:86:99:BE:1E:7E:B8:C7:0F:13:BC:78:C4:6A:F9:2C:F6:F3:5E:42:11:0F:1C:74:18:F6:DD:95:75 +a=setup:passive +a=ice-options:trickle +a=extmap:14 urn:ietf:params:rtp-hdrext:toffset +a=extmap:2 http://www.webrtc.org/experiments/rtp-hdrext/abs-send-time +a=extmap:13 urn:3gpp:video-orientation +a=extmap:3 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01 +a=extmap:12 http://www.webrtc.org/experiments/rtp-hdrext/playout-delay +a=recvonly +a=rtcp-mux +a=rtpmap:102 H264/90000 +a=rtcp-fb:102 goog-remb +a=rtcp-fb:102 transport-cc +a=rtcp-fb:102 ccm fir +a=rtcp-fb:102 nack +a=rtcp-fb:102 nack pli +a=fmtp:102 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42001f +a=rtpmap:121 rtx/90000 +a=fmtp:121 apt=102 \ No newline at end of file