Giter Site home page Giter Site logo

shinyoshiaki / werift-webrtc Goto Github PK

View Code? Open in Web Editor NEW
416.0 17.0 27.0 24.12 MB

WebRTC Implementation for TypeScript (Node.js), includes ICE/DTLS/SCTP/RTP/SRTP/WEBM/MP4

License: MIT License

TypeScript 98.47% Python 0.20% JavaScript 1.20% CSS 0.13%
webrtc typescript nodejs ice dtls rtp sctp srtp webm

werift-webrtc's Introduction

werift

werift (Webrtc Implementation for TypeScript)

werift is a WebRTC Implementation for TypeScript (Node.js), includes ICE/DTLS/SCTP/RTP.

install

npm install werift

requires at least Node.js 16

Documentation (WIP)

examples

https://github.com/shinyoshiaki/werift-webrtc/tree/master/examples

SFU

https://github.com/shinyoshiaki/node-sfu

demo

MediaChannel

yarn media

open https://shinyoshiaki.github.io/werift-webrtc/examples/mediachannel/pubsub/answer

see console & chrome://webrtc-internals/

DataChannel

run

yarn datachannel

open https://shinyoshiaki.github.io/werift-webrtc/examples/datachannel/answer

see console & chrome://webrtc-internals/

RoadMap

Work in Progress Towards 1.0

  • STUN
  • TURN
    • UDP
  • ICE
    • Vanilla ICE
    • Trickle ICE
    • ICE-Lite Client Side
    • ICE-Lite Server Side
  • DTLS
    • DTLS-SRTP
    • Curve25519
    • P-256
  • DataChannel
  • MediaChannel
    • sendonly
    • recvonly
    • sendrecv
    • multi track
    • RTX
    • RED
  • RTP
    • RFC 3550
    • Parse RTP Payload Format for VP8 Video
    • Parse RTP Payload Format for VP9 Video
    • Parse RTP Payload Format for H264 Video
    • Parse RTP Payload Format for AV1 Video
    • RED (RFC 2198)
  • RTCP
    • SR/RR
    • Picture Loss Indication
    • ReceiverEstimatedMaxBitrate
    • GenericNack
    • TransportWideCC
  • SRTP
  • SRTCP
  • SDP
  • PeerConnection
  • Simulcast
    • recv
  • BWE
    • sender side BWE
  • Documentation
  • Compatibility
    • Chrome
    • Safari
    • FireFox
    • Pion
    • aiortc
    • sipsorcery
    • webrtc-rs
  • Interop E2E test
  • Unit Tests
  • MediaRecorder
    • OPUS
    • VP8
    • H264
    • VP9
    • AV1

Road Map Towards 2.0

  • API compatible with browser RTCPeerConnection
  • ICE
    • ICE restart
  • SDP
    • reuse inactive m-line
  • Simulcast
    • send
  • support more cipher suites
  • getStats
  • TURN
    • TCP

reference

werift-webrtc's People

Contributors

dependabot[bot] avatar kibertoad avatar kolserdav avatar koush avatar lukks avatar nicolehippolite avatar oeed avatar shinyoshiaki avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

werift-webrtc's Issues

"invalid remote port" when data starts flowing

The following offer:

v=0
o=- 25373548 0 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic:WMS *
m=audio 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=ice-ufrag:e1e6
a=ice-pwd:3de05c27f761027baaeda2
a=ice-options:trickle
a=fingerprint:sha-256 02:35:32:AF:E1:44:8A:91:D3:54:BB:14:8C:40:2A:73:0A:81:57:14:E8:1D:4B:0E:C4:A2:D6:68:D4:5D:1E:6A
a=setup:actpass
a=recvonly
a=mid:0
a=msid:3a3e0c15-b3e6-4f46-bf38-bd904b44b782 c5af7974-995a-4a06-af72-84d0e2a69295
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:2112560515 cname:58cdd469-29cc-4620-bbfa-1e44461d2c76
a=rtpmap:96 opus/48000/2
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=ice-ufrag:e1e6
a=ice-pwd:3de05c27f761027baaeda2
a=ice-options:trickle
a=fingerprint:sha-256 02:35:32:AF:E1:44:8A:91:D3:54:BB:14:8C:40:2A:73:0A:81:57:14:E8:1D:4B:0E:C4:A2:D6:68:D4:5D:1E:6A
a=setup:actpass
a=recvonly
a=mid:1
a=msid:92de723a-910d-47b8-a694-ba16846c2155 7b970e2e-6610-42c4-9c0a-973953222f42
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:321650976 cname:58cdd469-29cc-4620-bbfa-1e44461d2c76
a=rtpmap:97 VP8/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:e1e6
a=ice-pwd:3de05c27f761027baaeda2
a=ice-options:trickle
a=fingerprint:sha-256 02:35:32:AF:E1:44:8A:91:D3:54:BB:14:8C:40:2A:73:0A:81:57:14:E8:1D:4B:0E:C4:A2:D6:68:D4:5D:1E:6A
a=setup:actpass
a=mid:2
a=sctp-port:5000
a=max-message-size:65536

and answer:

v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 2 1
a=msid-semantic: WMS 13945094204333313074/3212739396 virtual-6666
a=ice-lite
m=audio 19305 UDP/TLS/RTP/SAVPF 96
c=IN IP4 <redacted>
a=rtcp:9 IN IP4 0.0.0.0
a=candidate: 1 udp 2113939711 2607:f8b0:400e:c03::7f 19305 typ host generation 0
a=candidate: 1 tcp 2113939710 2607:f8b0:400e:c03::7f 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113939709 2607:f8b0:400e:c03::7f 443 typ host generation 0
a=candidate: 1 udp 2113932031 74.125.197.127 19305 typ host generation 0
a=candidate: 1 tcp 2113932030 74.125.197.127 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113932029 74.125.197.127 443 typ host generation 0
a=ice-ufrag:KFPTBCP4YKPZTY1Q
a=ice-pwd:VA0L9MQMWS8IYO9NJF+ITE++
a=fingerprint:sha-256 92:D6:06:D6:CB:64:B4:EF:47:76:00:F7:48:E0:ED:DD:9F:3E:DA:16:41:49:47:43:E0:77:DD:C6:D7:83:7E:19
a=setup:passive
a=mid:0
a=sendrecv
a=msid:virtual-6666 virtual-6666
a=rtcp-mux
a=rtpmap:96 opus/48000/2
a=fmtp:96 minptime=10;useinbandfec=1
a=ssrc:6666 cname:6666
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:KFPTBCP4YKPZTY1Q
a=ice-pwd:VA0L9MQMWS8IYO9NJF+ITE++
a=fingerprint:sha-256 92:D6:06:D6:CB:64:B4:EF:47:76:00:F7:48:E0:ED:DD:9F:3E:DA:16:41:49:47:43:E0:77:DD:C6:D7:83:7E:19
a=setup:passive
a=mid:1
a=sendrecv
a=msid:13945094204333313074/3212739396 13945094204333313074/3212739396
a=rtcp-mux
a=rtpmap:97 VP8/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
a=ssrc:3212739396 cname:3212739396
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:KFPTBCP4YKPZTY1Q
a=ice-pwd:VA0L9MQMWS8IYO9NJF+ITE++
a=fingerprint:sha-256 92:D6:06:D6:CB:64:B4:EF:47:76:00:F7:48:E0:ED:DD:9F:3E:DA:16:41:49:47:43:E0:77:DD:C6:D7:83:7E:19
a=setup:passive
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

At the start of data flow an ack will try to be sent and the remote port of the server will be undefined here: https://github.com/shinyoshiaki/werift-webrtc/blob/develop/packages/sctp/src/sctp.ts#L1111

Probably related to: #141, to make this work I had to "hack" the answer sdp to change "sctpmap" to "sctpMap".

FireFox DTLS issue

I can't recall if I ever tested Firefox before, so I'm unsure if this is a regression in Werift or behavior change in Firefox.

When attempting to connect a peer connection with a Firefox browser, werift fails during dtls handshaking with:
' ContentType.alert [object Object] BadCertificate flight 5 lastFlight [object Object]'

I'll see if I can fix this, but figured I'd give you a heads up first in case you know what the issue is.

trickle candidates

From what I'm observing, the stun/srflx are not trickled? It seems to hang/timeout the initial create/setLocalDescription if the stun server does not respond in a timely fashion.

How to use MediaStream ?

hi :
I saw that the API can use MediaStream addTrack, I want to combine them to get a stream of audio and video,Can you do an example? I tried to do it myself, but it didn't work
exp:

image
image

"throw new Error();"

Some data channel messages seem to cause werift to "throw new Error();" at this line: https://github.com/shinyoshiaki/werift-webrtc/blob/develop/packages/webrtc/src/transport/sctp.ts#L94

Here is the full log:

/Users/me/.nvm/versions/node/v16.13.1/bin/node /Users/me/Source/webrtctest/dist/index.js
werift/webrtc/utils iceOptions {
stunServer: [ 'stun.l.google.com', 19302 ],
turnServer: undefined,
turnUsername: undefined,
turnPassword: undefined
} +0ms
werift:packages/webrtc/src/peerConnection.ts iceGatheringStateChange new +0ms
werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange new +1ms
werift:packages/webrtc/src/peerConnection.ts signalingStateChange have-local-offer +52ms
werift:packages/webrtc/src/peerConnection.ts iceGatheringStateChange gathering +1ms

v=0
o=- 17858619 0 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic:WMS *
m=audio 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=ice-ufrag:7441
a=ice-pwd:5458ef9e20f8f7e44bfd4d
a=ice-options:trickle
a=fingerprint:sha-256 D8:DB:13:39:07:F5:20:8C:A2:A1:DD:24:F6:F2:44:7A:ED:13:C4:CB:37:E9:27:91:C3:44:99:A4:EE:11:DA:F2
a=setup:actpass
a=recvonly
a=mid:0
a=msid:01f3f107-8a92-4727-bf6e-f16d113e1074 78c4643f-a66b-4d3b-b692-fa0996e1b0f4
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:769720978 cname:11ee087f-4ce9-481d-bde6-674cb159939c
a=rtpmap:96 opus/48000/2
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=ice-ufrag:7441
a=ice-pwd:5458ef9e20f8f7e44bfd4d
a=ice-options:trickle
a=fingerprint:sha-256 D8:DB:13:39:07:F5:20:8C:A2:A1:DD:24:F6:F2:44:7A:ED:13:C4:CB:37:E9:27:91:C3:44:99:A4:EE:11:DA:F2
a=setup:actpass
a=recvonly
a=mid:1
a=msid:55a23c31-fb42-447d-ad77-38780e198f14 874c4544-0316-45a0-974d-54dd46d0de4d
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:2374351791 cname:11ee087f-4ce9-481d-bde6-674cb159939c
a=rtpmap:97 H264/90000
a=rtcp-fb:97 transport-cc
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
a=fmtp:97 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:7441
a=ice-pwd:5458ef9e20f8f7e44bfd4d
a=ice-options:trickle
a=fingerprint:sha-256 D8:DB:13:39:07:F5:20:8C:A2:A1:DD:24:F6:F2:44:7A:ED:13:C4:CB:37:E9:27:91:C3:44:99:A4:EE:11:DA:F2
a=setup:actpass
a=mid:2
a=sctp-port:5000
a=max-message-size:65536

v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 2 1
a=msid-semantic: WMS 12472791870915183646/3212739396 virtual-6666
a=ice-lite
m=audio 19305 UDP/TLS/RTP/SAVPF 96
c=IN IP4
a=rtcp:9 IN IP4 0.0.0.0
a=candidate: 1 udp 2113939711 2607:f8b0:400e:c0a::7f 19305 typ host generation 0
a=candidate: 1 tcp 2113939710 2607:f8b0:400e:c0a::7f 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113939709 2607:f8b0:400e:c0a::7f 443 typ host generation 0
a=candidate: 1 udp 2113932031 172.253.117.127 19305 typ host generation 0
a=candidate: 1 tcp 2113932030 172.253.117.127 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113932029 172.253.117.127 443 typ host generation 0
a=ice-ufrag:QNI9WYYGY3SUVKFU
a=ice-pwd:QFMXR+WUA1NJBL/EJGJCXA00
a=fingerprint:sha-256 A9:FC:30:FE:52:00:89:D2:F1:B1:C3:87:85:A6:7F:28:2E:85:65:2A:9B:EF:9E:D9:42:AD:02:22:E0:C3:32:CC
a=setup:passive
a=mid:0
a=sendrecv
a=msid:virtual-6666 virtual-6666
a=rtcp-mux
a=rtpmap:96 opus/48000/2
a=fmtp:96 minptime=10;useinbandfec=1
a=ssrc:6666 cname:6666
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:QNI9WYYGY3SUVKFU
a=ice-pwd:QFMXR+WUA1NJBL/EJGJCXA00
a=fingerprint:sha-256 A9:FC:30:FE:52:00:89:D2:F1:B1:C3:87:85:A6:7F:28:2E:85:65:2A:9B:EF:9E:D9:42:AD:02:22:E0:C3:32:CC
a=setup:passive
a=mid:1
a=sendrecv
a=msid:12472791870915183646/3212739396 12472791870915183646/3212739396
a=rtcp-mux
a=rtpmap:97 H264/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
a=fmtp:97 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f
a=ssrc:3212739396 cname:3212739396
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:QNI9WYYGY3SUVKFU
a=ice-pwd:QFMXR+WUA1NJBL/EJGJCXA00
a=fingerprint:sha-256 A9:FC:30:FE:52:00:89:D2:F1:B1:C3:87:85:A6:7F:28:2E:85:65:2A:9B:EF:9E:D9:42:AD:02:22:E0:C3:32:CC
a=setup:passive
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

werift:packages/webrtc/src/peerConnection.ts negotiated codecs [
RTCRtpCodecParameters {
rtcpFeedback: [],
mimeType: 'audio/opus',
channels: 2,
clockRate: 48000,
payloadType: 96,
parameters: 'minptime=10;useinbandfec=1'
}
] +1s
werift:packages/webrtc/src/media/router.ts registerRtpReceiverBySsrc {
muxId: '0',
rtcp: undefined,
codecs: [
RTCRtpCodecParameters {
rtcpFeedback: [],
mimeType: 'audio/opus',
channels: 2,
clockRate: 48000,
payloadType: 96,
parameters: 'minptime=10;useinbandfec=1'
}
],
headerExtensions: [],
encodings: [ RTCRtpCodingParameters { ssrc: 6666, payloadType: 96 } ]
} +0ms
werift:packages/webrtc/src/media/rtpSender.ts replaceTrack ssrc 6666 rid undefined +0ms
werift:packages/webrtc/src/media/rtpReceiver.ts twcc support false +0ms
werift:packages/webrtc/src/peerConnection.ts negotiated codecs [
RTCRtpCodecParameters {
rtcpFeedback: [
[RTCRtcpFeedback],
[RTCRtcpFeedback],
[RTCRtcpFeedback],
[RTCRtcpFeedback]
],
mimeType: 'video/H264',
channels: undefined,
clockRate: 90000,
payloadType: 97,
parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f'
}
] +4ms
werift:packages/webrtc/src/media/router.ts registerRtpReceiverBySsrc {
muxId: '1',
rtcp: undefined,
codecs: [
RTCRtpCodecParameters {
rtcpFeedback: [Array],
mimeType: 'video/H264',
channels: undefined,
clockRate: 90000,
payloadType: 97,
parameters: 'level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640c1f'
}
],
headerExtensions: [],
encodings: [ RTCRtpCodingParameters { ssrc: 3212739396, payloadType: 97 } ]
} +4ms
werift:packages/webrtc/src/media/rtpSender.ts replaceTrack ssrc 3212739396 rid undefined +5ms
werift:packages/webrtc/src/media/rtpReceiver.ts twcc support false +4ms
werift:packages/webrtc/src/peerConnection.ts connectionStateChange connecting +3ms
werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange checking +0ms
werift-ice : packages/ice/src/ice.ts : log start connect ice +0ms
werift-ice : packages/ice/src/ice.ts : log check start Candidate {
foundation: '',
component: 1,
transport: 'udp',
priority: 2113932031,
host: '172.253.117.127',
port: 19305,
type: 'host',
relatedAddress: undefined,
relatedPort: undefined,
tcptype: undefined,
generation: undefined
} +1ms
werift:packages/webrtc/src/peerConnection.ts signalingStateChange stable +5ms
answer applied
werift-ice : packages/ice/src/ice.ts : log check start Candidate {
foundation: '',
component: 1,
transport: 'udp',
priority: 2113939711,
host: '2607:f8b0:400e:c0a::7f',
port: 19305,
type: 'host',
relatedAddress: undefined,
relatedPort: undefined,
tcptype: undefined,
generation: undefined
} +25ms
werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 ed 6a 91 31 db 2c 37 e8 b9 05 42 ac 00 06 00 15 51 4e 49 39 57 59 59 47 59 33 53 55 56 4b 46 55 3a 37 34 34 31 00 00 00 00 24 ... 50 more bytes> +0ms
werift-ice : packages/ice/src/ice.ts : log response Message {
messageMethod: 1,
messageClass: 256,
transactionId: <Buffer 18 8f 86 23 f6 ba 55 f7 fc e7 fa ee>,
attributes: {
USERNAME: 'QNI9WYYGY3SUVKFU:7441',
'XOR-MAPPED-ADDRESS': [ '65.35.254.126', 51908 ],
'MESSAGE-INTEGRITY': <Buffer 93 63 9d af 89 87 17 a8 79 d6 42 68 12 fb e5 38 52 ca 8b 7a>,
FINGERPRINT: 3911387794
}
} [ '172.253.117.127', 19305 ] +68ms
werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 ed 6a 91 31 db 2c 37 e8 b9 05 42 ac 00 06 00 15 51 4e 49 39 57 59 59 47 59 33 53 55 56 4b 46 55 3a 37 34 34 31 00 00 00 00 24 ... 50 more bytes> +100ms
werift-ice : packages/ice/src/ice.ts : log ICE completed +86ms
werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange connected +190ms
werift:packages/webrtc/src/peerConnection.ts ice connected +1ms
werift-dtls : packages/dtls/src/socket.ts : log support srtpProfiles [ 7, 1 ] +0ms
werift-dtls : packages/dtls/src/client.ts : log start client +0ms
werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 ed 6a 91 31 db 2c 37 e8 b9 05 42 ac 00 06 00 15 51 4e 49 39 57 59 59 47 59 33 53 55 56 4b 46 55 3a 37 34 34 31 00 00 00 00 24 ... 50 more bytes> +202ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [ 2 ] +195ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log serverHello 49199 +0ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log selected cipherSuite 49199 +1ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log RenegotiationIndication +0ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log selected srtp profile 1 +0ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [ 11 ] +3ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [ 12 ] +0ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [] +1ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log handshake certificate Certificate {
certificateList: [
<Buffer 30 82 02 ff 30 82 01 e7 a0 03 02 01 02 02 08 62 ca 1e 6c 00 5c 08 64 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 13 31 11 30 0f 06 03 55 04 03 13 ... 721 more bytes>
],
msgType: 11
} +2ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log ServerKeyExchange ServerKeyExchange {
ellipticCurveType: 3,
namedCurve: 29,
publicKeyLength: 32,
publicKey: <Buffer 36 bf 07 89 38 bd 9b 29 e4 ac f9 64 64 8a 65 5c 5d a8 68 c7 14 93 e8 f1 86 f1 c7 a6 25 bf 3b 24>,
hashAlgorithm: 4,
signatureAlgorithm: 1,
signatureLength: 256,
signature: <Buffer bd 36 ff 3a 8f 4f a0 30 8a 41 fa 9f 4f 88 bc 90 33 70 9d 63 de b4 31 8e 74 f7 ba 88 01 85 03 d4 55 ba d1 fd 00 dc e1 a4 5a 70 1b b5 97 eb 0a 41 14 d0 ... 206 more bytes>,
msgType: 12
} +1ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log selected curve 29 +1ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [ 13 ] +27ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [ 14 ] +1ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log certificate_request ServerCertificateRequest {
certificateTypes: [ 1, 64 ],
signatures: [
[Object: null prototype] { hash: 4, signature: 3 },
[Object: null prototype] { hash: 8, signature: 4 },
[Object: null prototype] { hash: 4, signature: 1 },
[Object: null prototype] { hash: 5, signature: 3 },
[Object: null prototype] { hash: 8, signature: 5 },
[Object: null prototype] { hash: 5, signature: 1 },
[Object: null prototype] { hash: 8, signature: 6 },
[Object: null prototype] { hash: 6, signature: 1 },
[Object: null prototype] { hash: 2, signature: 1 }
],
authorities: [],
msgType: 13
} +27ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log server_hello_done ServerHelloDone { msgType: 14 } +2ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log send flight5 true +1ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log extendedMasterSecret true true +4ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log cipher {
id: 49199,
verifyDataLength: 12,
keyLength: 16,
nonceLength: 12,
ivLength: 4,
authTagLength: 16,
nonceImplicitLength: 4,
nonceExplicitLength: 8,
name: 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
blockAlgorithm: 'aes-128-gcm',
hashAlgorithm: 'sha256',
clientWriteKey: '0x8b,0x3d,0x81,0x37,0xc4,0x51,0x45,0x59,0xb0,0x00,0x4e,0x82,0x98,0x7c,0x6b,0xc8',
serverWriteKey: '0x36,0x6d,0xb5,0xab,0x45,0xfd,0x98,0xba,0xc7,0x95,0x80,0xea,0x83,0x37,0xc0,0x16',
clientNonce: '0x2d,0x44,0xa0,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00',
serverNonce: '0x3a,0x3f,0xf4,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'
} +3ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log signatureScheme 3 1027 +2ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log raw finish packet {
header: {
contentType: 22,
protocolVersion: { major: 254, minor: 253 },
epoch: 1,
sequenceNumber: 6,
contentLen: 24
},
fragment: '0x14,0x00,0x00,0x0c,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x0c,0xcd,0xc6,0x28,0xfe,0xeb,0x94,0xb1,0xe4,0x9e,0x56,0x0f,0x3a'
} [
{
msg_type: 1,
length: 86,
message_seq: 0,
fragment_offset: 0,
fragment_length: 86,
fragment: '0xfe,0xfd,0x61,0xca,0x35,0x9e,0x04,0x36,0x97,0x21,0x9c,0x8d,0xa0,0xab,0x57,0xa2,0x30,0x28,0x0a,0xb0,0x91,0x7f,0x11,0x56,0xc7,0xad,0x7d,0x73,0x98,0x30,0xf9,0xfc,0x19,0x69,0x00,0x00,0x00,0x04,0xc0,0x2b,0xc0,0x2f,0x01,0x00,0x00,0x28,0x00,0x0e,0x00,0x07,0x00,0x04,0x00,0x07,0x00,0x01,0x00,0x00,0x0a,0x00,0x06,0x00,0x04,0x00,0x1d,0x00,0x17,0x00,0x0d,0x00,0x06,0x00,0x04,0x04,0x01,0x04,0x03,0x00,0x17,0x00,0x00,0xff,0x01,0x00,0x01,0x00'
},
{
msg_type: 2,
length: 90,
message_seq: 0,
fragment_offset: 0,
fragment_length: 90,
fragment: '0xfe,0xfd,0x61,0xca,0x35,0x9e,0xba,0x0e,0x91,0x93,0xa2,0x5f,0x7a,0x14,0xbd,0x67,0x2e,0xc8,0x90,0x1f,0x78,0x29,0x08,0x8c,0x1b,0x51,0x58,0x05,0xc9,0xe2,0x56,0x9d,0x8c,0xcd,0x20,0x92,0x9b,0xc2,0x59,0x88,0x3a,0xfc,0x5a,0x89,0x41,0x4e,0xc7,0x79,0x8a,0xc2,0xc0,0x53,0xbd,0x79,0x64,0x3e,0x24,0xd4,0xb2,0xd9,0x05,0x30,0x25,0x77,0x1e,0x90,0x57,0xc0,0x2f,0x00,0x00,0x12,0x00,0x17,0x00,0x00,0xff,0x01,0x00,0x01,0x00,0x00,0x0e,0x00,0x05,0x00,0x02,0x00,0x01,0x00'
},
{
msg_type: 11,
length: 777,
message_seq: 1,
fragment_offset: 0,
fragment_length: 777,
fragment: '0x00,0x03,0x06,0x00,0x03,0x03,0x30,0x82,0x02,0xff,0x30,0x82,0x01,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x08,0x62,0xca,0x1e,0x6c,0x00,0x5c,0x08,0x64,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x03,0x13,0x08,0x68,0x61,0x6e,0x67,0x6f,0x75,0x74,0x73,0x30,0x1e,0x17,0x0d,0x32,0x31,0x31,0x32,0x32,0x32,0x30,0x39,0x30,0x31,0x35,0x36,0x5a,0x17,0x0d,0x32,0x32,0x31,0x32,0x32,0x33,0x30,0x39,0x30,0x31,0x35,0x36,0x5a,0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x03,0x13,0x08,0x68,0x61,0x6e,0x67,0x6f,0x75,0x74,0x73,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xc5,0x63,0x91,0x6b,0x10,0xfc,0xc5,0xd1,0x02,0x45,0x47,0x3d,0x26,0x55,0xc0,0x8d,0x57,0xd3,0x3d,0x38,0x09,0x37,0x81,0x09,0x2b,0xfd,0x4b,0xf1,0x30,0x84,0x79,0xbd,0xd5,0xbf,0xa3,0x9e,0x11,0xee,0xff,0x29,0xc0,0x35,0x24,0xd9,0x18,0x5c,0x3b,0xa8,0xec,0xe5,0xd9,0x49,0xa0,0x72,0x01,0x3f,0x43,0x8a,0x00,0xc8,0x9e,0x37,0xe5,0xb9,0xd0,0xaf,0x8d,0xdf,0x10,0xba,0xcb,0x56,0x78,0x71,0x23,0x16,0xfc,0x48,0x45,0x67,0x84,0x7e,0x1a,0x7c,0x24,0x26,0xa0,0x1e,0x85,0x1f,0x95,0xe7,0x77,0xd4,0x33,0x04,0xbc,0x09,0x8f,0x58,0x8d,0x5f,0xfb,0xca,0x23,0x32,0x28,0x53,0xa7,0x1b,0x66,0x93,0x20,0xdd,0xc6,0xfc,0x2c,0x6c,0xb8,0x49,0xb2,0xe2,0x85,0x57,0x78,0x03,0xe2,0x01,0x62,0xd8,0xef,0xc8,0x19,0x21,0x47,0x59,0xf6,0xe6,0x92,0x73,0x5c,0x9c,0x06,0x50,0x8f,0xaf,0xb3,0x26,0x54,0xb7,0xf7,0x18,0x4b,0xef,0x25,0xb9,0x61,0x62,0x4f,0xa7,0xea,0x93,0x20,0xd3,0xb0,0xb3,0xd4,0xef,0x1c,0xec,0xf3,0xf1,0x25,0x5f,0xe8,0xd1,0xb0,0xc2,0xfe,0x96,0xe2,0xc3,0xa4,0xa0,0x02,0x2b,0x5c,0x98,0x05,0xa4,0x4a,0x89,0x56,0x1f,0x3b,0x7d,0x40,0xd4,0x26,0x2d,0x0d,0xef,0xed,0xdb,0x79,0x12,0x42,0x48,0xd0,0x00,0x9e,0xa4,0x22,0x76,0xfd,0xa6,0xea,0x35,0x28,0x20,0x5f,0xef,0x04,0xfc,0xaa,0x20,0xb4,0x80,0x3b,0xc4,0xdc,0x25,0x57,0xdf,0x28,0x8d,0x9c,0xbd,0x07,0x42,0xbb,0x47,0x3e,0x3d,0xdd,0xd6,0x76,0xe9,0xcf,0x46,0x40,0xdd,0x08,0x08,0x6d,0x7d,0x02,0x03,0x01,0x00,0x01,0xa3,0x57,0x30,0x55,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x02,0x84,0x30,0x13,0x06,0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0xa4,0x54,0x9f,0x04,0xd1,0x0a,0xc5,0x3b,0x84,0x2d,0x6a,0x37,0x8e,0xf6,0x63,0x49,0xb6,0x4f,0x64,0x8a,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0xab,0x32,0xa8,0xc7,0xcf,0x1c,0x32,0xeb,0xa2,0xfc,0x03,0x72,0x4e,0x13,0xce,0x72,0xff,0xa9,0xe1,0xa6,0x15,0xca,0xcb,0xe3,0x69,0x17,0xbe,0x8b,0x39,0xa6,0xad,0x98,0xc1,0x4f,0xef,0xb8,0x39,0x51,0x7c,0xcf,0xed,0x62,0x4e,0x20,0x40,0xb4,0x13,0x68,0x5d,0x2b,0xb6,0x73,0xeb,0xe9,0x7d,0x45,0xef,0xe9,0x34,0x2d,0x41,0xd8,0x45,0x79,0x9d,0x92,0x31,0x2d,0x07,0x67,0xc5,0x2e,0x8e,0x4c,0x69,0xcb,0x68,0x32,0x26,0x76,0x65,0xcd,0x4f,0xc2,0x28,0x4c,0xef,0xa7,0x57,0x2c,0x5d,0x37,0x11,0x87,0x8a,0xed,0xc6,0x0d,0xdb,0xfd,0xbd,0x12,0xab,0x07,0xfa,0xb9,0x51,0xfb,0xe4,0x8a,0x4e,0xab,0x04,0xf6,0x1b,0xfc,0x72,0xec,0x1c,0xe8,0x28,0xf9,0x72,0x18,0x4d,0xd2,0xa2,0xe5,0x9a,0x35,0x08,0x4f,0xe7,0x7f,0xe8,0x0f,0x42,0xb7,0x85,0x68,0xc8,0xfd,0x93,0x16,0x30,0x48,0x75,0x8d,0xe4,0x67,0xcf,0x1d,0x28,0xd3,0x92,0xd4,0x0b,0xb6,0x4f,0x7c,0x2d,0x63,0x14,0x1b,0x5f,0xd4,0x6d,0x48,0x75,0x42,0x76,0x4e,0xc0,0xa9,0xc5,0x0e,0x8b,0xa8,0x3d,0x0f,0x90,0x4c,0x2a,0xa4,0x91,0x76,0x48,0x7a,0xdf,0xf0,0x9f,0x27,0xa3,0x4c,0x32,0x90,0x67,0x5e,0xd4,0x41,0xe8,0x3f,0xaa,0x6a,0xe3,0xa4,0x3e,0xf2,0x6c,0x8d,0x6c,0xeb,0x38,0xa0,0x37,0x58,0x7f,0xec,0x87,0xda,0x61,0xbf,0xae,0x1c,0xeb,0x70,0x41,0x17,0xed,0x17,0x76,0x34,0x78,0x24,0x74,0x64,0x15,0x01,0x53,0xfb,0x32,0x8d,0x27,0x8c,0x48,0x09,0xa3,0x05,0x9f,0xb1,0x6a,0x15,0x3f,0x2f,0x9a,0x07'
},
{
msg_type: 12,
length: 296,
message_seq: 2,
fragment_offset: 0,
fragment_length: 296,
fragment: '0x03,0x00,0x1d,0x20,0x36,0xbf,0x07,0x89,0x38,0xbd,0x9b,0x29,0xe4,0xac,0xf9,0x64,0x64,0x8a,0x65,0x5c,0x5d,0xa8,0x68,0xc7,0x14,0x93,0xe8,0xf1,0x86,0xf1,0xc7,0xa6,0x25,0xbf,0x3b,0x24,0x04,0x01,0x01,0x00,0xbd,0x36,0xff,0x3a,0x8f,0x4f,0xa0,0x30,0x8a,0x41,0xfa,0x9f,0x4f,0x88,0xbc,0x90,0x33,0x70,0x9d,0x63,0xde,0xb4,0x31,0x8e,0x74,0xf7,0xba,0x88,0x01,0x85,0x03,0xd4,0x55,0xba,0xd1,0xfd,0x00,0xdc,0xe1,0xa4,0x5a,0x70,0x1b,0xb5,0x97,0xeb,0x0a,0x41,0x14,0xd0,0xb3,0xd6,0x74,0x19,0xf3,0x31,0xb0,0x7c,0x4c,0x3a,0xc7,0x7a,0x9c,0xab,0x33,0x09,0x15,0x69,0x76,0xf6,0xa6,0x34,0xec,0x24,0x04,0x56,0xf0,0x6b,0x45,0x49,0x73,0x68,0x67,0x91,0xf9,0xda,0x04,0xd8,0x68,0xea,0xfb,0xfb,0x9f,0x03,0x2e,0x4d,0x29,0x3e,0x6c,0xa3,0xe0,0x3c,0xb7,0xbc,0xe9,0x55,0x2f,0xb1,0xa3,0x5b,0xfa,0xa5,0x13,0xf5,0xbf,0x16,0x0c,0x23,0x10,0x33,0xdd,0x10,0xa6,0xb4,0x0a,0x2d,0x0e,0x64,0xf1,0x8c,0xa7,0x48,0x4e,0xfc,0xb6,0xaf,0x54,0x90,0xf6,0xfc,0xb5,0xf9,0xe9,0x37,0xa0,0xbb,0x19,0xe2,0x7d,0xbc,0x19,0x88,0x9a,0xa6,0x93,0xe4,0x56,0x43,0x44,0xec,0x29,0x38,0x73,0xb2,0xe8,0x74,0x75,0x36,0xad,0xe0,0x5a,0x82,0x0f,0x48,0x18,0x50,0x1d,0x28,0x37,0x0b,0x66,0xdb,0xf2,0x39,0xd3,0x13,0x01,0x5e,0x1e,0x0e,0x65,0x9b,0xbc,0x0e,0xaf,0xf5,0x41,0x68,0x88,0x90,0x79,0x13,0xe4,0x8a,0xab,0x89,0x93,0x8d,0x44,0x79,0xf4,0xea,0xd0,0xf4,0xc7,0xf0,0x85,0xa9,0xa8,0xd4,0xef,0x71,0xea,0xba,0x71,0x81,0xf2,0x5e,0x56,0xe3,0xd2,0x6a,0xc6,0xa0,0xdf,0x52,0xdc,0x55,0xd8,0xc0,0x62,0x2b,0x67,0x92,0x61,0xe2,0x10,0x2e,0xb3,0x6c,0x22,0x1c,0x99,0x16,0x71,0xdf'
},
{
msg_type: 13,
length: 25,
message_seq: 3,
fragment_offset: 0,
fragment_length: 25,
fragment: '0x02,0x01,0x40,0x00,0x12,0x04,0x03,0x08,0x04,0x04,0x01,0x05,0x03,0x08,0x05,0x05,0x01,0x08,0x06,0x06,0x01,0x02,0x01,0x00,0x00'
},
{
msg_type: 14,
length: 0,
message_seq: 4,
fragment_offset: 0,
fragment_length: 0,
fragment: '0x'
},
{
msg_type: 11,
length: 388,
message_seq: 1,
fragment_offset: 0,
fragment_length: 388,
fragment: '0x00,0x01,0x81,0x00,0x01,0x7e,0x30,0x82,0x01,0x7a,0x30,0x82,0x01,0x21,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02,0x30,0x45,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x41,0x55,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x13,0x0a,0x53,0x6f,0x6d,0x65,0x2d,0x53,0x74,0x61,0x74,0x65,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x0a,0x13,0x18,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x20,0x57,0x69,0x64,0x67,0x69,0x74,0x73,0x20,0x50,0x74,0x79,0x20,0x4c,0x74,0x64,0x30,0x1e,0x17,0x0d,0x32,0x31,0x31,0x32,0x32,0x37,0x32,0x31,0x35,0x32,0x32,0x39,0x5a,0x17,0x0d,0x33,0x31,0x31,0x32,0x32,0x37,0x32,0x31,0x35,0x32,0x32,0x39,0x5a,0x30,0x45,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x41,0x55,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x13,0x0a,0x53,0x6f,0x6d,0x65,0x2d,0x53,0x74,0x61,0x74,0x65,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x0a,0x13,0x18,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x20,0x57,0x69,0x64,0x67,0x69,0x74,0x73,0x20,0x50,0x74,0x79,0x20,0x4c,0x74,0x64,0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x09,0x9e,0x84,0x71,0xb4,0xf0,0x33,0xb6,0xc1,0x35,0x89,0xf5,0x9f,0x85,0xbd,0xdf,0x8d,0xb4,0x3a,0x91,0x45,0x63,0x04,0xc5,0x53,0x05,0x82,0x65,0xd4,0xec,0x9a,0xa0,0x01,0xc7,0xaa,0x5e,0xba,0xd0,0x2f,0x35,0xcd,0xcd,0x38,0xf7,0x9b,0x5c,0xa3,0xad,0xcf,0xe4,0xa3,0x26,0x1f,0x9f,0x91,0x23,0x06,0x14,0x9b,0x22,0xd5,0xc6,0x51,0x4a,0xa3,0x02,0x30,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02,0x03,0x47,0x00,0x30,0x44,0x02,0x20,0x4c,0xd3,0xae,0xbc,0x55,0xc8,0xa1,0x46,0x67,0x6b,0x1d,0xfb,0x1a,0x1c,0x31,0x4d,0xd2,0x71,0x54,0xfa,0xd3,0x50,0x1b,0xc8,0xb2,0x9d,0x82,0x42,0x31,0x06,0xaf,0xfd,0x02,0x20,0x1d,0x9f,0xc7,0x4f,0x66,0xeb,0xe6,0x20,0xe8,0xc0,0x57,0xc7,0xc8,0xbb,0x9c,0xb5,0xf2,0xd5,0x66,0x25,0x1e,0x1d,0xc1,0x1d,0x55,0xd8,0xea,0x05,0x02,0x7e,0x1b,0x35'
},
{
msg_type: 16,
length: 33,
message_seq: 2,
fragment_offset: 0,
fragment_length: 33,
fragment: '0x20,0x80,0x28,0xeb,0x2e,0xc8,0x3a,0x9f,0x26,0x27,0xb6,0xfe,0x7f,0x6f,0x65,0x5d,0x1c,0x9d,0x0e,0x8c,0x5e,0x9a,0xc1,0x3e,0x71,0xac,0x7d,0xe7,0x79,0xdc,0x65,0xb4,0x63'
},
{
msg_type: 15,
length: 74,
message_seq: 3,
fragment_offset: 0,
fragment_length: 74,
fragment: '0x04,0x03,0x00,0x46,0x30,0x44,0x02,0x20,0x34,0xb3,0x6f,0x17,0xbe,0xb3,0xf0,0x63,0x1d,0x80,0xa2,0x43,0x41,0x4e,0x71,0x42,0x0d,0xd1,0x57,0x06,0x31,0xf1,0x6a,0x4e,0x45,0xd1,0xd6,0xa6,0xb5,0xfe,0xfa,0x34,0x02,0x20,0x10,0xb2,0x30,0x5d,0x70,0xef,0xee,0x07,0xc7,0x06,0xaf,0x5b,0x9f,0xe5,0x44,0x13,0x08,0xb6,0x0f,0x4e,0x2d,0x35,0xa8,0xc4,0x78,0xc8,0x6f,0xd0,0xe9,0xc1,0x53,0xf7'
},
{
msg_type: 20,
length: 12,
message_seq: 4,
fragment_offset: 0,
fragment_length: 12,
fragment: '0xcd,0xc6,0x28,0xfe,0xeb,0x94,0xb1,0xe4,0x9e,0x56,0x0f,0x3a'
}
] +3ms
werift-dtls : packages/dtls/src/flight/client/flight5.ts : log finished {
id: 49199,
verifyDataLength: 12,
keyLength: 16,
nonceLength: 12,
ivLength: 4,
authTagLength: 16,
nonceImplicitLength: 4,
nonceExplicitLength: 8,
name: 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
blockAlgorithm: 'aes-128-gcm',
hashAlgorithm: 'sha256',
clientWriteKey: '0x8b,0x3d,0x81,0x37,0xc4,0x51,0x45,0x59,0xb0,0x00,0x4e,0x82,0x98,0x7c,0x6b,0xc8',
serverWriteKey: '0x36,0x6d,0xb5,0xab,0x45,0xfd,0x98,0xba,0xc7,0x95,0x80,0xea,0x83,0x37,0xc0,0x16',
clientNonce: '0x2d,0x44,0xa0,0x04,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06',
serverNonce: '0x3a,0x3f,0xf4,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'
} +7ms
werift/sctp/sctp receive init InitChunk {
flags: 0,
_body: <Buffer 3a 05 79 c4 00 50 00 00 ff ff ff ff 27 01 dd 1c c0 00 00 04 80 08 00 06 82 c0>,
initiateTag: 973437380,
advertisedRwnd: 5242880,
outboundStreams: 65535,
inboundStreams: 65535,
initialTsn: 654433564,
params: [ [ 49152, ], [ 32776, <Buffer 82 c0> ] ]
} +0ms
werift/sctp/sctp send initAck InitAckChunk {
flags: 0,
_body: ,
initiateTag: 1738840112,
advertisedRwnd: 1048576,
outboundStreams: 65535,
inboundStreams: 65535,
initialTsn: 4026905075,
params: [
[ 49152, ],
[ 32776, <Buffer c0 82> ],
[
7,
<Buffer 61 ca 35 9f 48 ee 1c 4b ae 74 f5 d6 eb d7 60 e9 ec 03 d6 5a 74 5b 87 05>
]
]
} +2ms
werift-dtls : packages/dtls/record/receive.ts : log change cipher spec +0ms
werift-dtls : packages/dtls/record/receive.ts : log decrypt handshake +0ms
werift-dtls : packages/dtls/src/client.ts : log handleHandshakes [ 20 ] +121ms
werift-dtls : packages/dtls/src/client.ts : log dtls connected +0ms
werift:packages/webrtc/src/transport/dtls.ts selected SRTP Profile 1 +0ms
werift:packages/webrtc/src/transport/dtls.ts dtls connected +4ms
werift:packages/webrtc/src/peerConnection.ts dtls connected +359ms
werift/sctp/sctp send init InitChunk {
flags: 0,
_body: ,
initiateTag: 1738840112,
advertisedRwnd: 1048576,
outboundStreams: 65535,
inboundStreams: 65535,
initialTsn: 4026905075,
params: [ [ 49152, ], [ 32776, <Buffer c0 82> ] ]
} +12ms
werift/webrtc/transport/sctp DCEP 111 50 <Buffer 03 00 00 00 00 00 00 00 00 06 00 12 70 75 73 68 65 73 77 65 62 72 74 63 2d 64 61 74 61 63 68 61 6e 6e 65 6c> +0ms
werift/webrtc/transport/sctp DATA_CHANNEL_OPEN {
channelType: 0,
reliability: 0,
streamId: 111,
label: 'pushes',
protocol: 'webrtc-datachannel'
} +0ms
werift/webrtc/datachannel change state open +0ms
werift/webrtc/transport/sctp DCEP 113 50 <Buffer 03 00 00 00 00 00 00 00 00 0b 00 12 63 6f 6c 6c 65 63 74 69 6f 6e 73 77 65 62 72 74 63 2d 64 61 74 61 63 68 61 6e 6e 65 6c> +0ms
werift/webrtc/transport/sctp DATA_CHANNEL_OPEN {
channelType: 0,
reliability: 0,
streamId: 113,
label: 'collections',
protocol: 'webrtc-datachannel'
} +0ms
werift/webrtc/datachannel change state open +1ms
werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 ed 6a 91 31 db 2c 37 e8 b9 05 42 ac 00 06 00 15 51 4e 49 39 57 59 59 47 59 33 53 55 56 4b 46 55 3a 37 34 34 31 00 00 00 00 24 ... 50 more bytes> +401ms
werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 ed 6a 91 31 db 2c 37 e8 b9 05 42 ac 00 06 00 15 51 4e 49 39 57 59 59 47 59 33 53 55 56 4b 46 55 3a 37 34 34 31 00 00 00 00 24 ... 50 more bytes> +801ms
werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 ed 6a 91 31 db 2c 37 e8 b9 05 42 ac 00 06 00 15 51 4e 49 39 57 59 59 47 59 33 53 55 56 4b 46 55 3a 37 34 34 31 00 00 00 00 24 ... 50 more bytes> +2s
werift-ice:packages/ice/src/stun/transaction.ts retry failed times:7 maxLimit:7 +0ms
werift-ice : packages/ice/src/ice.ts : log failure case undefined +6s
werift-ice : packages/ice/src/ice.ts : log CandidatePairState.FAILED +0ms
werift:packages/webrtc/src/peerConnection.ts connectionStateChange connected +12s
werift/webrtc/transport/sctp DCEP 1 50 <Buffer 02> +12s
werift/webrtc/transport/sctp DATA_CHANNEL_ACK +0ms
werift/webrtc/datachannel change state open +12s
werift/webrtc/transport/sctp DCEP 111 50 <Buffer 03 00 00 00 00 00 00 00 00 06 00 12 70 75 73 68 65 73 77 65 62 72 74 63 2d 64 61 74 61 63 68 61 6e 6e 65 6c> +303ms
werift/webrtc/transport/sctp DCEP 113 50 <Buffer 03 00 00 00 00 00 00 00 00 0b 00 12 63 6f 6c 6c 65 63 74 69 6f 6e 73 77 65 62 72 74 63 2d 64 61 74 61 63 68 61 6e 6e 65 6c> +1ms
/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/transport/sctp.js:52
throw new Error();
^

Error
at Object.RTCSctpTransport.datachannelReceive [as execute] (/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/transport/sctp.js:52:43)
at Event.execute (/Users/me/Source/webrtctest/node_modules/rx.mini/lib/core/index.js:17:30)
at SCTP.receive (/Users/me/Source/webrtctest/node_modules/werift/lib/sctp/src/sctp.js:625:24)
at SCTP.receiveDataChunk (/Users/me/Source/webrtctest/node_modules/werift/lib/sctp/src/sctp.js:475:18)
at SCTP.receiveChunk (/Users/me/Source/webrtctest/node_modules/werift/lib/sctp/src/sctp.js:263:22)
at SCTP.handleData (/Users/me/Source/webrtctest/node_modules/werift/lib/sctp/src/sctp.js:232:24)
at RTCDtlsTransport.SCTP.transport.onData [as dataReceiver] (/Users/me/Source/webrtctest/node_modules/werift/lib/sctp/src/sctp.js:197:18)
at Object.execute (/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/transport/dtls.js:89:22)
at Event.execute (/Users/me/Source/webrtctest/node_modules/rx.mini/lib/core/index.js:17:30)
at IceTransport.DtlsSocket.udpOnMessage [as onData] (/Users/me/Source/webrtctest/node_modules/werift/lib/dtls/src/socket.js:70:45)

Process finished with exit code 1

Whether it can transfer the raw stream to the Web side

Get the original stream through ffmpeg and add it to the channel for Web-based presentation

I saw the ffmpeg example, which specifies the encoding format, but I need the browser to negotiate the encoding format with it

exp:

    const video= ffmpeg('/dev/video0')
        .size(`480x240`)
        .outputOptions(['-pix_fmt yuv420p'])

    const audio = ffmpeg("plughw:1,0")
        .inputFormat("alsa")
        .audioChannels(1)
        .audioFrequency(48000)
        .audioCodec("pcm_s16le")
        .outputFormat("s16le")

        .format("rawvideo")

useSdesMid causes negotiation with Google Camera to fail

This change introduced a bug in the scrypted google camera plugin.
This likely isn't a bug in werift. removing the extensions allows the webrtc connection to negotiate successfully (google returns 500 error otherwise).

f934e1a#diff-3bc78b20b7ffa3340be89f975e4457f6b8a11a11f67789d5554286e6ab0780caR1549

What are your thoughts on using conservative defaults to prevent issues like this? There are probably various sdp/webrtc consumers out there that will choke on unexpected data.

Here is my workaround in my code:

  const ret = new RTCPeerConnection({
          bundlePolicy: setup.configuration?.bundlePolicy as BundlePolicy,
          codecs: {
              audio: [
                  ...requiredAudioCodecs,
              ],
              video: [
                  requiredVideoCodec,
              ],
          },
          iceServers: getWeriftIceServers(setup.configuration),
      });

      ret.config.headerExtensions = {
          video: [],
          audio: [],
      };

MediaDescription defines property "sctpMap" but when setting a description looks for "sctpmap"

When setting a remote description, we look for the "sctpmap" property:

https://github.com/shinyoshiaki/werift-webrtc/blob/develop/packages/webrtc/src/sdp.ts#L223

But the property on the MediaDescription type is named "sctpMap":

https://github.com/shinyoshiaki/werift-webrtc/blob/develop/packages/webrtc/src/sdp.ts#L356

So if you try to set a remote SDP like so:

v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 2 1
a=msid-semantic: WMS 17156406933747196835/3212739396 virtual-6666
a=ice-lite
m=audio 19305 UDP/TLS/RTP/SAVPF 96
c=IN IP4 <redacted>
a=rtcp:9 IN IP4 0.0.0.0
a=candidate: 1 udp 2113939711 2607:f8b0:400e:c03::7f 19305 typ host generation 0
a=candidate: 1 tcp 2113939710 2607:f8b0:400e:c03::7f 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113939709 2607:f8b0:400e:c03::7f 443 typ host generation 0
a=candidate: 1 udp 2113932031 74.125.197.127 19305 typ host generation 0
a=candidate: 1 tcp 2113932030 74.125.197.127 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113932029 74.125.197.127 443 typ host generation 0
a=ice-ufrag:ZYYVZ8WXE65U5BKY
a=ice-pwd:TII1ZWXJ56MILBHWDVZTELNA
a=fingerprint:sha-256 F3:67:F7:32:B9:1D:E5:41:F2:DF:1B:05:89:5E:5C:8D:A3:B3:23:16:97:2D:EF:89:C9:BA:23:63:E1:27:04:86
a=setup:passive
a=mid:0
a=sendrecv
a=msid:virtual-6666 virtual-6666
a=rtcp-mux
a=rtpmap:96 opus/48000/2
a=fmtp:96 minptime=10;useinbandfec=1
a=ssrc:6666 cname:6666
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:ZYYVZ8WXE65U5BKY
a=ice-pwd:TII1ZWXJ56MILBHWDVZTELNA
a=fingerprint:sha-256 F3:67:F7:32:B9:1D:E5:41:F2:DF:1B:05:89:5E:5C:8D:A3:B3:23:16:97:2D:EF:89:C9:BA:23:63:E1:27:04:86
a=setup:passive
a=mid:1
a=sendrecv
a=msid:17156406933747196835/3212739396 17156406933747196835/3212739396
a=rtcp-mux
a=rtpmap:97 VP8/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
a=ssrc:3212739396 cname:3212739396
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:ZYYVZ8WXE65U5BKY
a=ice-pwd:TII1ZWXJ56MILBHWDVZTELNA
a=fingerprint:sha-256 F3:67:F7:32:B9:1D:E5:41:F2:DF:1B:05:89:5E:5C:8D:A3:B3:23:16:97:2D:EF:89:C9:BA:23:63:E1:27:04:86
a=setup:passive
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

You will get:

TypeError: Cannot set properties of undefined (setting '5000')
    at /Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/sdp.js:190:68
    at Array.forEach (<anonymous>)
    at /Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/sdp.js:99:33
    at Array.forEach (<anonymous>)
    at Function.parse (/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/sdp.js:78:21)
    at RTCPeerConnection.setRemoteDescription (/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/peerConnection.js:474:52)
    at doIt (/Users/me/Source/webrtctest/dist/rtc.js:112:14)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

TypeError: Cannot read property 'rtp' of undefined on `setRemoteDescription`

I'm currently trying to make a weird media server thing as a little experiment, though I keep getting the following error on setRemoteDescription:

    at RTCPeerConnection.remoteRtp (/home/MYUSERNAME/code/JS/project/chat/chat/node_modules/werift/lib/webrtc/src/peerConnection.js:382:26)
    at /home/MYUSERNAME/code/JS/project/chat/chat/node_modules/werift/lib/webrtc/src/peerConnection.js:533:37
    at Array.forEach (<anonymous>)
    at RTCPeerConnection.setRemoteDescription (/home/MYUSERNAME/code/JS/project/chat/chat/node_modules/werift/lib/webrtc/src/peerConnection.js:530:27)
    at processTicksAndRejections (internal/process/task_queues.js:93:5)
    at async GatewayRTCConnection.answer (/home/MYUSERNAME/code/JS/project/chat/chat/api/v2/gateway/index.js:24:9)
    at async WebSocket.<anonymous> (/home/MYUSERNAME/code/JS/project/chat/chat/api/v2/gateway/index.js:169:37)

Here is the serverside handler for getting an offer from the client.

let isNewConnection = true;
if (ws.rtc) {
    isNewConnection = false;
} else {
    ws.rtc = new GatewayRTCConnection(ws, this);
}

if (isNewConnection) {
    ws.rtc.connection.onTransceiver.subscribe(async (transceiver) => {
        const [track] = await transceiver.onTrack.asPromise();
        this.inChannel(channel._id, (otherWs) => {
            if (!this.clientRTCReady(otherWs)) return;
            if (otherWs.session.sessionId === ws.session.sessionId) return; // Don't perform the actions below on ourselves

            otherWs.rtc.addTrack(track);
            otherWs.rtc.renegotiate();
        });
    });
}

ws.send(this.packet("EVENT_VOICE_CONNECTION_ANSWER", {
    answer: await ws.rtc.answer(offer)
}));

if (isNewConnection) {
    this.inChannel(channel._id, (otherWs) => {
        if (!this.clientRTCReady(otherWs)) return;
        if (otherWs.session.sessionId === ws.session.sessionId) return; // Don't perform the actions below on ourselves
        
        const otherReceivers = otherWs.rtc.connection.getReceivers();
        for (let i = 0; i < otherReceivers.length; i++) {
            const otherRecevier = otherReceivers[i];
            ws.rtc.addTrack(otherRecevier.tracks[0]);
        }
    });
    ws.rtc.renegotiate();
}

This is the small GatewayRTCConnection wrapper I made to simplify the code a little:

class GatewayRTCConnection {
    constructor(ws, server) {
        this.ws = ws;
        this.server = server;

        this.connection = new werift.RTCPeerConnection();
        this.connection.onnegotiationneeded.subscribe(() => this.renegotiate);
    }

    async answer(offer) {
        await this.connection.setRemoteDescription(offer);
        await this.connection.setLocalDescription(await this.connection.createAnswer());
        return this.connection.localDescription;
    }

    async addTrack(track) {
        if (!track) return;
        this.connection.addTrack(track);
    }

    async renegotiate() {
        this.ws.send(this.server.packet("EVENT_RENEGOTIATE_REQUIRED", {}));
    }
}

I inspected it a little and found that one of the transceivers just does not have an mLineIndex, which is used in remoteRtp. I assume it's because I'm adding tracks myself to the connection, but I'm not sure what to do.
Note that it works fine with 2 users, as soon as the new user tries to connect, it generates this error.

Handling of `remoteIsLite` seems incorrect

  • iceControlling is set to true in setLocalDescription here if this.iceTransport.connection.remoteIsLite is true
  • iceControlling is set to true in setRemoteDescription here if media.iceParams?.iceLite is true

The problem is that remoteIsLite seems not to be set in the second case. This means that we end up with no controlling agent if we first setRemoteDescription and then setLocalDescription.

Maybe it is enough to set remoteIsLite = true in the second case?

reuse inactive m-line

#29 の実装には問題があったので一旦コードから削除した。
再度実装し直したい

Sending RTP packets from nodejs client to browser does not work

Hi!

I'm trying to send RTP packets from NodeJS client using werift-webrtc, to browser client using browser webrtc API. My code is basically the same as in sendonly example, the only difference is I spawn ffmpeg process instead of gstreamer.

I was testing the code with Brave (chromium), Firefox and Edge and for none of them sending video worked. I also checked webrtc-internal page and in statistics I noticed that RTP packets were received and all of them were lost.

Sending video worked, when the other client was another NodeJS client and not a browser one.

What do I need to do to send video to browser? Or maybe is it not possible at the moment?

Audio Data but no Video Data

Version: 0.14.2-debug2b
Node: v16.13.1

The following code:

const pc = new RTCPeerConnection({
        codecs: {
            audio: [
                new RTCRtpCodecParameters({
                    mimeType: "audio/opus",
                    clockRate: 48000,
                    channels: 2,
                })
            ],
            video: [
                new RTCRtpCodecParameters({
                    mimeType: "video/VP8",
                    clockRate: 90000,
                    rtcpFeedback: [
                        { type: "ccm", parameter: "fir" },
                        { type: "nack" },
                        { type: "nack", parameter: "pli" },
                        { type: "goog-remb" },
                    ],
                })
            ],
        }
    });

    const audioTransceiver = pc.addTransceiver("audio", {direction: "recvonly"});
    audioTransceiver.onTrack.subscribe((track) => {
        audioTransceiver.sender.replaceTrack(track); //this line will be hit
        track.onReceiveRtp.subscribe((rtp) => {
            console.log('audio data'); //this line will be hit
        });
    });

    const videoTransceiver = pc.addTransceiver("video", {direction: "recvonly"});
    videoTransceiver.onTrack.subscribe((track) => {
        videoTransceiver.sender.replaceTrack(track); //this line will be hit
        track.onReceiveRtp.subscribe((rtp) => {
            console.log('video data'); //this line will not be hit
        });
        track.onReceiveRtcp.subscribe((rtp) => {
            console.log('video data'); //this line will not be hit
        });
        track.onReceiveRtp.once((rtp) => {
            setInterval(() => videoTransceiver.receiver.sendRtcpPLI(track.ssrc!), 2000); //this line will not be hit
        });
    });

    pc.createDataChannel('dataSendChannel', {id: 1});

    let offer = await pc.createOffer();
    await pc.setLocalDescription(offer);

    console.log(offer.sdp);

    let answerSdp = <get answer from remote service>;

    console.log(answerSdp);
    await pc.setRemoteDescription({
            type: 'answer',
            sdp: answerSdp
        });

    console.log('answer applied');

Will result in a successful connection being established and audio data will start being received. However, no video data is ever received. If using a web browser the video comes through perfectly.

I have added the complete output of the program including debug logs. I can definitely see errors like werift-ice:packages/ice/src/stun/transaction.ts retry failed times:7 maxLimit:7 +0ms but have no idea what they mean.

  werift/webrtc/utils iceOptions {
  stunServer: [ 'stun.l.google.com', 19302 ],
  turnServer: undefined,
  turnUsername: undefined,
  turnPassword: undefined
} +0ms
  werift:packages/webrtc/src/peerConnection.ts iceGatheringStateChange new +0ms
  werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange new +0ms
  werift:packages/webrtc/src/peerConnection.ts signalingStateChange have-local-offer +29ms
  werift:packages/webrtc/src/peerConnection.ts iceGatheringStateChange gathering +1ms
  werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange completed +166ms
  werift:packages/webrtc/src/peerConnection.ts iceGatheringStateChange complete +0ms
v=0
o=- 27163183 0 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic:WMS *
m=audio 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=ice-ufrag:4171
a=ice-pwd:b67ad4b731dc4f9d23c292
a=ice-options:trickle
a=fingerprint:sha-256 B7:01:87:42:A0:2C:60:98:D8:86:DA:2C:A5:3A:31:7C:B3:79:54:F4:C4:A6:9F:DE:DB:C7:1A:51:25:FF:7D:D3
a=setup:actpass
a=recvonly
a=mid:0
a=msid:8509b42c-b6bb-4edc-98e7-ff4b3687c39a 3d8ec64e-5b30-4e6b-86bb-e1927086c276
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:3585382150 cname:6bd88e2c-6c8a-4d61-8c7e-bdaa0dd97471
a=rtpmap:96 opus/48000/2
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=ice-ufrag:4171
a=ice-pwd:b67ad4b731dc4f9d23c292
a=ice-options:trickle
a=fingerprint:sha-256 B7:01:87:42:A0:2C:60:98:D8:86:DA:2C:A5:3A:31:7C:B3:79:54:F4:C4:A6:9F:DE:DB:C7:1A:51:25:FF:7D:D3
a=setup:actpass
a=recvonly
a=mid:1
a=msid:84255785-386f-4360-a389-ad66082cca66 a766083c-2e8b-4083-94fb-c8d6682266d8
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:1714994459 cname:6bd88e2c-6c8a-4d61-8c7e-bdaa0dd97471
a=rtpmap:97 VP8/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:4171
a=ice-pwd:b67ad4b731dc4f9d23c292
a=ice-options:trickle
a=fingerprint:sha-256 B7:01:87:42:A0:2C:60:98:D8:86:DA:2C:A5:3A:31:7C:B3:79:54:F4:C4:A6:9F:DE:DB:C7:1A:51:25:FF:7D:D3
a=setup:actpass
a=mid:2
a=sctp-port:5000
a=max-message-size:65536

v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 2 1
a=msid-semantic: WMS 16116520851131665030/3212739396 virtual-6666
a=ice-lite
m=audio 19305 UDP/TLS/RTP/SAVPF 96
c=IN IP4 <redacted>
a=rtcp:9 IN IP4 0.0.0.0
a=candidate: 1 udp 2113939711 2607:f8b0:400e:c0a::7f 19305 typ host generation 0
a=candidate: 1 tcp 2113939710 2607:f8b0:400e:c0a::7f 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113939709 2607:f8b0:400e:c0a::7f 443 typ host generation 0
a=candidate: 1 udp 2113932031 172.253.117.127 19305 typ host generation 0
a=candidate: 1 tcp 2113932030 172.253.117.127 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113932029 172.253.117.127 443 typ host generation 0
a=ice-ufrag:5PTJZ9W/9VAVMSZJ
a=ice-pwd:ZYWGZUFHS2PPREUMKNLDTDAU
a=fingerprint:sha-256 6A:F0:32:31:30:C4:9B:ED:81:D4:93:DF:56:16:06:DC:79:6F:9D:EA:03:16:BF:C4:EA:D0:19:7F:6D:10:6E:5D
a=setup:passive
a=mid:0
a=sendrecv
a=msid:virtual-6666 virtual-6666
a=rtcp-mux
a=rtpmap:96 opus/48000/2
a=fmtp:96 minptime=10;useinbandfec=1
a=ssrc:6666 cname:6666
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:5PTJZ9W/9VAVMSZJ
a=ice-pwd:ZYWGZUFHS2PPREUMKNLDTDAU
a=fingerprint:sha-256 6A:F0:32:31:30:C4:9B:ED:81:D4:93:DF:56:16:06:DC:79:6F:9D:EA:03:16:BF:C4:EA:D0:19:7F:6D:10:6E:5D
a=setup:passive
a=mid:1
a=sendrecv
a=msid:16116520851131665030/3212739396 16116520851131665030/3212739396
a=rtcp-mux
a=rtpmap:97 VP8/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
a=ssrc:3212739396 cname:3212739396
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:5PTJZ9W/9VAVMSZJ
a=ice-pwd:ZYWGZUFHS2PPREUMKNLDTDAU
a=fingerprint:sha-256 6A:F0:32:31:30:C4:9B:ED:81:D4:93:DF:56:16:06:DC:79:6F:9D:EA:03:16:BF:C4:EA:D0:19:7F:6D:10:6E:5D
a=setup:passive
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

  werift:packages/webrtc/src/peerConnection.ts negotiated codecs [
  RTCRtpCodecParameters {
    rtcpFeedback: [],
    mimeType: 'audio/opus',
    channels: 2,
    clockRate: 48000,
    payloadType: 96,
    parameters: 'minptime=10;useinbandfec=1'
  }
] +1s
  werift:packages/webrtc/src/media/router.ts registerRtpReceiverBySsrc {
  muxId: '0',
  rtcp: undefined,
  codecs: [
    RTCRtpCodecParameters {
      rtcpFeedback: [],
      mimeType: 'audio/opus',
      channels: 2,
      clockRate: 48000,
      payloadType: 96,
      parameters: 'minptime=10;useinbandfec=1'
    }
  ],
  headerExtensions: [],
  encodings: [ RTCRtpCodingParameters { ssrc: 6666, payloadType: 96 } ]
} +0ms
  werift:packages/webrtc/src/media/rtpSender.ts replaceTrack ssrc 6666 rid undefined +0ms
  werift:packages/webrtc/src/media/rtpReceiver.ts twcc support false +0ms
  werift:packages/webrtc/src/peerConnection.ts negotiated codecs [
  RTCRtpCodecParameters {
    rtcpFeedback: [
      [RTCRtcpFeedback],
      [RTCRtcpFeedback],
      [RTCRtcpFeedback],
      [RTCRtcpFeedback]
    ],
    mimeType: 'video/VP8',
    channels: undefined,
    clockRate: 90000,
    payloadType: 97
  }
] +3ms
  werift:packages/webrtc/src/media/router.ts registerRtpReceiverBySsrc {
  muxId: '1',
  rtcp: undefined,
  codecs: [
    RTCRtpCodecParameters {
      rtcpFeedback: [Array],
      mimeType: 'video/VP8',
      channels: undefined,
      clockRate: 90000,
      payloadType: 97
    }
  ],
  headerExtensions: [],
  encodings: [ RTCRtpCodingParameters { ssrc: 3212739396, payloadType: 97 } ]
} +2ms
  werift:packages/webrtc/src/media/rtpSender.ts replaceTrack ssrc 3212739396 rid undefined +3ms
  werift:packages/webrtc/src/media/rtpReceiver.ts twcc support false +2ms
  werift:packages/webrtc/src/peerConnection.ts connectionStateChange connecting +1ms
  werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange checking +0ms
  werift-ice : packages/ice/src/ice.ts : log start connect ice +0ms
  werift-ice : packages/ice/src/ice.ts : log check start Candidate {
  foundation: '',
  component: 1,
  transport: 'udp',
  priority: 2113932031,
  host: '172.253.117.127',
  port: 19305,
  type: 'host',
  relatedAddress: undefined,
  relatedPort: undefined,
  tcptype: undefined,
  generation: undefined
} +1ms
  werift:packages/webrtc/src/peerConnection.ts signalingStateChange stable +4ms
answer applied
  werift-ice : packages/ice/src/ice.ts : log check start Candidate {
  foundation: '',
  component: 1,
  transport: 'udp',
  priority: 2113939711,
  host: '2607:f8b0:400e:c0a::7f',
  port: 19305,
  type: 'host',
  relatedAddress: undefined,
  relatedPort: undefined,
  tcptype: undefined,
  generation: undefined
} +23ms
  werift-ice : packages/ice/src/ice.ts : log response Message {
  messageMethod: 1,
  messageClass: 256,
  transactionId: <Buffer 76 0c 40 71 b2 19 53 15 83 6a e4 92>,
  attributes: {
    USERNAME: '5PTJZ9W/9VAVMSZJ:4171',
    'XOR-MAPPED-ADDRESS': [ '174.95.161.246', 51621 ],
    'MESSAGE-INTEGRITY': <Buffer a8 34 cf ec 91 e0 d8 d5 41 b3 46 0f 7e 75 55 33 0a b1 b0 74>,
    FINGERPRINT: 542204007
  }
} [ '172.253.117.127', 19305 ] +41ms
  werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 19 da 65 c1 39 b1 10 cc a6 f8 c2 54 00 06 00 15 35 50 54 4a 5a 39 57 2f 39 56 41 56 4d 53 5a 4a 3a 34 31 37 31 00 00 00 00 24 ... 50 more bytes> +0ms
  werift-ice : packages/ice/src/ice.ts : log ICE completed +60ms
  werift:packages/webrtc/src/peerConnection.ts iceConnectionStateChange connected +124ms
  werift:packages/webrtc/src/peerConnection.ts ice connected +0ms
  werift-dtls : packages/dtls/src/socket.ts : log  support srtpProfiles [ 7, 1 ] +0ms
  werift-dtls : packages/dtls/src/client.ts : log  start client +0ms
  werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 19 da 65 c1 39 b1 10 cc a6 f8 c2 54 00 06 00 15 35 50 54 4a 5a 39 57 2f 39 56 41 56 4d 53 5a 4a 3a 34 31 37 31 00 00 00 00 24 ... 50 more bytes> +99ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [ 2 ] +164ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  serverHello 49199 +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  selected cipherSuite 49199 +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  RenegotiationIndication +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  selected srtp profile 1 +0ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [ 11 ] +1ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [ 12 ] +1ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [] +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  handshake certificate Certificate {
  certificateList: [
    <Buffer 30 82 02 ff 30 82 01 e7 a0 03 02 01 02 02 08 07 9d 46 a2 5f d0 c2 b5 30 0d 06 09 2a 86 48 86 f7 0d 01 01 0b 05 00 30 13 31 11 30 0f 06 03 55 04 03 13 ... 721 more bytes>
  ],
  msgType: 11
} +1ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  ServerKeyExchange ServerKeyExchange {
  ellipticCurveType: 3,
  namedCurve: 29,
  publicKeyLength: 32,
  publicKey: <Buffer d9 6f 11 b9 8d da 9b 1f b4 72 10 c1 9e 95 46 06 55 bc d9 ca b6 3c 27 6d 25 1d 97 a1 1f bf 13 43>,
  hashAlgorithm: 4,
  signatureAlgorithm: 1,
  signatureLength: 256,
  signature: <Buffer 06 41 91 65 fa c5 87 46 a9 e6 50 a8 b7 85 f3 cb e0 33 cc b2 79 e3 1e 28 ea 7f b0 da d0 a5 ef 31 17 2f 16 fc 66 4b ef 90 2c 10 4a 74 31 41 4f bf 11 1a ... 206 more bytes>,
  msgType: 12
} +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  selected curve 29 +0ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [ 13 ] +14ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [ 14 ] +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  certificate_request ServerCertificateRequest {
  certificateTypes: [ 1, 64 ],
  signatures: [
    [Object: null prototype] { hash: 4, signature: 3 },
    [Object: null prototype] { hash: 8, signature: 4 },
    [Object: null prototype] { hash: 4, signature: 1 },
    [Object: null prototype] { hash: 5, signature: 3 },
    [Object: null prototype] { hash: 8, signature: 5 },
    [Object: null prototype] { hash: 5, signature: 1 },
    [Object: null prototype] { hash: 8, signature: 6 },
    [Object: null prototype] { hash: 6, signature: 1 },
    [Object: null prototype] { hash: 2, signature: 1 }
  ],
  authorities: [],
  msgType: 13
} +14ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  server_hello_done ServerHelloDone { msgType: 14 } +1ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  send flight5 true +0ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  extendedMasterSecret true true +2ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  cipher {
  id: 49199,
  verifyDataLength: 12,
  keyLength: 16,
  nonceLength: 12,
  ivLength: 4,
  authTagLength: 16,
  nonceImplicitLength: 4,
  nonceExplicitLength: 8,
  name: 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
  blockAlgorithm: 'aes-128-gcm',
  hashAlgorithm: 'sha256',
  clientWriteKey: '0x0f,0x12,0xe0,0x18,0xe4,0x95,0xbf,0x38,0xe6,0x18,0xe5,0xb2,0x6d,0x66,0x6b,0x03',
  serverWriteKey: '0x4a,0x45,0xdf,0xdc,0x8d,0xa5,0x6a,0x56,0xae,0x13,0x62,0x80,0xd1,0xb2,0xff,0xf6',
  clientNonce: '0x6f,0xc0,0x86,0xe0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00',
  serverNonce: '0x6a,0x54,0x2a,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'
} +2ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  signatureScheme 3 1027 +1ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  raw finish packet {
  header: {
    contentType: 22,
    protocolVersion: { major: 254, minor: 253 },
    epoch: 1,
    sequenceNumber: 6,
    contentLen: 24
  },
  fragment: '0x14,0x00,0x00,0x0c,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x0c,0x97,0xcc,0xb6,0x89,0xf9,0x95,0xcd,0x9c,0x71,0x64,0xa1,0x79'
} [
  {
    msg_type: 1,
    length: 86,
    message_seq: 0,
    fragment_offset: 0,
    fragment_length: 86,
    fragment: '0xfe,0xfd,0x61,0xbe,0x15,0xc6,0xc0,0x83,0x13,0x2c,0x59,0x86,0xa1,0xcf,0x99,0x9c,0x22,0x5c,0x51,0xd9,0x42,0xc8,0x34,0x72,0xbc,0x16,0x26,0x7d,0x18,0xab,0x1e,0xe4,0xc0,0x5f,0x00,0x00,0x00,0x04,0xc0,0x2b,0xc0,0x2f,0x01,0x00,0x00,0x28,0x00,0x0e,0x00,0x07,0x00,0x04,0x00,0x07,0x00,0x01,0x00,0x00,0x0a,0x00,0x06,0x00,0x04,0x00,0x1d,0x00,0x17,0x00,0x0d,0x00,0x06,0x00,0x04,0x04,0x01,0x04,0x03,0x00,0x17,0x00,0x00,0xff,0x01,0x00,0x01,0x00'
  },
  {
    msg_type: 2,
    length: 90,
    message_seq: 0,
    fragment_offset: 0,
    fragment_length: 90,
    fragment: '0xfe,0xfd,0x61,0xbe,0x15,0xc6,0xd3,0x59,0xd0,0xf8,0x84,0x33,0x87,0xfe,0xfb,0x15,0x52,0xaa,0x88,0xb7,0x12,0xa8,0x08,0xcb,0x66,0x6a,0xf1,0x26,0x66,0x7c,0x4c,0xc9,0xf8,0x75,0x20,0x9c,0x6e,0x66,0x1e,0xfb,0x68,0xea,0x23,0xc0,0xae,0xc0,0x7a,0x14,0x01,0x4e,0x7d,0x4d,0xd4,0x07,0xb6,0x60,0x34,0xad,0x35,0x60,0xa8,0x21,0xce,0xab,0xf3,0xca,0xa7,0xc0,0x2f,0x00,0x00,0x12,0x00,0x17,0x00,0x00,0xff,0x01,0x00,0x01,0x00,0x00,0x0e,0x00,0x05,0x00,0x02,0x00,0x01,0x00'
  },
  {
    msg_type: 11,
    length: 777,
    message_seq: 1,
    fragment_offset: 0,
    fragment_length: 777,
    fragment: '0x00,0x03,0x06,0x00,0x03,0x03,0x30,0x82,0x02,0xff,0x30,0x82,0x01,0xe7,0xa0,0x03,0x02,0x01,0x02,0x02,0x08,0x07,0x9d,0x46,0xa2,0x5f,0xd0,0xc2,0xb5,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x03,0x13,0x08,0x68,0x61,0x6e,0x67,0x6f,0x75,0x74,0x73,0x30,0x1e,0x17,0x0d,0x32,0x31,0x31,0x32,0x31,0x35,0x30,0x39,0x31,0x38,0x34,0x36,0x5a,0x17,0x0d,0x32,0x32,0x31,0x32,0x31,0x36,0x30,0x39,0x31,0x38,0x34,0x36,0x5a,0x30,0x13,0x31,0x11,0x30,0x0f,0x06,0x03,0x55,0x04,0x03,0x13,0x08,0x68,0x61,0x6e,0x67,0x6f,0x75,0x74,0x73,0x30,0x82,0x01,0x22,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x01,0x05,0x00,0x03,0x82,0x01,0x0f,0x00,0x30,0x82,0x01,0x0a,0x02,0x82,0x01,0x01,0x00,0xa8,0x5e,0x7b,0xd1,0xef,0x2a,0x95,0xac,0xf0,0x8c,0x0f,0xb9,0xd4,0x79,0xa0,0x58,0x2e,0xfd,0x06,0xfa,0xe1,0x48,0x79,0x67,0x52,0x98,0x9a,0x02,0x4d,0xac,0x7d,0x3e,0x8a,0x37,0x69,0x21,0x26,0x58,0x1f,0x1e,0xed,0x70,0xbb,0x6a,0x0d,0x2d,0xf4,0xaa,0x33,0x07,0xb8,0xcf,0xf7,0x77,0x3f,0x70,0x4c,0x61,0xaa,0x32,0x5e,0xe2,0x55,0x9a,0x37,0xfd,0xc9,0x74,0xa4,0xc5,0xc6,0x5b,0x3b,0xf9,0x45,0xa6,0x30,0x5e,0xdf,0xd1,0x35,0x64,0x1a,0x7d,0xdb,0x53,0x57,0x47,0x24,0xec,0x2f,0x8e,0x08,0x51,0x7f,0x8e,0x00,0xf9,0xbe,0x25,0x00,0xae,0x18,0x34,0x2a,0xfa,0x49,0xf5,0x35,0x62,0x62,0x57,0x32,0xe2,0x64,0x44,0xa1,0x7a,0x3a,0xa0,0xba,0xef,0x7c,0x7a,0x01,0xc1,0xbd,0xd5,0x12,0x70,0x2b,0x35,0xa1,0x44,0x44,0x09,0x01,0x4a,0x3e,0xf4,0xcc,0x25,0xb9,0xe0,0xfb,0x9e,0x96,0xf2,0x2c,0x1b,0x38,0xa0,0xa4,0x76,0xaf,0x74,0x3e,0xe8,0x3f,0xb3,0xaa,0x10,0x8a,0x28,0x58,0xef,0xb0,0xe3,0x18,0x52,0xfe,0x80,0xcd,0xeb,0xf3,0x3e,0xfb,0x03,0x18,0x2d,0x01,0xaa,0x57,0x44,0x6f,0x81,0xc3,0x7a,0x1f,0x9a,0x95,0xbc,0x3f,0xaf,0xa8,0x32,0x00,0x28,0xc0,0x8a,0x90,0x50,0xe8,0x17,0xd1,0x1e,0xf0,0xc5,0x6e,0xd8,0x68,0x21,0xbb,0x9a,0xfe,0x93,0xc1,0x0f,0x7e,0x11,0x21,0xe2,0xf4,0xf8,0x95,0xe7,0x07,0x60,0xe4,0x3d,0xbf,0x66,0x7a,0xd9,0x14,0x79,0x05,0x17,0x03,0x92,0xe2,0xb5,0x6e,0x34,0x96,0x25,0x88,0xd0,0x2e,0x86,0xd6,0x0e,0xe6,0x3b,0x8e,0x39,0x02,0x03,0x01,0x00,0x01,0xa3,0x57,0x30,0x55,0x30,0x0e,0x06,0x03,0x55,0x1d,0x0f,0x01,0x01,0xff,0x04,0x04,0x03,0x02,0x02,0x84,0x30,0x13,0x06,0x03,0x55,0x1d,0x25,0x04,0x0c,0x30,0x0a,0x06,0x08,0x2b,0x06,0x01,0x05,0x05,0x07,0x03,0x01,0x30,0x0f,0x06,0x03,0x55,0x1d,0x13,0x01,0x01,0xff,0x04,0x05,0x30,0x03,0x01,0x01,0xff,0x30,0x1d,0x06,0x03,0x55,0x1d,0x0e,0x04,0x16,0x04,0x14,0xfe,0x08,0x85,0xf9,0x5d,0xeb,0xc9,0xe0,0xfc,0x43,0x57,0x19,0xf4,0xfe,0x52,0x01,0x29,0xac,0x56,0xd2,0x30,0x0d,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,0x01,0x0b,0x05,0x00,0x03,0x82,0x01,0x01,0x00,0x78,0xaa,0x1c,0x7b,0xe8,0x02,0x46,0x5f,0x2c,0xf5,0x8f,0xd9,0x00,0x9f,0xd0,0x2c,0x0c,0x17,0x43,0xb5,0x94,0xab,0x91,0x7e,0xc8,0xe7,0xbc,0xbb,0x02,0xfd,0x1e,0xa2,0x92,0x10,0x20,0x01,0x8b,0x9b,0x81,0x0b,0x5b,0xe8,0x45,0xb0,0xa6,0x56,0x12,0xc5,0xe8,0xce,0x8e,0x76,0x12,0x1a,0xc7,0x4b,0xbd,0xda,0x1c,0x43,0xf2,0xb4,0xfa,0x89,0x68,0xbe,0x93,0x1f,0x2e,0x36,0x99,0xf9,0x90,0x0f,0xb5,0x5c,0xa7,0x32,0xc9,0x1b,0xd7,0x06,0xc8,0x13,0x65,0xb0,0xff,0x08,0x2a,0x0d,0x1c,0xca,0xdb,0xe8,0x42,0xe8,0xbf,0x25,0x52,0x10,0xa9,0x09,0x52,0x21,0x7f,0xc6,0x39,0xc2,0xb0,0x35,0xa6,0xd7,0x50,0x66,0xb6,0xed,0x96,0x69,0xe8,0x0b,0x5d,0x23,0xe6,0x82,0xe2,0x04,0xf1,0x40,0x64,0x8d,0x0b,0x4c,0x6c,0x3d,0x1b,0xa2,0x7b,0x8e,0x34,0xa7,0xfd,0xca,0xfd,0x06,0xa8,0x8e,0xaf,0xd3,0x7e,0xfb,0x10,0x20,0x0b,0xc2,0x0b,0x9a,0x74,0xed,0xdb,0xe8,0xae,0x88,0x7a,0x6e,0x9b,0x26,0xfa,0x82,0xa8,0x91,0xdb,0xba,0x2e,0x61,0xbb,0x0b,0xaf,0xc0,0x87,0x51,0xaf,0x9a,0x69,0x6e,0xb1,0xd5,0x86,0x65,0xa5,0x52,0x42,0xb5,0xbc,0x59,0xf8,0x93,0x40,0x80,0x9d,0x61,0x16,0xc4,0xd8,0xc9,0x58,0xe7,0x69,0x28,0x5b,0x36,0xe2,0xea,0x4a,0x47,0x10,0x51,0x76,0xe0,0x42,0x55,0xb2,0x82,0xb0,0x84,0x67,0x03,0x63,0x4a,0x65,0xc5,0xed,0xf8,0xe4,0x8e,0xb6,0x59,0xd5,0xca,0x76,0x57,0x6e,0x09,0x12,0x0d,0x0a,0x35,0x63,0x65,0x6b,0x93,0xf1,0x04,0xb3,0x66,0xa2,0xb9'
  },
  {
    msg_type: 12,
    length: 296,
    message_seq: 2,
    fragment_offset: 0,
    fragment_length: 296,
    fragment: '0x03,0x00,0x1d,0x20,0xd9,0x6f,0x11,0xb9,0x8d,0xda,0x9b,0x1f,0xb4,0x72,0x10,0xc1,0x9e,0x95,0x46,0x06,0x55,0xbc,0xd9,0xca,0xb6,0x3c,0x27,0x6d,0x25,0x1d,0x97,0xa1,0x1f,0xbf,0x13,0x43,0x04,0x01,0x01,0x00,0x06,0x41,0x91,0x65,0xfa,0xc5,0x87,0x46,0xa9,0xe6,0x50,0xa8,0xb7,0x85,0xf3,0xcb,0xe0,0x33,0xcc,0xb2,0x79,0xe3,0x1e,0x28,0xea,0x7f,0xb0,0xda,0xd0,0xa5,0xef,0x31,0x17,0x2f,0x16,0xfc,0x66,0x4b,0xef,0x90,0x2c,0x10,0x4a,0x74,0x31,0x41,0x4f,0xbf,0x11,0x1a,0x54,0x1b,0x57,0x79,0x62,0x69,0xba,0x73,0x60,0x1b,0xa6,0xe1,0xcd,0xd3,0x71,0xd6,0x55,0x72,0x10,0x6f,0x17,0x25,0x53,0xac,0xa7,0x20,0xbb,0xf3,0xa3,0x4b,0x84,0x59,0x42,0xb2,0x4d,0xf5,0xd5,0x63,0x12,0xba,0x07,0x31,0x63,0x0c,0x7b,0x6a,0x28,0x1a,0x28,0xf6,0xbf,0x91,0x8e,0x7a,0x94,0xdc,0x64,0x7e,0x29,0x57,0x35,0x59,0x40,0x25,0x30,0x31,0x73,0x1e,0x39,0x28,0x67,0x76,0x61,0x8c,0x9d,0x84,0xf4,0x88,0x79,0x4d,0x3f,0xc4,0x71,0x09,0x20,0xe8,0x59,0x9b,0xde,0xad,0xc7,0xbf,0x95,0xdd,0x90,0xa4,0x00,0xcf,0x0f,0xbf,0x5a,0x8f,0x47,0xe6,0x1b,0x80,0xd4,0xf4,0xf9,0x95,0x3b,0x56,0xef,0xbb,0x50,0x5a,0xdc,0x99,0x95,0xe9,0x8b,0x93,0xb6,0xb4,0x52,0xc8,0x08,0xa9,0x93,0x26,0x50,0x11,0xa3,0x1f,0xe8,0x8e,0xc7,0x66,0x98,0x2d,0xde,0x52,0x5a,0x95,0x43,0x6c,0xe5,0x84,0xfb,0x2d,0x1b,0xb1,0x49,0x85,0x9f,0x95,0x7e,0x63,0x10,0x0a,0xd4,0xdf,0x3e,0x01,0x4b,0x93,0x21,0x07,0x3a,0x2f,0x69,0x6a,0x36,0xc8,0x89,0x60,0x51,0x48,0xe6,0x52,0x6c,0x90,0x85,0xb3,0x20,0x5d,0x48,0x5c,0x44,0x48,0xc1,0x2b,0x18,0x78,0x9d,0x12,0x88,0x23,0xe0,0x7b,0x4a,0xf6,0xd6,0x71,0xa0,0x69'
  },
  {
    msg_type: 13,
    length: 25,
    message_seq: 3,
    fragment_offset: 0,
    fragment_length: 25,
    fragment: '0x02,0x01,0x40,0x00,0x12,0x04,0x03,0x08,0x04,0x04,0x01,0x05,0x03,0x08,0x05,0x05,0x01,0x08,0x06,0x06,0x01,0x02,0x01,0x00,0x00'
  },
  {
    msg_type: 14,
    length: 0,
    message_seq: 4,
    fragment_offset: 0,
    fragment_length: 0,
    fragment: '0x'
  },
  {
    msg_type: 11,
    length: 389,
    message_seq: 1,
    fragment_offset: 0,
    fragment_length: 389,
    fragment: '0x00,0x01,0x82,0x00,0x01,0x7f,0x30,0x82,0x01,0x7b,0x30,0x82,0x01,0x21,0xa0,0x03,0x02,0x01,0x02,0x02,0x01,0x01,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02,0x30,0x45,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x41,0x55,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x13,0x0a,0x53,0x6f,0x6d,0x65,0x2d,0x53,0x74,0x61,0x74,0x65,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x0a,0x13,0x18,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x20,0x57,0x69,0x64,0x67,0x69,0x74,0x73,0x20,0x50,0x74,0x79,0x20,0x4c,0x74,0x64,0x30,0x1e,0x17,0x0d,0x32,0x31,0x31,0x32,0x31,0x38,0x31,0x37,0x30,0x39,0x32,0x35,0x5a,0x17,0x0d,0x33,0x31,0x31,0x32,0x31,0x38,0x31,0x37,0x30,0x39,0x32,0x35,0x5a,0x30,0x45,0x31,0x0b,0x30,0x09,0x06,0x03,0x55,0x04,0x06,0x13,0x02,0x41,0x55,0x31,0x13,0x30,0x11,0x06,0x03,0x55,0x04,0x08,0x13,0x0a,0x53,0x6f,0x6d,0x65,0x2d,0x53,0x74,0x61,0x74,0x65,0x31,0x21,0x30,0x1f,0x06,0x03,0x55,0x04,0x0a,0x13,0x18,0x49,0x6e,0x74,0x65,0x72,0x6e,0x65,0x74,0x20,0x57,0x69,0x64,0x67,0x69,0x74,0x73,0x20,0x50,0x74,0x79,0x20,0x4c,0x74,0x64,0x30,0x59,0x30,0x13,0x06,0x07,0x2a,0x86,0x48,0xce,0x3d,0x02,0x01,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x03,0x01,0x07,0x03,0x42,0x00,0x04,0x94,0x04,0xf1,0x32,0x0d,0xed,0x8e,0x4c,0xa0,0x67,0x4c,0x26,0x6a,0x02,0x9a,0xf6,0xf0,0xbc,0x1a,0x90,0x27,0x21,0x43,0x33,0xea,0xcd,0xb7,0x12,0xe1,0x60,0xbd,0x7b,0xd9,0x9d,0x5f,0xca,0xb2,0xaf,0xe5,0x7d,0x06,0x38,0x80,0x52,0x56,0xd2,0x39,0x59,0x49,0x53,0x58,0x01,0x0f,0xbb,0x05,0x5d,0xed,0xfe,0x09,0xb5,0x32,0x95,0x91,0x95,0xa3,0x02,0x30,0x00,0x30,0x0a,0x06,0x08,0x2a,0x86,0x48,0xce,0x3d,0x04,0x03,0x02,0x03,0x48,0x00,0x30,0x45,0x02,0x21,0x00,0xc4,0x57,0xdd,0x07,0x72,0x3b,0x4d,0x6d,0x5a,0x4c,0x2c,0x40,0x61,0xdf,0x82,0xcc,0x6a,0x94,0x23,0x31,0x92,0x07,0x28,0x48,0xd0,0xb1,0xae,0x7f,0xb7,0x58,0x7d,0x98,0x02,0x20,0x44,0x49,0xa3,0xb2,0xa9,0xc5,0x07,0xb4,0x80,0x24,0x47,0x5d,0x96,0xa9,0x59,0xac,0x7b,0xf5,0x5e,0x5c,0xc6,0x50,0x72,0x10,0xa1,0x22,0x09,0x2b,0x7a,0xe2,0x7f,0xa1'
  },
  {
    msg_type: 16,
    length: 33,
    message_seq: 2,
    fragment_offset: 0,
    fragment_length: 33,
    fragment: '0x20,0x21,0xcf,0xc3,0xe0,0x21,0x8e,0xa6,0x51,0x75,0x92,0xbd,0x0a,0xd9,0x7a,0x52,0x82,0x24,0x43,0x76,0xf0,0x13,0x20,0x09,0x36,0x4d,0xbe,0xfa,0xb7,0x1a,0x2e,0xbe,0x48'
  },
  {
    msg_type: 15,
    length: 75,
    message_seq: 3,
    fragment_offset: 0,
    fragment_length: 75,
    fragment: '0x04,0x03,0x00,0x47,0x30,0x45,0x02,0x21,0x00,0x88,0xbb,0xd8,0x7b,0x58,0xc3,0x1e,0xe0,0xe3,0xae,0x3e,0x2f,0xef,0xed,0x6b,0xec,0x7f,0xa0,0x37,0xb4,0xfd,0xb9,0x15,0x6b,0xca,0x1c,0x39,0xee,0x6e,0x37,0xb8,0x18,0x02,0x20,0x4a,0x03,0x3b,0x9b,0xcf,0x47,0x89,0x86,0x99,0x62,0x82,0x18,0xcd,0x07,0x56,0xe8,0x01,0x28,0x43,0x70,0x3b,0x8b,0x4a,0x11,0x16,0x64,0xd6,0x84,0x14,0xbb,0x8b,0xea'
  },
  {
    msg_type: 20,
    length: 12,
    message_seq: 4,
    fragment_offset: 0,
    fragment_length: 12,
    fragment: '0x97,0xcc,0xb6,0x89,0xf9,0x95,0xcd,0x9c,0x71,0x64,0xa1,0x79'
  }
] +2ms
  werift-dtls : packages/dtls/src/flight/client/flight5.ts : log  finished {
  id: 49199,
  verifyDataLength: 12,
  keyLength: 16,
  nonceLength: 12,
  ivLength: 4,
  authTagLength: 16,
  nonceImplicitLength: 4,
  nonceExplicitLength: 8,
  name: 'TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256',
  blockAlgorithm: 'aes-128-gcm',
  hashAlgorithm: 'sha256',
  clientWriteKey: '0x0f,0x12,0xe0,0x18,0xe4,0x95,0xbf,0x38,0xe6,0x18,0xe5,0xb2,0x6d,0x66,0x6b,0x03',
  serverWriteKey: '0x4a,0x45,0xdf,0xdc,0x8d,0xa5,0x6a,0x56,0xae,0x13,0x62,0x80,0xd1,0xb2,0xff,0xf6',
  clientNonce: '0x6f,0xc0,0x86,0xe0,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x06',
  serverNonce: '0x6a,0x54,0x2a,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00'
} +3ms
  werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 19 da 65 c1 39 b1 10 cc a6 f8 c2 54 00 06 00 15 35 50 54 4a 5a 39 57 2f 39 56 41 56 4d 53 5a 4a 3a 34 31 37 31 00 00 00 00 24 ... 50 more bytes> +201ms
  werift-dtls : packages/dtls/record/receive.ts : log  change cipher spec +0ms
  werift-dtls : packages/dtls/record/receive.ts : log  decrypt handshake +0ms
  werift-dtls : packages/dtls/src/client.ts : log  handleHandshakes [ 20 ] +72ms
  werift-dtls : packages/dtls/src/client.ts : log  dtls connected +0ms
  werift:packages/webrtc/src/transport/dtls.ts selected SRTP Profile 1 +0ms
  werift:packages/webrtc/src/transport/dtls.ts dtls connected +3ms
  werift:packages/webrtc/src/peerConnection.ts dtls connected +260ms
  werift/sctp/sctp send init InitChunk {
  flags: 0,
  _body: <Buffer >,
  initiateTag: 1380315946,
  advertisedRwnd: 1048576,
  outboundStreams: 65535,
  inboundStreams: 65535,
  initialTsn: 1599609742,
  params: [ [ 49152, <Buffer > ], [ 32776, <Buffer c0 82> ] ]
} +0ms
audio data
.
.
.
audio data
  werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 19 da 65 c1 39 b1 10 cc a6 f8 c2 54 00 06 00 15 35 50 54 4a 5a 39 57 2f 39 56 41 56 4d 53 5a 4a 3a 34 31 37 31 00 00 00 00 24 ... 50 more bytes> +400ms
audio data
.
.
.
audio data
  werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 19 da 65 c1 39 b1 10 cc a6 f8 c2 54 00 06 00 15 35 50 54 4a 5a 39 57 2f 39 56 41 56 4d 53 5a 4a 3a 34 31 37 31 00 00 00 00 24 ... 50 more bytes> +800ms
audio data
.
.
.
audio data
  werift-ice:packages/ice/src/transport.ts send error [ '2607:f8b0:400e:c0a::7f', 19305 ] <Buffer 00 01 00 50 21 12 a4 42 19 da 65 c1 39 b1 10 cc a6 f8 c2 54 00 06 00 15 35 50 54 4a 5a 39 57 2f 39 56 41 56 4d 53 5a 4a 3a 34 31 37 31 00 00 00 00 24 ... 50 more bytes> +2s
audio data
.
.
.
audio data
  werift-ice:packages/ice/src/stun/transaction.ts retry failed times:7 maxLimit:7 +0ms
  werift-ice : packages/ice/src/ice.ts : log failure case undefined +6s
  werift-ice : packages/ice/src/ice.ts : log CandidatePairState.FAILED +0ms
audio data
.
.
.

SDP validation fails if mid values do not match

throw new Error("Media sections in answer do not match offer");

Offer: Werift (mid: 0_srtp)
Answer: Google Camera Gen 2 (mid: 0)

Werift generates mid values that do not match the answer sdp (suffixed with strip). This causes the above failure. This is new behavior in this change:
32a3610#r77415945

For now, I am manually setting the mid values to to force a match (only because I know what the answer sdp will be ahead of time).
I believe the above matching code is incorrect, it should likely do a comparison against mLineIndex.

Datachannel performance

Hi, this looks like a very interesting project!

I was wondering if you have measured the maximum throughput of the data channel? It would be very interesting to know how the performance compares to that of other WebRTC implementations.

no response on second peer connection stun request

I've been having a hard time tracking this issue down, and was wanting to see if you had any insight:

Clients:
Offer: Safari iOS (on cellular)
Answer: Werift on Mac

On first run of connecting the peers, werift will successfully retrieve the srflx candidates from the STUN server. On second or third run, werift will fail to retrieve a response from the STUN server, causing the connection to fail. After a few minutes, the STUN server seems to start responding again.

I have observed this behavior with multiple different stun servers (with no quotas enabled). I only observe this behavior when the peer is on cellular. When the Safari iOS peer is on local network, Werift will successfully receive a STUN response every time.

I'm unsure why the cellular network peer would cause STUN requests to fail in werift. I verified that the requests are being sent, and no response is received on the datagram socket.

Do you have any ideas?

My guess is that werift is somehow sending bad stun requests after the first one.

"negotiate codecs failed"

version: 0.14.1-debug
node: v16.13.1

offer:

v=0
o=- 56374871 0 IN IP4 0.0.0.0
s=-
t=0 0
a=group:BUNDLE 0 1 2
a=extmap-allow-mixed
a=msid-semantic:WMS *
m=audio 9 UDP/TLS/RTP/SAVPF 96
c=IN IP4 0.0.0.0
a=ice-ufrag:c1e5
a=ice-pwd:2706765fe4fcda0887a954
a=ice-options:trickle
a=fingerprint:sha-256 CB:9A:F7:DB:AE:C7:A1:87:DB:08:30:7D:41:54:31:C7:BE:71:3E:35:39:88:E7:7F:CC:5B:F8:44:AD:8D:0A:4F
a=setup:actpass
a=recvonly
a=mid:0
a=msid:5fb4c17a-9c5f-49a7-bc80-c9b24d20c37a 5855df55-ea0b-4665-8149-0a9c39de5acd
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:2824052209 cname:a032b4a4-1c71-41af-9507-411972a48638
a=rtpmap:96 opus/48000/2
m=video 9 UDP/TLS/RTP/SAVPF 97
c=IN IP4 0.0.0.0
a=ice-ufrag:c1e5
a=ice-pwd:2706765fe4fcda0887a954
a=ice-options:trickle
a=fingerprint:sha-256 CB:9A:F7:DB:AE:C7:A1:87:DB:08:30:7D:41:54:31:C7:BE:71:3E:35:39:88:E7:7F:CC:5B:F8:44:AD:8D:0A:4F
a=setup:actpass
a=recvonly
a=mid:1
a=msid:b8a2bc98-28cf-4528-872b-a03ae1902c20 f3c9d1bb-c187-4f1d-8275-d808cb836d2b
a=rtcp:9 IN IP4 0.0.0.0
a=rtcp-mux
a=ssrc:2372508246 cname:a032b4a4-1c71-41af-9507-411972a48638
a=rtpmap:97 VP9/90000
a=rtcp-fb:97 ccm fir
a=rtcp-fb:97 nack
a=rtcp-fb:97 nack pli
a=rtcp-fb:97 goog-remb
m=application 9 UDP/DTLS/SCTP webrtc-datachannel
c=IN IP4 0.0.0.0
a=ice-ufrag:c1e5
a=ice-pwd:2706765fe4fcda0887a954
a=ice-options:trickle
a=fingerprint:sha-256 CB:9A:F7:DB:AE:C7:A1:87:DB:08:30:7D:41:54:31:C7:BE:71:3E:35:39:88:E7:7F:CC:5B:F8:44:AD:8D:0A:4F
a=setup:actpass
a=mid:2
a=sctp-port:5000
a=max-message-size:65536

answer:

v=0
o=- 0 2 IN IP4 127.0.0.1
s=-
t=0 0
a=group:BUNDLE 0 2 1
a=msid-semantic: WMS 5482079529792029765/3212739396 virtual-6666
a=ice-lite
m=audio 19305 UDP/TLS/RTP/SAVPF 96
c=IN IP4 <redacted>
a=rtcp:9 IN IP4 0.0.0.0
a=candidate: 1 udp 2113939711 2607:f8b0:400e:c0a::7f 19305 typ host generation 0
a=candidate: 1 tcp 2113939710 2607:f8b0:400e:c0a::7f 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113939709 2607:f8b0:400e:c0a::7f 443 typ host generation 0
a=candidate: 1 udp 2113932031 172.253.117.127 19305 typ host generation 0
a=candidate: 1 tcp 2113932030 172.253.117.127 19305 typ host tcptype passive generation 0
a=candidate: 1 ssltcp 2113932029 172.253.117.127 443 typ host generation 0
a=ice-ufrag:VZWKPZNWMUWLHSQV
a=ice-pwd:U/KRMXOOGEXNUTRO3FXRQHZ5
a=fingerprint:sha-256 19:FE:07:62:AA:47:66:BD:B7:78:05:4F:02:55:86:7F:FA:8C:94:A1:F6:D3:E4:CC:85:20:A7:E1:3C:9C:4F:D4
a=setup:passive
a=mid:0
a=sendrecv
a=msid:virtual-6666 virtual-6666
a=rtcp-mux
a=rtpmap:96 opus/48000/2
a=fmtp:96 minptime=10;useinbandfec=1
a=ssrc:6666 cname:6666
m=video 9 UDP/TLS/RTP/SAVPF 0
c=IN IP4 0.0.0.0
a=rtcp:9 IN IP4 0.0.0.0
a=ice-ufrag:VZWKPZNWMUWLHSQV
a=ice-pwd:U/KRMXOOGEXNUTRO3FXRQHZ5
a=fingerprint:sha-256 19:FE:07:62:AA:47:66:BD:B7:78:05:4F:02:55:86:7F:FA:8C:94:A1:F6:D3:E4:CC:85:20:A7:E1:3C:9C:4F:D4
a=setup:passive
a=mid:1
a=sendrecv
a=msid:5482079529792029765/3212739396 5482079529792029765/3212739396
a=rtcp-mux
a=ssrc:3212739396 cname:3212739396
m=application 9 DTLS/SCTP 5000
c=IN IP4 0.0.0.0
a=ice-ufrag:VZWKPZNWMUWLHSQV
a=ice-pwd:U/KRMXOOGEXNUTRO3FXRQHZ5
a=fingerprint:sha-256 19:FE:07:62:AA:47:66:BD:B7:78:05:4F:02:55:86:7F:FA:8C:94:A1:F6:D3:E4:CC:85:20:A7:E1:3C:9C:4F:D4
a=setup:passive
a=mid:2
a=sctpmap:5000 webrtc-datachannel 1024

results in:

/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/peerConnection.js:519
                    throw new Error("negotiate codecs failed.");
                          ^

Error: negotiate codecs failed.
    at RTCPeerConnection.setRemoteDescription (/Users/me/Source/webrtctest/node_modules/werift/lib/webrtc/src/peerConnection.js:519:27)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)

Seems to occur intermittently.

`RTCDataChannel` gets stuck as `dataChannelFlush` is never called

I'm testing the RTCDataChannel (version 0.8.3) and if I send multiple messages at the same time it gets stuck and the other channel never receives it. Debugging the code I've noticed RTCSctpTransport.dataChannelFlush() is never called after SCTP.receiveSackChunk(). And checking the reference implementation aiortc it's indeed missing. Check below:

To get rid of this bug I've monkey-patched RTCDataChannel as below:

    const rtcPeerConnection = new WeriftRTCPeerConnection()

    // Monkey patch missing `sctp.dataChannelFlush()` in `sctp.sctp.receiveSackChunk()`
    const createSctpTransport = rtcPeerConnection['createSctpTransport'].bind(rtcPeerConnection)
    rtcPeerConnection['createSctpTransport'] = () => {
      const sctp = createSctpTransport()
      const receiveSackChunk = sctp.sctp.receiveSackChunk.bind(sctp.sctp)
      const updateAdvancedPeerAckPoint = sctp.sctp.updateAdvancedPeerAckPoint.bind(sctp.sctp)
      let inReceiveSackChunk = false
      sctp.sctp.receiveSackChunk = (chunk: any) => {
        inReceiveSackChunk = true
        try {
          return receiveSackChunk(chunk)
        } finally {
          inReceiveSackChunk = false
        }
      }
      sctp.sctp.updateAdvancedPeerAckPoint = () => {
        updateAdvancedPeerAckPoint()
        if (inReceiveSackChunk) {
          sctp.dataChannelFlush()
        }
      }

      return sctp
    }

Missing ice-lite support

Lack of ice-lite support means that this lib can not be used to establish a ICE+DTLS connection with ICE Lite servers.

If you add support for ice-lite I'll extensively test this lib against mediasoup and will make a handler to use it within mediasoup-client in Node (as we did for Python aiortc lib).

ice transport failures when there are multiple transports (non-bundle)

Here, any ice transport failure fails the whole connection I think:

this.checkListDone = true;

I believe that all the ice transport results should be iterated to see if anything in the checklist succeeded. Or check to see if nominated is not empty.

res = await this.checkListState.get();

I have a fix for this, but I wanted to make sure I am understanding this code correctly.

Support fragmentation packets for MediaRecorder

If trying to use MediaRecorder with an H264 stream which contains fragmentation packets, attempts to record will error out with:

    at Function.concat (node:buffer:544:19)
    at basicCodecParser (/Users/me/Source/webrtctest/node_modules/werift/lib/rtp/src/processor/webm.js:119:33)
    at WebmOutput.dePacketizeRtpPackets (/Users/me/Source/webrtctest/node_modules/werift/lib/rtp/src/processor/webm.js:130:24)
    at WebmOutput.onRtpPackets (/Users/me/Source/webrtctest/node_modules/werift/lib/rtp/src/processor/webm.js:93:43)
    at Object.promise (/Users/me/Source/webrtctest/node_modules/werift/lib/rtp/src/processor/webm.js:85:36)
    at PromiseQueue.run (/Users/me/Source/webrtctest/node_modules/werift/lib/common/src/promise.js:18:24)
    at /Users/me/Source/webrtctest/node_modules/werift/lib/common/src/promise.js:11:22
    at new Promise (<anonymous>)
    at PromiseQueue.push (/Users/me/Source/webrtctest/node_modules/werift/lib/common/src/promise.js:8:34)
    at WebmOutput.pushRtpPackets (/Users/me/Source/webrtctest/node_modules/werift/lib/rtp/src/processor/webm.js:85:20)

Seems to be because here https://github.com/shinyoshiaki/werift-webrtc/blob/develop/packages/rtp/src/codec/h264.ts#L77 if the unit type is 28/29 it will return a packet with an undefined payload.

todo fix ci

Ttodo fix probabilistic datachannel_close_client_create_close fails

`rolloverCounter` can get negative

I noticed that during some long-running stream I end up getting an exception which originates here because the value of rolloverCounter gets -1 at some point.
Probably there is something wrong with the update rule.

Specify server port/port range

@shinyoshiaki First of all, thanks for this awesome library.

I would like to use this library to start webrtc server for comunicating over datachannels. I looked at the examples and managed to do so on my local computer. Now I would like to host this on server. But my hosting provider supports listening to only limited number of udp ports and that too only in a specific range.
So where should I specify the port/port range? Would be very grateful to you if you could provide the answer with respect to this example https://github.com/shinyoshiaki/werift-webrtc/blob/develop/examples/datachannel/answer.ts and the corresponding client side https://github.com/shinyoshiaki/werift-webrtc/blob/develop/examples/datachannel/offer.html
I am looking for something similar to that provided by another nodejs webrtc library https://github.com/geckosio/geckos.io#new-in-version-170

In some cases, video does not play after event ontrack is triggered on the client

Hello! I moved my project from wrtc to werift. Due to the fact that 1 has different results between the first and subsequent server launches - apparently wrtc has some dependencies that store variables in memory bound to the process, so the server on wrtc does not work stably, the same happens if you use webdriver through puppeteer or playwright. But at werift this moment works stably, but I ran into a problem with reconnecting werift.

Description of the problem

When two or more room clients connect to the server at the same time, the video is played, but if you first connect one user, and then reconnect again, then his video is never played. Also, this problem occurs when about 5 users are connected and several users reload the page at the same time, but this moment is more difficult to track, so I temporarily set the disconnect from the client when clicking on the button to close the full screen video. And the listener then connects the disconnected but active user in the room.

Problem reproduction

In my project, you can make sure that the moment with a single reconnect worked with wrtc but does not work with werift.
I have checked all possible options, but everything suggests that the problem may be at a lower level of code than my application. That's why I'm writing this question because perhaps my project example will help you find a hard-to-find problem.


Result of reconnection to wrtc: https://iili.io/gd1gCG.png


Result of reconnection to werift: https://iili.io/gd1rGf.png


To reproduce this examples need:

Add-ons

I don't see any difference between normal and non-playable video streams:
https://iili.io/gd1444.png
Perhaps you will have some ideas.

[WEBRTC] Implement MediaPlayer

I am very happy to see that you implemented the MediaRecorder interface to save streams to webm files. I am probably going to replace my own implementation and try yours.

Are you also planning to create an interface which make streaming from webm files possible, i.e., something like a MediaPlayer (which is not part of the standard WebRTC infrastructure)?

chrome and android webrtc

image
image
image
When chrome talks with Android webrtc, the Android end cannot receive the stream, and onaddstream has no callback,The onicecandidate of the third figure also does not receive a callback

DataChannel close

create datachnnel

reconfig param は帰ってくる(StreamResetResponseParam)
chromeのcloseが発火しない

subscribe datachannel

chromeのcloseが発火する

`dataChannelFlush()` starves sending only one data buffer per entire event loop

The problem is in the following loop of RTCSctpTransport.dataChannelFlush() function:

while (
this.dataChannelQueue.length > 0 &&
this.sctp.outboundQueue.length === 0
) {
const [channel, protocol, userData] = this.dataChannelQueue.shift()!;
let streamId = channel.id;
if (streamId === undefined) {
streamId = this.dataChannelId!;
while (Object.keys(this.dataChannels).includes(streamId.toString())) {
streamId += 2;
}
this.dataChannels[streamId] = channel;
channel.setId(streamId);
}
if (protocol === WEBRTC_DCEP) {
this.sctp.send(streamId, protocol, userData);
} else {
if (channel.maxPacketLifeTime) {
expiry = Date.now() + channel.maxPacketLifeTime / 1000;
} else {
expiry = undefined;
}
this.sctp
.send(
streamId,
protocol,
userData,
expiry,
channel.maxRetransmits,
channel.ordered
)
.then(() => this.dataChannelFlush());
channel.addBufferedAmount(-userData.length);
}
}

My use case is that I call send every time the user changes a text in a text-editor. And when I use Werift instead of the native wrtc package the other side gets the changes really slowly until the user stops typing. Upon investigating it I've found out that the this.dataChannelQueue in this loop increases a lot because this.sctp.outboundQueue is always with one item to be sent.

As it turns out, every time a this.sctp.send is called inside this loop chunks are immediately added to this.sctp.outboundQueue and the loop ends right away. So, it's only going to execute in the next event loop but once again this repeats one by one until the this.dataChannelQueue gets empty.

Comparing this function with the reference implementation in aiortc they look like the same but there is a fundamental difference between Python AsyncIO and JavaScript Promises. Python AsyncIO enqueue awaitable functions to be run on the next event loop, but JavaScript Promises runs its executor function synchronously. So, even though the SCTP.send() is an async function the code is going to execute synchronously and this function adds chunks to outboundQueue and makes the former loop to stop. The loop logic is then flawed in JavaScript as it's going to always dequeue only one item from dataChannelQueue and then it stops (Having this while loop or just a if is the same in JavaScript).

Upon investigating a solution for it the easiest one is to wrap the SCTP.send() in a Promise.resolve.then() as JavaScript always enqueue then executor functions. Below is the mokey-patch I've made to make it work.

    const rtcPeerConnection = new WeriftRTCPeerConnection({ iceServers })

    // Monkey patch `sctp.sctp.send()` to be queued on next event loop otherwise `sctp.dataChannelFlush()` "starves"
    // sending only one buffered data on each event loop
    const createSctpTransport = rtcPeerConnection['createSctpTransport'].bind(rtcPeerConnection)
    rtcPeerConnection['createSctpTransport'] = () => {
      const sctp = createSctpTransport()
      const send = sctp.sctp.send
      sctp.sctp.send = (...args: any[]) => Promise.resolve().then(() => send(...args))
      return sctp
    }

With this solution the other side gets the updates much faster but it's not fluid. The other side gets the stream in chunks of text instead of letter by letter. The problem with that solution is that it's going to enqueue everything from this.dataChannelQueue not giving any chance to some finished IO waiting in the event loop. It would be nice to have an async dataChannelFlush with the loop logic fixed so this would never happen. Also, looks like Werift's Transport.send function implementations are not async as well so it always halts the entire event loop until the IO finishes.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.