@@ -3,10 +3,7 @@ import 'logger.dart';
33import 'transports/http.dart' if (dart.library.html) 'transports/http_web.dart' ;
44import 'utils.dart' ;
55
6- enum WhipMode {
7- kSend,
8- kReceive,
9- }
6+ enum WhipMode { kSend, kReceive }
107
118enum WhipState {
129 kNew,
@@ -25,14 +22,17 @@ class WHIP {
2522 RTCPeerConnection ? pc;
2623 late WhipMode mode;
2724 final String url;
28- String ? _sessionUrl ;
25+ String ? _resourceUrl ;
2926 String ? _eTag;
3027 Map <String , String >? headers = {};
3128 String ? videoCodec;
3229 WHIP ({required this .url, this .headers});
3330
34- Future <void > initlize (
35- {required WhipMode mode, MediaStream ? stream, String ? videoCodec}) async {
31+ Future <void > initlize ({
32+ required WhipMode mode,
33+ MediaStream ? stream,
34+ String ? videoCodec,
35+ }) async {
3636 initHttpClient ();
3737 if (pc != null ) {
3838 return ;
@@ -56,23 +56,26 @@ class WHIP {
5656 case WhipMode .kSend:
5757 stream? .getTracks ().forEach ((track) async {
5858 await pc! .addTransceiver (
59- track: track,
60- kind: track.kind == 'audio'
61- ? RTCRtpMediaType .RTCRtpMediaTypeAudio
62- : RTCRtpMediaType .RTCRtpMediaTypeVideo ,
63- init: RTCRtpTransceiverInit (
64- direction: TransceiverDirection .SendOnly , streams: [stream]));
59+ track: track,
60+ kind: track.kind == 'audio'
61+ ? RTCRtpMediaType .RTCRtpMediaTypeAudio
62+ : RTCRtpMediaType .RTCRtpMediaTypeVideo ,
63+ init: RTCRtpTransceiverInit (
64+ direction: TransceiverDirection .SendOnly ,
65+ streams: [stream],
66+ ),
67+ );
6568 });
6669 break ;
6770 case WhipMode .kReceive:
6871 await pc! .addTransceiver (
69- kind: RTCRtpMediaType .RTCRtpMediaTypeAudio ,
70- init: RTCRtpTransceiverInit (
71- direction : TransceiverDirection . RecvOnly ) );
72+ kind: RTCRtpMediaType .RTCRtpMediaTypeAudio ,
73+ init: RTCRtpTransceiverInit (direction : TransceiverDirection . RecvOnly ),
74+ );
7275 await pc! .addTransceiver (
73- kind: RTCRtpMediaType .RTCRtpMediaTypeVideo ,
74- init: RTCRtpTransceiverInit (
75- direction : TransceiverDirection . RecvOnly ) );
76+ kind: RTCRtpMediaType .RTCRtpMediaTypeVideo ,
77+ init: RTCRtpTransceiverInit (direction : TransceiverDirection . RecvOnly ),
78+ );
7679 break ;
7780 }
7881 log.debug ('Initlize whip connection: mode = $mode , stream = ${stream ?.id }' );
@@ -93,34 +96,36 @@ class WHIP {
9396 var offer = await pc! .getLocalDescription ();
9497 final sdp = offer! .sdp;
9598 log.debug ('Sending offer: $sdp ' );
96- var respose = await httpPost (Uri .parse (url),
97- headers: {
98- 'Content-Type' : 'application/sdp' ,
99- if (headers != null ) ...headers!
100- },
101- body: sdp);
99+ var respose = await httpPost (
100+ Uri .parse (url),
101+ headers: {
102+ 'Content-Type' : 'application/sdp' ,
103+ if (headers != null ) ...headers! ,
104+ },
105+ body: sdp,
106+ );
102107
103108 if (respose.statusCode != 200 && respose.statusCode != 201 ) {
104109 throw Exception (
105- 'Failed to send offer: ${respose .statusCode }, body ${respose .body }' );
110+ 'Failed to send offer: ${respose .statusCode }, body ${respose .body }' ,
111+ );
106112 }
107-
108- log.debug ('Resource URL: $_sessionUrl ' );
113+ _resourceUrl = respose.headers[ 'location' ];
114+ log.debug ('Resource URL: $_resourceUrl ' );
109115 final answer = RTCSessionDescription (respose.body, 'answer' );
110116 log.debug ('Received answer: ${answer .sdp }' );
111117 await pc! .setRemoteDescription (answer);
112118 setState (WhipState .kConnected);
113119
114120 _eTag = respose.headers['etag' ];
115121
116- _sessionUrl = respose.headers['location' ];
117- if (_sessionUrl == null ) {
118- _sessionUrl = url;
122+ if (_resourceUrl == null ) {
123+ _resourceUrl = url;
119124 log.warn ('Resource url not found, use $url as resource url!' );
120125 } else {
121- if (_sessionUrl ! .startsWith ('/' )) {
126+ if (_resourceUrl ! .startsWith ('/' )) {
122127 var uri = Uri .parse (url);
123- _sessionUrl = '${uri .origin }$_sessionUrl ' ;
128+ _resourceUrl = '${uri .origin }$_resourceUrl ' ;
124129 }
125130 }
126131 } catch (e) {
@@ -137,10 +142,10 @@ class WHIP {
137142 log.debug ('Closing whip connection' );
138143 await pc? .close ();
139144 try {
140- if (_sessionUrl == null ) {
141- throw 'Resource url not found!' ;
145+ if (_resourceUrl == null ) {
146+ throw Exception ( 'Resource url not found!' ) ;
142147 }
143- await httpDelete (Uri .parse (_sessionUrl ?? url));
148+ await httpDelete (Uri .parse (_resourceUrl ?? url));
144149 } catch (e) {
145150 log.error ('connect error: $e ' );
146151 setState (WhipState .kFailure);
@@ -155,17 +160,19 @@ class WHIP {
155160 }
156161
157162 void onicecandidate (RTCIceCandidate ? candidate) async {
158- if (candidate == null || _sessionUrl == null ) {
163+ if (candidate == null || _resourceUrl == null ) {
159164 return ;
160165 }
161166 log.debug ('Sending candidate: ${candidate .toMap ().toString ()}' );
162167 try {
163- var respose = await httpPatch (Uri .parse (_sessionUrl! ),
164- headers: {
165- 'Content-Type' : 'application/trickle-ice-sdpfrag' ,
166- if (headers != null ) ...headers!
167- },
168- body: candidate.candidate);
168+ var respose = await httpPatch (
169+ Uri .parse (_resourceUrl! ),
170+ headers: {
171+ 'Content-Type' : 'application/trickle-ice-sdpfrag' ,
172+ if (headers != null ) ...headers! ,
173+ },
174+ body: candidate.candidate,
175+ );
169176 if (respose.statusCode == 204 ) {
170177 log.debug ('Candidate sent successfully' );
171178 return ;
@@ -184,8 +191,11 @@ class WHIP {
184191 state = newState;
185192 }
186193
187- void setPreferredCodec (RTCSessionDescription description,
188- {String audioCodec = 'opus' , String videoCodec = 'vp8' }) {
194+ void setPreferredCodec (
195+ RTCSessionDescription description, {
196+ String audioCodec = 'opus' ,
197+ String videoCodec = 'vp8' ,
198+ }) {
189199 var capSel = CodecCapabilitySelector (description.sdp! );
190200 var acaps = capSel.getCapabilities ('audio' );
191201 if (acaps != null ) {
0 commit comments