@@ -13,7 +13,7 @@ type SignalingMessage =
1313
1414export function useWebRTC (
1515 send : ( msg : unknown ) => void ,
16- onTrack : ( stream : MediaStream ) => void ,
16+ onTrack : ( stream : MediaStream | null ) => void ,
1717) {
1818 const pcRef = useRef < RTCPeerConnection | null > ( null )
1919 const dcUnorderedRef = useRef < RTCDataChannel | null > ( null )
@@ -98,11 +98,26 @@ export function useWebRTC(
9898
9999 pc . onconnectionstatechange = ( ) => {
100100 console . log ( "[RTC] Connection State:" , pc . connectionState )
101+ if (
102+ pc . connectionState === "failed" ||
103+ pc . connectionState === "disconnected" ||
104+ pc . connectionState === "closed"
105+ ) {
106+ onTrack ( null )
107+ }
101108 }
102109
103110 pc . ontrack = ( event ) => {
104111 console . log ( "[RTC] track received" )
105112 const stream = event . streams [ 0 ] ?? new MediaStream ( [ event . track ] )
113+ event . track . addEventListener (
114+ "ended" ,
115+ ( ) => {
116+ console . log ( "[RTC] track ended" )
117+ onTrack ( null )
118+ } ,
119+ { once : true } ,
120+ )
106121 onTrack ( stream )
107122 }
108123
@@ -130,41 +145,41 @@ export function useWebRTC(
130145
131146 const handleSignalingMessage = useCallback (
132147 async ( msg : SignalingMessage ) => {
133- if ( msg . type === "offer" ) {
134- if ( ! pcRef . current ) {
135- pcRef . current = createPeerConnection ( )
136- }
137- const pc = pcRef . current
138- await pc . setRemoteDescription ( new RTCSessionDescription ( msg . sdp ) )
139-
140- for ( const c of pendingIceCandidatesRef . current ) {
141- await pc . addIceCandidate ( c )
142- }
143- pendingIceCandidatesRef . current = [ ]
144-
145- const answer = await pc . createAnswer ( )
146- await pc . setLocalDescription ( answer )
147- sendRef . current ( { type : "answer" , sdp : pc . localDescription } )
148- } else if ( msg . type === "answer" ) {
149- const pc = pcRef . current
150- if ( pc ) {
148+ try {
149+ if ( msg . type === "offer" ) {
150+ if ( ! pcRef . current ) {
151+ pcRef . current = createPeerConnection ( )
152+ }
153+ const pc = pcRef . current
151154 await pc . setRemoteDescription ( new RTCSessionDescription ( msg . sdp ) )
155+
152156 for ( const c of pendingIceCandidatesRef . current ) {
153157 await pc . addIceCandidate ( c )
154158 }
155159 pendingIceCandidatesRef . current = [ ]
156- }
157- } else if ( msg . type === "ice-candidate" ) {
158- const pc = pcRef . current
159- if ( pc ?. remoteDescription ) {
160- try {
160+
161+ const answer = await pc . createAnswer ( )
162+ await pc . setLocalDescription ( answer )
163+ sendRef . current ( { type : "answer" , sdp : pc . localDescription } )
164+ } else if ( msg . type === "answer" ) {
165+ const pc = pcRef . current
166+ if ( pc ) {
167+ await pc . setRemoteDescription ( new RTCSessionDescription ( msg . sdp ) )
168+ for ( const c of pendingIceCandidatesRef . current ) {
169+ await pc . addIceCandidate ( c )
170+ }
171+ pendingIceCandidatesRef . current = [ ]
172+ }
173+ } else if ( msg . type === "ice-candidate" ) {
174+ const pc = pcRef . current
175+ if ( pc ?. remoteDescription ) {
161176 await pc . addIceCandidate ( new RTCIceCandidate ( msg . candidate ) )
162- } catch ( e ) {
163- console . error ( "[RTC] Failed to add ICE candidate" , e )
177+ } else {
178+ pendingIceCandidatesRef . current . push ( msg . candidate )
164179 }
165- } else {
166- pendingIceCandidatesRef . current . push ( msg . candidate )
167180 }
181+ } catch ( e ) {
182+ console . error ( "[RTC] Failed to handle signaling message" , e )
168183 }
169184 } ,
170185 [ createPeerConnection ] ,
@@ -187,11 +202,23 @@ export function useWebRTC(
187202 }
188203 } , [ ] )
189204
205+ const closePeerConnection = useCallback ( ( ) => {
206+ if ( pcRef . current ) {
207+ pcRef . current . close ( )
208+ pcRef . current = null
209+ }
210+
211+ dcUnorderedRef . current = null
212+ dcOrderedRef . current = null
213+ pendingIceCandidatesRef . current = [ ]
214+ } , [ ] )
215+
190216 return {
191217 pcRef,
192218 createPeerConnection,
193219 handleSignalingMessage,
194220 sendInput,
221+ closePeerConnection,
195222 configureMediaSender,
196223 }
197224}
0 commit comments