@@ -25,7 +25,8 @@ class WHIP {
2525 RTCPeerConnection ? pc;
2626 late WhipMode mode;
2727 final String url;
28- String ? resourceURL;
28+ String ? _sessionUrl;
29+ String ? _eTag;
2930 Map <String , String >? headers = {};
3031 String ? videoCodec;
3132 WHIP ({required this .url, this .headers});
@@ -46,6 +47,7 @@ class WHIP {
4647 'rtcpMuxPolicy' : 'require' ,
4748 });
4849 pc? .onIceCandidate = onicecandidate;
50+ pc? .onRenegotiationNeeded = onrenegotiationneeded;
4951 pc? .onIceConnectionState = (state) {
5052 print ('state: ${state .toString ()}' );
5153 };
@@ -99,23 +101,26 @@ class WHIP {
99101 body: sdp);
100102
101103 if (respose.statusCode != 200 && respose.statusCode != 201 ) {
102- throw Exception ('Failed to send offer: ${respose .statusCode }' );
104+ throw Exception (
105+ 'Failed to send offer: ${respose .statusCode }, body ${respose .body }' );
103106 }
104107
105- log.debug ('Resource URL: $resourceURL ' );
108+ log.debug ('Resource URL: $_sessionUrl ' );
106109 final answer = RTCSessionDescription (respose.body, 'answer' );
107110 log.debug ('Received answer: ${answer .sdp }' );
108111 await pc! .setRemoteDescription (answer);
109112 setState (WhipState .kConnected);
110113
111- resourceURL = respose.headers['location' ];
112- if (resourceURL == null ) {
113- resourceURL = url;
114+ _eTag = respose.headers['etag' ];
115+ 116+ _sessionUrl = respose.headers['location' ];
117+ if (_sessionUrl == null ) {
118+ _sessionUrl = url;
114119 log.warn ('Resource url not found, use $url as resource url!' );
115120 } else {
116- if (resourceURL ! .startsWith ('/' )) {
121+ if (_sessionUrl ! .startsWith ('/' )) {
117122 var uri = Uri .parse (url);
118- resourceURL = '${uri .origin }$resourceURL ' ;
123+ _sessionUrl = '${uri .origin }$_sessionUrl ' ;
119124 }
120125 }
121126 } catch (e) {
@@ -132,10 +137,10 @@ class WHIP {
132137 log.debug ('Closing whip connection' );
133138 await pc? .close ();
134139 try {
135- if (resourceURL == null ) {
140+ if (_sessionUrl == null ) {
136141 throw 'Resource url not found!' ;
137142 }
138- await httpDelete (Uri .parse (resourceURL ?? url));
143+ await httpDelete (Uri .parse (_sessionUrl ?? url));
139144 } catch (e) {
140145 log.error ('connect error: $e ' );
141146 setState (WhipState .kFailure);
@@ -145,18 +150,26 @@ class WHIP {
145150 setState (WhipState .kDisconnected);
146151 }
147152
153+ void onrenegotiationneeded () async {
154+ log.debug ('onRenegotiationNeeded' );
155+ }
156+ 148157 void onicecandidate (RTCIceCandidate ? candidate) async {
149- if (candidate == null || resourceURL == null ) {
158+ if (candidate == null || _sessionUrl == null ) {
150159 return ;
151160 }
152161 log.debug ('Sending candidate: ${candidate .toMap ().toString ()}' );
153162 try {
154- var respose = await httpPatch (Uri .parse (resourceURL ! ),
163+ var respose = await httpPatch (Uri .parse (_sessionUrl ! ),
155164 headers: {
156165 'Content-Type' : 'application/trickle-ice-sdpfrag' ,
157166 if (headers != null ) ...headers!
158167 },
159168 body: candidate.candidate);
169+ if (respose.statusCode == 204 ) {
170+ log.debug ('Candidate sent successfully' );
171+ return ;
172+ }
160173 log.debug ('Received Patch response: ${respose .body }' );
161174 // TODO(cloudwebrtc): Add remote candidate to local pc.
162175 } catch (e) {
0 commit comments