shinyoshiaki / werift-webrtc

WebRTC Implementation for TypeScript (Node.js), includes ICE/DTLS/SCTP/RTP/SRTP/WEBM/MP4
MIT License
469 stars 30 forks source link

Error sending RTP packets when trying to connect to stream which is currently being written by MediaRecorder #302

Closed kolserdav closed 1 year ago

kolserdav commented 1 year ago

When recording a stream of one client through MediaRecorder, the second client cannot connect to it, as an error occurs when sending RTP packets

[0] [1] 03:58:14  error  unhandledRejection  TypeError: Cannot read properties of null (reading 'length')
[0] [1]     at RTCRtpSender.sendRtp (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpSender.js:296:40)
[0] [1]     at Object.execute (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpSender.js:155:24)
[0] [1]     at Event.execute (/home/kol/Projects/werift-sfu-react/node_modules/rx.mini/lib/core/index.js:17:30)
[0] [1]     at RTCRtpReceiver.handleRTP (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpReceiver.js:259:36)
[0] [1]     at RTCRtpReceiver.handleRtpBySsrc (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpReceiver.js:49:18)
[0] [1]     at RtpRouter.routeRtp (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/router.js:29:29)
[0] [1]     at Object.execute (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/transport/dtls.js:172:33)
[0] [1]     at Event.execute (/home/kol/Projects/werift-sfu-react/node_modules/rx.mini/lib/core/index.js:17:30)
[0] [1]     at Connection.dataReceived (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/ice/src/ice.js:552:21)
[0] [1]     at StunProtocol.datagramReceived (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/ice/src/stun/protocol.js:42:27) 

The top element of the error stack refers to this line https://github.com/shinyoshiaki/werift-webrtc/blob/39c9756f27151f3db773e6edb5fd49c3f84343a8/packages/webrtc/src/media/rtpSender.ts#L368

Between adjacent cycles of outputs of these errors, something like the following occurs:

... previous copies of error output 8-10

[0] [1] 04:19:02  error  unhandledRejection  TypeError: Cannot read properties of null (reading 'length')
[0] [1]     at RTCRtpSender.sendRtp (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpSender.js:296:40)
[0] [1]     at Object.execute (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpSender.js:155:24)
[0] [1]     at Event.execute (/home/kol/Projects/werift-sfu-react/node_modules/rx.mini/lib/core/index.js:17:30)
[0] [1]     at RTCRtpReceiver.handleRTP (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpReceiver.js:259:36)
[0] [1]     at RTCRtpReceiver.handleRtpBySsrc (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpReceiver.js:49:18)
[0] [1]     at RtpRouter.routeRtp (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/router.js:29:29)
[0] [1]     at Object.execute (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/transport/dtls.js:172:33)
[0] [1]     at Event.execute (/home/kol/Projects/werift-sfu-react/node_modules/rx.mini/lib/core/index.js:17:30)
[0] [1]     at Connection.dataReceived (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/ice/src/ice.js:552:21)
[0] [1]     at StunProtocol.datagramReceived (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/ice/src/stun/protocol.js:42:27)  
[0] [1] 
[0] [1] 04:19:02  info  | Closing the call  {
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   eventName: 'close-peer-handler'
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  info  --> Creating answer  {
[0] [1]   roomId: '1671704372346',
[0] [1]   userId: '1671742236952',
[0] [1]   target: '1',
[0] [1]   connId: '5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   peers: [
[0] [1]     '1_0_2764d409-6496-48b1-b8f6-debb9e97edac',
[0] [1]     '1671742236952_0_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1_1671742236952_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54'
[0] [1]   ],
[0] [1]   is: 'new',
[0] [1]   cs: 'new',
[0] [1]   ss: 'stable'
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  info  ontrack  {
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   isRoom: false,
[0] [1]   si: '{a2e5c9f9-8eae-413f-a177-e40af6f1b8a7}',
[0] [1]   isNew: true,
[0] [1]   userId: '1671742236952',
[0] [1]   target: '1',
[0] [1]   tracks: [ 'audio' ],
[0] [1]   isChanged: false
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  info  ontrack  {
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   isRoom: false,
[0] [1]   si: '{a2e5c9f9-8eae-413f-a177-e40af6f1b8a7}',
[0] [1]   isNew: true,
[0] [1]   userId: '1671742236952',
[0] [1]   target: '1',
[0] [1]   tracks: [ 'video' ],
[0] [1]   isChanged: false
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  info  Add tracks  {
[0] [1]   roomId: '1671704372346',
[0] [1]   userId: '1671742236952',
[0] [1]   target: '1',
[0] [1]   connId: '5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   _peerId: '1_0_2764d409-6496-48b1-b8f6-debb9e97edac',
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   tracksL: 2,
[0] [1]   tracks: [ 'audio', 'video' ],
[0] [1]   ssL: 2,
[0] [1]   peers: [
[0] [1]     '1_0_2764d409-6496-48b1-b8f6-debb9e97edac',
[0] [1]     '1671742236952_0_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1_1671742236952_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54'
[0] [1]   ],
[0] [1]   cS: 'new',
[0] [1]   sS: 'have-remote-offer',
[0] [1]   iS: 'new'
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  info  ! WebRTC signaling state changed to:  have-remote-offer  
[0] [1] 
[0] [1] 04:19:03  info  ---> Setting local description after creating answer  {
[0] [1]   roomId: '1671704372346',
[0] [1]   userId: '1671742236952',
[0] [1]   target: '1',
[0] [1]   connId: '5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   peers: [
[0] [1]     '1_0_2764d409-6496-48b1-b8f6-debb9e97edac',
[0] [1]     '1671742236952_0_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1_1671742236952_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54'
[0] [1]   ],
[0] [1]   is: 'new',
[0] [1]   cs: 'new',
[0] [1]   ss: 'stable'
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  info  ! WebRTC signaling state changed to:  stable  
[0] [1] 
[0] [1] 04:19:03  info  Sending answer packet back to other peer  {
[0] [1]   roomId: '1671704372346',
[0] [1]   userId: '1671742236952',
[0] [1]   target: '1',
[0] [1]   connId: '5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   peerId: '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]   peers: [
[0] [1]     '1_0_2764d409-6496-48b1-b8f6-debb9e97edac',
[0] [1]     '1671742236952_0_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1_1671742236952_5e298b54-573a-47e0-a157-1c5bc43b3a54',
[0] [1]     '1671742236952_1_5e298b54-573a-47e0-a157-1c5bc43b3a54'
[0] [1]   ],
[0] [1]   is: 'new',
[0] [1]   cs: 'new',
[0] [1]   ss: 'stable'
[0] [1] }  
[0] [1] 
[0] [1] 04:19:03  error  unhandledRejection  TypeError: Cannot read properties of null (reading 'length')
[0] [1]     at RTCRtpSender.sendRtp (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpSender.js:296:40)
[0] [1]     at Object.execute (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpSender.js:155:24)
[0] [1]     at Event.execute (/home/kol/Projects/werift-sfu-react/node_modules/rx.mini/lib/core/index.js:17:30)
[0] [1]     at RTCRtpReceiver.handleRTP (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpReceiver.js:259:36)
[0] [1]     at RTCRtpReceiver.handleRtpBySsrc (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/rtpReceiver.js:49:18)
[0] [1]     at RtpRouter.routeRtp (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/media/router.js:29:29)
[0] [1]     at Object.execute (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/webrtc/src/transport/dtls.js:172:33)
[0] [1]     at Event.execute (/home/kol/Projects/werift-sfu-react/node_modules/rx.mini/lib/core/index.js:17:30)
[0] [1]     at Connection.dataReceived (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/ice/src/ice.js:552:21)
[0] [1]     at StunProtocol.datagramReceived (/home/kol/Projects/werift-sfu-react/node_modules/werift/lib/ice/src/stun/protocol.js:42:27)  

subsequent copies of error output 8-10 ...

The recording is made by the client thread under id 1, the client connects under a different id. As can be seen from the logs, the error occurs not on the connection where the second client sends its media tracks to the server, but on the connection where it tries to receive incoming media tracks from client 1.

kolserdav commented 1 year ago

I tried to figure out how rtp.payload becomes null. This line https://github.com/shinyoshiaki/werift-webrtc/blob/39c9756f27151f3db773e6edb5fd49c3f84343a8/packages/webrtc/src/media/rtpReceiver.ts#L331 is referenced by the fourth element from the top of the error stack, if it is logged there, then the payload is never null. The second error stack entry from the top refers to this line https://github.com/shinyoshiaki/werift-webrtc/blob/39c9756f27151f3db773e6edb5fd49c3f84343a8/packages/webrtc/src/media/rtpSender.ts#L196 , if it is logged there, then the payload is indeed null before an error is thrown.

The conclusion suggests itself that the payload when recording a stream, when this stream needs to connect to another client, sometime becomes null somewhere inside rx.mini.

Roughly handling these exceptions does nothing, even if the error does not pop up, then such a stream is never played or recorded.

@shinyoshiaki , I need your help to find the reason for the RTP of stream packets crossing while recording and sending to clients at the same time.

Once again, note that this problem only occurs when trying to connect to a stream that is in the recording. But if we start recording streams of already connected clients, then everything works fine.

shinyoshiaki commented 1 year ago

I've tried to fix it, please make sure it's fixed in v0.17.6

kolserdav commented 1 year ago

I've tried to fix it, please make sure it's fixed in v0.17.6

Cool, it works, thanks!