Skip to content

Instantly share code, notes, and snippets.

@tfoldi
Created February 22, 2024 19:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfoldi/270ddfdf919bf035cd96652d4bb03622 to your computer and use it in GitHub Desktop.
Save tfoldi/270ddfdf919bf035cd96652d4bb03622 to your computer and use it in GitHub Desktop.
Incoming unhandled RTCP ssrc(305150496), on_track will not be fired
ice/src/mdns/mod.rs:61 [INFO] 20:15:22.745336 - mDNS is using 0.0.0.0:5353 as dest_addr
mdns/src/conn/mod.rs:89 [TRACE] 20:15:22.746518 - Connected to interface address 127.0.0.1:0
mdns/src/conn/mod.rs:89 [TRACE] 20:15:22.746619 - Connected to interface address 192.168.88.147:0
mdns/src/conn/mod.rs:254 [INFO] 20:15:22.746708 - Looping and listening Ok(0.0.0.0:5353)
ice/src/agent/agent_internal.rs:332 [TRACE] 20:15:22.748053 - [controlled]: Set selected candidate pair: None
webrtc/src/peer_connection/mod.rs:298 [INFO] 20:15:22.750639 - signaling state changed to have-local-offer
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751584 - [controlled]: could not listen udp fe80::9adb:84cb:8e81:8c38: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751611 - [controlled]: could not listen udp fe80::1: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751634 - [controlled]: could not listen udp fe80::6919:bdd8:ec09:337: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751657 - [controlled]: could not listen udp fe80::ee18:abf3:c0f3:7bd2: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751677 - [controlled]: could not listen udp fe80::dc70:f4ff:fecc:33f3: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751699 - [controlled]: could not listen udp fe80::ce81:b1c:bd2c:69e: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751718 - [controlled]: could not listen udp fe80::777a:2f5b:f550:bc1b: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751740 - [controlled]: could not listen udp fe80::489:bbde:94e1:7733: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751761 - [controlled]: could not listen udp fe80::b505:23be:e50b:135e: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.751984 - [controlled]: could not listen udp fe80::18bb:a7ff:fe4a:5859: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.752006 - [controlled]: could not listen udp fe80::10fe:76c:5fc1:4c5: io error: Can't assign requested address (os error 49)
ice/src/agent/agent_gather.rs:286 [WARN] 20:15:22.752025 - [controlled]: could not listen udp fe80::dc70:f4ff:fecc:33f2: io error: Can't assign requested address (os error 49)
webrtc/src/peer_connection/mod.rs:2082 [TRACE] 20:15:22.752066 - setGatherCompleteHandler
{"type":"offer","sdp":"v=0\r\no=- 4573865625008534223 744790000 IN IP4 0.0.0.0\r\ns=-\r\nt=0 0\r\na=fingerprint:sha-256 74:2B:A6:FF:E2:8B:F2:FB:5F:D8:62:07:D0:17:BF:A7:74:40:06:7A:43:4E:25:DA:8B:0C:C8:6F:B8:41:63:BC\r\na=group:BUNDLE 0 1\r\nm=video 9 UDP/TLS/RTP/SAVPF 102 96 98 100 127 125 108 123 41 116\r\nc=IN IP4 0.0.0.0\r\na=setup:actpass\r\na=mid:0\r\na=ice-ufrag:hliwcNWNMeTgpAPe\r\na=ice-pwd:BiJOBfHvLpYbARnSPPvptUUPuYzYREhz\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:102 H264/90000\r\na=rtcp-fb:102 nack\r\na=rtcp-fb:102 nack pli\r\na=rtcp-fb:102 transport-cc\r\na=rtpmap:96 VP8/90000\r\na=rtcp-fb:96 goog-remb\r\na=rtcp-fb:96 ccm fir\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtcp-fb:96 nack\r\na=rtcp-fb:96 nack pli\r\na=rtcp-fb:96 transport-cc\r\na=rtpmap:98 VP9/90000\r\na=fmtp:98 profile-id=0\r\na=rtcp-fb:98 goog-remb\r\na=rtcp-fb:98 ccm fir\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=rtcp-fb:98 nack\r\na=rtcp-fb:98 nack pli\r\na=rtcp-fb:98 transport-cc\r\na=rtpmap:100 VP9/90000\r\na=fmtp:100 profile-id=1\r\na=rtcp-fb:100 goog-remb\r\na=rtcp-fb:100 ccm fir\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=rtcp-fb:100 nack\r\na=rtcp-fb:100 nack pli\r\na=rtcp-fb:100 transport-cc\r\na=rtpmap:127 H264/90000\r\na=fmtp:127 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42001f\r\na=rtcp-fb:127 goog-remb\r\na=rtcp-fb:127 ccm fir\r\na=rtcp-fb:127 nack\r\na=rtcp-fb:127 nack pli\r\na=rtcp-fb:127 nack\r\na=rtcp-fb:127 nack pli\r\na=rtcp-fb:127 transport-cc\r\na=rtpmap:125 H264/90000\r\na=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtcp-fb:125 goog-remb\r\na=rtcp-fb:125 ccm fir\r\na=rtcp-fb:125 nack\r\na=rtcp-fb:125 nack pli\r\na=rtcp-fb:125 nack\r\na=rtcp-fb:125 nack pli\r\na=rtcp-fb:125 transport-cc\r\na=rtpmap:108 H264/90000\r\na=fmtp:108 level-asymmetry-allowed=1;packetization-mode=0;profile-level-id=42e01f\r\na=rtcp-fb:108 goog-remb\r\na=rtcp-fb:108 ccm fir\r\na=rtcp-fb:108 nack\r\na=rtcp-fb:108 nack pli\r\na=rtcp-fb:108 nack\r\na=rtcp-fb:108 nack pli\r\na=rtcp-fb:108 transport-cc\r\na=rtpmap:123 H264/90000\r\na=fmtp:123 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=640032\r\na=rtcp-fb:123 goog-remb\r\na=rtcp-fb:123 ccm fir\r\na=rtcp-fb:123 nack\r\na=rtcp-fb:123 nack pli\r\na=rtcp-fb:123 nack\r\na=rtcp-fb:123 nack pli\r\na=rtcp-fb:123 transport-cc\r\na=rtpmap:41 AV1/90000\r\na=fmtp:41 profile-id=0\r\na=rtcp-fb:41 goog-remb\r\na=rtcp-fb:41 ccm fir\r\na=rtcp-fb:41 nack\r\na=rtcp-fb:41 nack pli\r\na=rtcp-fb:41 nack\r\na=rtcp-fb:41 nack pli\r\na=rtcp-fb:41 transport-cc\r\na=rtpmap:116 ulpfec/90000\r\na=rtcp-fb:116 nack\r\na=rtcp-fb:116 nack pli\r\na=rtcp-fb:116 transport-cc\r\na=extmap:1 http://www.ietf.org/id/draft-holmer-rmcat-transport-wide-cc-extensions-01\r\na=sendrecv\r\na=candidate:2787683327 1 udp 2130706431 192.168.88.147 54506 typ host\r\na=candidate:2787683327 2 udp 2130706431 192.168.88.147 54506 typ host\r\na=end-of-candidates\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 0.0.0.0\r\na=setup:actpass\r\na=mid:1\r\na=sendrecv\r\na=sctp-port:5000\r\na=ice-ufrag:hliwcNWNMeTgpAPe\r\na=ice-pwd:BiJOBfHvLpYbARnSPPvptUUPuYzYREhz\r\n"}
/Users/tfoldi/.cargo/registry/src/index.crates.io-6f17d22bba15001f/reqwest-0.11.24/src/connect.rs:449 [DEBUG] 20:15:22.818794 - starting new connection: http://192.168.88.93:8081/
Received response: {"type":"answer","sdp":"v=0\r\no=- 793879525 2 IN IP4 127.0.0.1\r\ns=-\r\nt=0 0\r\na=group:BUNDLE 0 1\r\na=msid-semantic: WMS myKvsVideoStream\r\nm=video 9 UDP/TLS/RTP/SAVPF 125\r\nc=IN IP4 127.0.0.1\r\na=candidate:2 1 udp 2130706431 FD34:DA26:3057:A4AD:7C60:01F4:0AB3:A087 60921 typ host raddr ::/0 rport 0 generation 0 network-cost 999\r\na=candidate:1 1 udp 2130706431 FD34:DA26:3057:A4AD:FE6E:E5EF:595B:7F28 36772 typ host raddr ::/0 rport 0 generation 0 network-cost 999\r\na=candidate:0 1 udp 2130706431 192.168.88.93 38476 typ host raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=msid:unitreeMediaStream unitreeVideoTrack\r\na=ssrc:1310685370 cname:YOLSaPNo5twymX0W\r\na=ssrc:1310685370 msid:unitreeMediaStream unitreeVideoTrack\r\na=ssrc:1310685370 mslabel:unitreeMediaStream\r\na=ssrc:1310685370 label:unitreeVideoTrack\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:wC4w\r\na=ice-pwd:EiW8sud4mUdWJ26wu61owmbN\r\na=ice-options:trickle\r\na=fingerprint:sha-256 6A:C8:C7:9B:4C:EC:33:B8:BC:D5:34:AD:3F:64:87:79:94:A7:73:1D:3F:69:6A:45:93:FF:7B:BB:AB:9D:7E:09\r\na=setup:active\r\na=mid:0\r\na=sendrecv\r\na=rtcp-mux\r\na=rtcp-rsize\r\na=rtpmap:125 H264/90000\r\na=fmtp:125 level-asymmetry-allowed=1;packetization-mode=1;profile-level-id=42e01f\r\na=rtcp-fb:125 nack\r\na=rtcp-fb:125 goog-remb\r\na=rtcp-fb:125 transport-cc\r\nm=application 9 UDP/DTLS/SCTP webrtc-datachannel\r\nc=IN IP4 127.0.0.1\r\na=candidate:2 1 udp 2130706431 FD34:DA26:3057:A4AD:7C60:01F4:0AB3:A087 60921 typ host raddr ::/0 rport 0 generation 0 network-cost 999\r\na=candidate:1 1 udp 2130706431 FD34:DA26:3057:A4AD:FE6E:E5EF:595B:7F28 36772 typ host raddr ::/0 rport 0 generation 0 network-cost 999\r\na=candidate:0 1 udp 2130706431 192.168.88.93 38476 typ host raddr 0.0.0.0 rport 0 generation 0 network-cost 999\r\na=rtcp:9 IN IP4 0.0.0.0\r\na=ice-ufrag:wC4w\r\na=ice-pwd:EiW8sud4mUdWJ26wu61owmbN\r\na=fingerprint:sha-256 6A:C8:C7:9B:4C:EC:33:B8:BC:D5:34:AD:3F:64:87:79:94:A7:73:1D:3F:69:6A:45:93:FF:7B:BB:AB:9D:7E:09\r\na=setup:active\r\na=mid:1\r\na=sctp-port:5000\r\n","id":"STA_localNetwork"}
webrtc/src/peer_connection/mod.rs:298 [INFO] 20:15:23.379366 - signaling state changed to stable
webrtc/src/rtp_transceiver/mod.rs:364 [TRACE] 20:15:23.380577 - Changing current direction of transceiver from Unspecified to sendrecv
webrtc/src/rtp_transceiver/mod.rs:387 [TRACE] 20:15:23.380615 - Processing transceiver(Some("0")) direction change from Unspecified to sendrecv
Press ctrl-c to stop
webrtc/src/peer_connection/mod.rs:1581 [TRACE] 20:15:23.383718 - start_transports: ice_role=controlling, dtls_role=client
ice/src/agent/agent_internal.rs:182 [DEBUG] 20:15:23.383826 - Started agent: isControlling? true, remoteUfrag: wC4w, remotePwd: EiW8sud4mUdWJ26wu61owmbN
ice/src/agent/agent_internal.rs:312 [INFO] 20:15:23.384102 - [controlling]: Setting new connection state: Checking
webrtc/src/peer_connection/mod.rs:620 [INFO] 20:15:23.384460 - ICE connection state changed: checking
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.384469 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.384683 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.384696 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 1, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.384744 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.384839 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.384851 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 1, true
ice/src/agent/agent_internal.rs:364 [TRACE] 20:15:23.384873 - [controlling]: pinging all candidates
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.384935 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_internal.rs:715 [TRACE] 20:15:23.385022 - [controlling]: ping STUN from udp4 host 192.168.88.147:54506 to udp4 host 192.168.88.93:38476
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385102 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385112 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385151 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385206 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385219 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385262 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385304 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385314 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385354 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385397 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385406 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385445 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385485 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385492 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385530 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385570 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385580 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385617 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385655 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385664 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385701 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385741 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385749 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_internal.rs:961 [TRACE] 20:15:23.385785 - [controlling]: inbound STUN (Request) from 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:363 [TRACE] 20:15:23.385828 - controllingSelector: sendBindingSuccess
ice/src/agent/agent_selector.rs:371 [TRACE] 20:15:23.385834 - controllingSelector: after findPair prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 2, true
ice/src/agent/agent_selector.rs:323 [TRACE] 20:15:23.397131 - inbound STUN (SuccessResponse) from udp4 host 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:333 [TRACE] 20:15:23.397225 - Found valid candidate pair: prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 4, isUseCandidate: false, true
ice/src/agent/agent_selector.rs:257 [TRACE] 20:15:23.586730 - Nominatable pair found, nominating (udp4 host 192.168.88.147:54506, udp4 host 192.168.88.93:38476)
ice/src/agent/agent_selector.rs:143 [TRACE] 20:15:23.587275 - ping STUN (nominate candidate pair from udp4 host 192.168.88.147:54506 to udp4 host 192.168.88.93:38476
ice/src/agent/agent_internal.rs:715 [TRACE] 20:15:23.587307 - [controlling]: ping STUN from udp4 host 192.168.88.147:54506 to udp4 host 192.168.88.93:38476
ice/src/agent/agent_selector.rs:323 [TRACE] 20:15:23.596404 - inbound STUN (SuccessResponse) from udp4 host 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:333 [TRACE] 20:15:23.596565 - Found valid candidate pair: prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 4, isUseCandidate: true, true
ice/src/agent/agent_internal.rs:332 [TRACE] 20:15:23.596612 - [controlling]: Set selected candidate pair: Some(prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431))
ice/src/agent/agent_internal.rs:312 [INFO] 20:15:23.596668 - [controlling]: Setting new connection state: Connected
webrtc/src/peer_connection/mod.rs:620 [INFO] 20:15:23.596914 - ICE connection state changed: connected
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.599010 - [handshake:server] Flight 0: Preparing
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.599059 - [handshake:server] Flight 0: Sending
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.599154 - [handshake:server] Flight 0: Waiting
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.599255 - Unsupported Extension Type 0 35
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.599266 - Unsupported Extension Type 0 22
dtls/src/conn/mod.rs:1012 [TRACE] 20:15:23.599277 - Recv [handshake:server] -> ClientHello (epoch: 0, seq: 0)
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.599319 - Unsupported Extension Type 0 35
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.599340 - Unsupported Extension Type 0 22
dtls/src/flight/flight0.rs:84 [DEBUG] 20:15:23.599377 - [handshake:server] use cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
dtls/src/handshaker.rs:345 [TRACE] 20:15:23.599737 - [handshake:server] Flight 0 -> Flight 2
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.599751 - [handshake:server] Flight 2: Preparing
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.599764 - [handshake:server] Flight 2: Sending
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.599781 - Send [handshake:server] -> HelloVerifyRequest (epoch: 0, seq: 0)
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.599883 - [handshake:server] Flight 2: Waiting
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.610855 - Unsupported Extension Type 0 35
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.610902 - Unsupported Extension Type 0 22
dtls/src/conn/mod.rs:1012 [TRACE] 20:15:23.610934 - Recv [handshake:server] -> ClientHello (epoch: 0, seq: 1)
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.611057 - Unsupported Extension Type 0 35
dtls/src/handshake/handshake_message_client_hello.rs:173 [WARN] 20:15:23.611080 - Unsupported Extension Type 0 22
dtls/src/handshaker.rs:345 [TRACE] 20:15:23.611140 - [handshake:server] Flight 2 -> Flight 4
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.611166 - [handshake:server] Flight 4: Preparing
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.611415 - [handshake:server] Flight 4: Sending
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.611486 - Send [handshake:server] -> ServerHello (epoch: 0, seq: 1)
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.611536 - Send [handshake:server] -> Certificate (epoch: 0, seq: 2)
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.611575 - Send [handshake:server] -> ServerKeyExchange (epoch: 0, seq: 3)
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.611613 - Send [handshake:server] -> CertificateRequest (epoch: 0, seq: 4)
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.611649 - Send [handshake:server] -> ServerHelloDone (epoch: 0, seq: 5)
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.611755 - [handshake:server] Flight 4: Waiting
dtls/src/conn/mod.rs:1012 [TRACE] 20:15:23.625638 - Recv [handshake:server] -> Certificate (epoch: 0, seq: 2)
dtls/src/conn/mod.rs:1012 [TRACE] 20:15:23.625724 - Recv [handshake:server] -> ClientKeyExchange (epoch: 0, seq: 3)
dtls/src/conn/mod.rs:1012 [TRACE] 20:15:23.625786 - Recv [handshake:server] -> CertificateVerify (epoch: 0, seq: 4)
dtls/src/conn/mod.rs:1091 [DEBUG] 20:15:23.625826 - server: CipherSuite not initialized, queuing packet
dtls/src/conn/mod.rs:919 [DEBUG] 20:15:23.625852 - server: received packet of next epoch, queuing packet
dtls/src/flight/flight4.rs:112 [TRACE] 20:15:23.625956 - [handshake] PeerCertificates4 1
dtls/src/crypto/mod.rs:340 [TRACE] 20:15:23.626719 - Picked an algorithm ECDSA_P256_SHA256_ASN1
dtls/src/conn/mod.rs:1101 [TRACE] 20:15:23.629633 - server: <- ChangeCipherSpec (epoch: 1)
dtls/src/conn/mod.rs:1012 [TRACE] 20:15:23.629710 - Recv [handshake:server] -> Finished (epoch: 1, seq: 5)
dtls/src/flight/flight4.rs:444 [TRACE] 20:15:23.629736 - server peer_certificates.len() 1
dtls/src/handshaker.rs:345 [TRACE] 20:15:23.629750 - [handshake:server] Flight 4 -> Flight 6
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.629759 - [handshake:server] Flight 6: Preparing
dtls/src/handshaker.rs:286 [TRACE] 20:15:23.629890 - [handshake:server] -> changeCipherSpec (epoch: 1)
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.629896 - [handshake:server] Flight 6: Sending
dtls/src/conn/mod.rs:546 [TRACE] 20:15:23.629919 - Send [handshake:server] -> Finished (epoch: 1, seq: 6)
dtls/src/handshaker.rs:204 [TRACE] 20:15:23.630005 - [handshake:server] Flight 6: Finished
dtls/src/conn/mod.rs:390 [TRACE] 20:15:23.630015 - Handshake Completed
webrtc/src/peer_connection/mod.rs:900 [INFO] 20:15:23.630714 - peer connection state changed: connected
Peer Connection State has changed: connected
sctp/src/association/association_internal.rs:165 [TRACE] 20:15:23.631341 - [] updated cwnd=4380 ssthresh=0 inflight=0 (INI)
sctp/src/association/association_internal.rs:594 [DEBUG] 20:15:23.631558 - [] state change: 'Closed' => 'CookieWait'
sctp/src/association/association_internal.rs:179 [DEBUG] 20:15:23.631568 - [] sending INIT
sctp/src/association/mod.rs:486 [DEBUG] 20:15:23.631602 - [] write_loop entered
sctp/src/association/mod.rs:430 [DEBUG] 20:15:23.631697 - [] read_loop entered
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.639596 - [] recving 100 bytes
sctp/src/association/association_internal.rs:610 [DEBUG] 20:15:23.639645 - [] chunkInit received in state 'CookieWait'
sctp/src/association/association_internal.rs:651 [DEBUG] 20:15:23.639653 - [] use ForwardTSN (on init)
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.639842 - [] recving 352 bytes
sctp/src/association/association_internal.rs:716 [DEBUG] 20:15:23.639862 - [] chunkInitAck received in state 'CookieWait'
sctp/src/association/association_internal.rs:743 [DEBUG] 20:15:23.639869 - [] initial rwnd=131072
sctp/src/association/association_internal.rs:750 [TRACE] 20:15:23.639873 - [] updated cwnd=4380 ssthresh=131072 inflight=0 (INI)
sctp/src/association/association_internal.rs:770 [DEBUG] 20:15:23.639915 - [] use ForwardTSN (on initAck)
sctp/src/association/association_internal.rs:203 [DEBUG] 20:15:23.639925 - [] sending COOKIE-ECHO
sctp/src/association/association_internal.rs:594 [DEBUG] 20:15:23.639936 - [] state change: 'CookieWait' => 'CookieEchoed'
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.652143 - [] recving 48 bytes
sctp/src/association/association_internal.rs:832 [DEBUG] 20:15:23.652442 - [] COOKIE-ECHO received in state 'CookieEchoed'
sctp/src/association/association_internal.rs:594 [DEBUG] 20:15:23.652496 - [] state change: 'CookieEchoed' => 'Established'
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.652801 - [] recving 16 bytes
sctp/src/association/association_internal.rs:880 [DEBUG] 20:15:23.652840 - [] COOKIE-ACK received in state 'Established'
sctp/src/stream/mod.rs:354 [TRACE] 20:15:23.653250 - [1:] bufferedAmount = 16
sctp/src/association/association_internal.rs:1862 [TRACE] 20:15:23.653432 - [] sending ppi=50 tsn=3398947670 ssn=0 sent=1 len=16 (true,true)
sctp/src/association/association_internal.rs:355 [TRACE] 20:15:23.653452 - [] T3-rtx timer start (pt1)
Data channel 'data'-'1' open. Random messages will now be sent to any connected DataChannels every 5 seconds
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.665557 - [] recving 80 bytes
sctp/src/association/association_internal.rs:903 [TRACE] 20:15:23.665617 - [] DATA: tsn=138126322 immediateSack=false len=50
sctp/src/stream/mod.rs:208 [DEBUG] 20:15:23.665670 - [1:] reassemblyQueue readable=true
sctp/src/stream/mod.rs:216 [DEBUG] 20:15:23.665715 - [1:] readNotifier.signal()
sctp/src/stream/mod.rs:218 [DEBUG] 20:15:23.665726 - [1:] readNotifier.signal() done
sctp/src/association/association_internal.rs:970 [DEBUG] 20:15:23.665732 - [] peer_last_tsn = 138126321
sctp/src/association/association_internal.rs:973 [DEBUG] 20:15:23.665739 - [] peer_last_tsn = 138126322
Message!!!
Message from DataChannel 'data': '{"type":"validation","data":"kYykRghmTrtZIOLBYsH"}'
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.665868 - [] recving 80 bytes
sctp/src/association/association_internal.rs:903 [TRACE] 20:15:23.665925 - [] DATA: tsn=138126323 immediateSack=false len=50
sctp/src/stream/mod.rs:208 [DEBUG] 20:15:23.665938 - [1:] reassemblyQueue readable=true
sctp/src/stream/mod.rs:216 [DEBUG] 20:15:23.665970 - [1:] readNotifier.signal()
Message!!!
Message from DataChannel 'data': '{"type":"validation","data":"kYykRghmTrtZIOLBYsH"}'
sctp/src/stream/mod.rs:218 [DEBUG] 20:15:23.665978 - [1:] readNotifier.signal() done
sctp/src/association/association_internal.rs:970 [DEBUG] 20:15:23.666033 - [] peer_last_tsn = 138126322
sctp/src/association/association_internal.rs:973 [DEBUG] 20:15:23.666040 - [] peer_last_tsn = 138126323
sctp/src/association/mod.rs:455 [DEBUG] 20:15:23.666061 - [] recving 28 bytes
sctp/src/association/association_internal.rs:1362 [TRACE] 20:15:23.666073 - [] 3398947669, SACK: cumTSN=3398947670 a_rwnd=131072
sctp/src/association/association_internal.rs:1136 [TRACE] 20:15:23.666087 - [] SACK: measured-rtt=12 srtt=12 new-rto=1000
sctp/src/association/association_internal.rs:1408 [TRACE] 20:15:23.666096 - [] SACK: cumTSN advanced: 3398947669 -> 3398947670
sctp/src/association/association_internal.rs:1220 [TRACE] 20:15:23.666103 - [] SACK: no more packet in-flight (pending=0)
sctp/src/association/association_internal.rs:1259 [TRACE] 20:15:23.666121 - [] cwnd did not grow: cwnd=4380 ssthresh=131072 acked=16 FR=false pending=0
sctp/src/stream/mod.rs:450 [TRACE] 20:15:23.666129 - [1:] bufferedAmount = 0, from_amount = 16, buffered_amount_low = 0
sctp/src/association/association_internal.rs:482 [DEBUG] 20:15:23.666207 - [] sending SACK: SACK cumTsnAck=138126323 arwnd=1048576 dupTsn=[]
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:23.789660 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:23.991860 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:24.193170 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:24.395652 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:24.597639 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:24.799834 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:25.002397 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:25.204854 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:25.407245 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:25.609284 - [controlling]: checking keepalive
mdns/src/conn/mod.rs:273 [TRACE] 20:15:25.796417 - Received new connection from 192.168.88.39:5353
mdns/src/conn/mod.rs:309 [TRACE] 20:15:25.796552 - Parsing has completed
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:25.811823 - [controlling]: checking keepalive
ice/src/agent/agent_internal.rs:715 [TRACE] 20:15:25.812115 - [controlling]: ping STUN from udp4 host 192.168.88.147:54506 to udp4 host 192.168.88.93:38476
ice/src/agent/agent_selector.rs:323 [TRACE] 20:15:25.821919 - inbound STUN (SuccessResponse) from udp4 host 192.168.88.93:38476 to udp4 host 192.168.88.147:54506
ice/src/agent/agent_selector.rs:333 [TRACE] 20:15:25.822009 - Found valid candidate pair: prio 9151314440652587007 (local, prio 2130706431) udp4 host 192.168.88.147:54506 <-> udp4 host 192.168.88.93:38476 (remote, prio 2130706431), p.state: 4, isUseCandidate: false, false
srtp/src/session/mod.rs:159 [TRACE] 20:15:25.873595 - srtp session got new rtcp stream 305150496
webrtc/src/peer_connection/peer_connection_internal.rs:322 [WARN] 20:15:25.873716 - Incoming unhandled RTCP ssrc(305150496), on_track will not be fired
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:26.015188 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:26.217836 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:26.419031 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:26.621058 - [controlling]: checking keepalive
mdns/src/conn/mod.rs:273 [TRACE] 20:15:26.785020 - Received new connection from 192.168.88.39:5353
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:26.823232 - [controlling]: checking keepalive
mdns/src/conn/mod.rs:273 [TRACE] 20:15:26.923576 - Received new connection from 192.168.88.110:5353
mdns/src/conn/mod.rs:309 [TRACE] 20:15:26.923727 - Parsing has completed
mdns/src/conn/mod.rs:273 [TRACE] 20:15:26.945361 - Received new connection from 192.168.88.107:5353
mdns/src/conn/mod.rs:309 [TRACE] 20:15:26.945495 - Parsing has completed
mdns/src/conn/mod.rs:273 [TRACE] 20:15:26.961648 - Received new connection from 192.168.88.103:5353
mdns/src/conn/mod.rs:309 [TRACE] 20:15:26.961691 - Parsing has completed
mdns/src/conn/mod.rs:273 [TRACE] 20:15:26.995637 - Received new connection from 192.168.88.39:5353
mdns/src/conn/mod.rs:273 [TRACE] 20:15:27.008864 - Received new connection from 192.168.88.104:5353
mdns/src/conn/mod.rs:309 [TRACE] 20:15:27.008980 - Parsing has completed
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:27.025511 - [controlling]: checking keepalive
mdns/src/conn/mod.rs:273 [TRACE] 20:15:27.092390 - Received new connection from 192.168.88.104:5353
mdns/src/conn/mod.rs:309 [TRACE] 20:15:27.092430 - Parsing has completed
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:27.227514 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:27.430319 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:27.632907 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:27.835125 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:28.037455 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:28.239531 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:28.441596 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:28.644231 - [controlling]: checking keepalive
Sending 'TqRDtQjtyeTZTwI'
sctp/src/stream/mod.rs:354 [TRACE] 20:15:28.655698 - [1:] bufferedAmount = 15
sctp/src/association/association_internal.rs:1862 [TRACE] 20:15:28.655882 - [] sending ppi=51 tsn=3398947671 ssn=1 sent=1 len=15 (true,true)
sctp/src/association/association_internal.rs:355 [TRACE] 20:15:28.655927 - [] T3-rtx timer start (pt1)
sctp/src/association/mod.rs:455 [DEBUG] 20:15:28.666676 - [] recving 76 bytes
sctp/src/association/association_internal.rs:903 [TRACE] 20:15:28.666767 - [] DATA: tsn=138126324 immediateSack=false len=46
sctp/src/stream/mod.rs:208 [DEBUG] 20:15:28.666814 - [1:] reassemblyQueue readable=true
sctp/src/stream/mod.rs:216 [DEBUG] 20:15:28.666831 - [1:] readNotifier.signal()
sctp/src/stream/mod.rs:218 [DEBUG] 20:15:28.666864 - [1:] readNotifier.signal() done
sctp/src/association/association_internal.rs:970 [DEBUG] 20:15:28.666881 - [] peer_last_tsn = 138126323
sctp/src/association/association_internal.rs:973 [DEBUG] 20:15:28.666900 - [] peer_last_tsn = 138126324
Message!!!
Message from DataChannel 'data': '{"type":"err", "info":"Failed to parse json."}'
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:28.845738 - [controlling]: checking keepalive
sctp/src/association/association_internal.rs:2259 [TRACE] 20:15:28.867600 - [] ack timed out (ack_state: Delay)
sctp/src/association/association_internal.rs:482 [DEBUG] 20:15:28.867684 - [] sending SACK: SACK cumTsnAck=138126324 arwnd=1048576 dupTsn=[]
sctp/src/association/mod.rs:455 [DEBUG] 20:15:28.867760 - [] recving 28 bytes
sctp/src/association/association_internal.rs:1362 [TRACE] 20:15:28.867785 - [] 3398947670, SACK: cumTSN=3398947671 a_rwnd=131072
sctp/src/association/association_internal.rs:1136 [TRACE] 20:15:28.867827 - [] SACK: measured-rtt=211 srtt=36 new-rto=1000
sctp/src/association/association_internal.rs:1408 [TRACE] 20:15:28.867897 - [] SACK: cumTSN advanced: 3398947670 -> 3398947671
sctp/src/association/association_internal.rs:1220 [TRACE] 20:15:28.867905 - [] SACK: no more packet in-flight (pending=0)
sctp/src/association/association_internal.rs:1259 [TRACE] 20:15:28.867912 - [] cwnd did not grow: cwnd=4380 ssthresh=131072 acked=15 FR=false pending=0
sctp/src/stream/mod.rs:450 [TRACE] 20:15:28.867920 - [1:] bufferedAmount = 0, from_amount = 15, buffered_amount_low = 0
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:29.046410 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:29.248198 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:29.449794 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:29.651323 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:29.852851 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:30.054989 - [controlling]: checking keepalive
ice/src/agent/agent_selector.rs:242 [TRACE] 20:15:30.256875 - [controlling]: checking keepalive
use std::io::Write;
use std::sync::Arc;
use anyhow::Result;
use clap::{AppSettings, Arg, Command};
use tokio::time::Duration;
use tokio::sync::{Mutex, Notify};
use webrtc::api::interceptor_registry::register_default_interceptors;
use webrtc::api::APIBuilder;
use webrtc::data_channel::data_channel_message::DataChannelMessage;
use webrtc::ice_transport::ice_server::RTCIceServer;
use webrtc::interceptor::registry::Registry;
use webrtc::peer_connection::configuration::RTCConfiguration;
use webrtc::peer_connection::math_rand_alpha;
use webrtc::peer_connection::peer_connection_state::RTCPeerConnectionState;
use webrtc::peer_connection::sdp::session_description::RTCSessionDescription;
use webrtc::rtp_transceiver::rtp_codec::{
RTCRtpCodecCapability, RTCRtpCodecParameters, RTPCodecType,
};
use webrtc::api::media_engine::{MediaEngine, MIME_TYPE_OPUS, MIME_TYPE_H264};
use webrtc::track::track_remote::TrackRemote;
use webrtc::rtp_transceiver::rtp_transceiver_direction::RTCRtpTransceiverDirection;
use webrtc::rtp_transceiver::RTCRtpTransceiverInit;
use webrtc::media::io::h264_writer::H264Writer;
use webrtc::media::io::ogg_writer::OggWriter;
use reqwest::Client;
use serde::{Serialize, Deserialize};
use serde_json::Value;
use webrtc::rtcp::payload_feedbacks::picture_loss_indication::PictureLossIndication;
use std::fs::File;
#[derive(Serialize)]
struct PostData {
sdp: String,
id: String,
#[serde(rename = "type")]
type_field: String,
token: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct SDPMessage {
#[serde(rename = "type")]
type_field: String,
sdp: String,
}
async fn save_to_disk(
writer: Arc<Mutex<dyn webrtc::media::io::Writer + Send + Sync>>,
track: Arc<TrackRemote>,
notify: Arc<Notify>,
) -> Result<()> {
loop {
tokio::select! {
result = track.read_rtp() => {
if let Ok((rtp_packet, _)) = result {
let mut w = writer.lock().await;
w.write_rtp(&rtp_packet)?;
}else{
println!("file closing begin after read_rtp error");
let mut w = writer.lock().await;
if let Err(err) = w.close() {
println!("file close err: {err}");
}
println!("file closing end after read_rtp error");
return Ok(());
}
}
_ = notify.notified() => {
println!("file closing begin after notified");
let mut w = writer.lock().await;
if let Err(err) = w.close() {
println!("file close err: {err}");
}
println!("file closing end after notified");
return Ok(());
}
}
}
}
async fn post_offer(ip: &str, token: &str, offer_sdp: &str) -> Result<Option<Value>> {
let url = format!("http://{}:8081/offer", ip);
let client = Client::new();
let data = PostData {
sdp: offer_sdp.to_string(),
id: "STA_localNetwork".to_string(),
type_field: "offer".to_string(),
token: token.to_string(),
};
let resp = client.post(&url)
.json(&data)
.header("content-type", "application/json")
.send()
.await?;
match resp.status().is_success() {
true => {
let json: Value = resp.json().await?;
Ok(Some(json))
},
false => {
println!("Failed to get answer from server");
Ok(None)
},
}
}
#[tokio::main]
async fn main() -> Result<()> {
let mut app = Command::new("data-channels-create")
.version("0.1.0")
.author("Rain Liu <yliu@webrtc.rs>")
.about("An example of Data-Channels-Create.")
.setting(AppSettings::DeriveDisplayOrder)
.subcommand_negates_reqs(true)
.arg(
Arg::new("FULLHELP")
.help("Prints more detailed help information")
.long("fullhelp"),
)
.arg(
Arg::new("vp9")
.long("vp9")
.help("Save VP9 to disk. Default: VP8"),
)
.arg(
Arg::new("video")
.required_unless_present("FULLHELP")
.takes_value(true)
.short('v')
.long("video")
.help("Video file to be streaming."),
)
.arg(
Arg::new("audio")
.required_unless_present("FULLHELP")
.takes_value(true)
.short('a')
.long("audio")
.help("Audio file to be streaming."),
)
.arg(
Arg::new("debug")
.long("debug")
.short('d')
.help("Prints debug log information"),
);
let matches = app.clone().get_matches();
if matches.is_present("FULLHELP") {
app.print_long_help().unwrap();
std::process::exit(0);
}
let video_file = matches.value_of("video").unwrap();
let audio_file = matches.value_of("audio").unwrap();
let h264_writer: Arc<Mutex<dyn webrtc::media::io::Writer + Send + Sync>> =
Arc::new(Mutex::new(H264Writer::new(File::create(video_file)?)));
let ogg_writer: Arc<Mutex<dyn webrtc::media::io::Writer + Send + Sync>> = Arc::new(Mutex::new(
OggWriter::new(File::create(audio_file)?, 48000, 2)?,
));
let debug = matches.is_present("debug");
if debug {
env_logger::Builder::new()
.format(|buf, record| {
writeln!(
buf,
"{}:{} [{}] {} - {}",
record.file().unwrap_or("unknown"),
record.line().unwrap_or(0),
record.level(),
chrono::Local::now().format("%H:%M:%S.%6f"),
record.args()
)
})
.filter(None, log::LevelFilter::Trace)
.init();
}
// Everything below is the WebRTC-rs API! Thanks for using it ❤️.
// Create a MediaEngine object to configure the supported codec
let mut m = MediaEngine::default();
m.register_codec(
RTCRtpCodecParameters {
capability: RTCRtpCodecCapability {
mime_type: MIME_TYPE_H264.to_owned(),
clock_rate: 90000,
channels: 0,
sdp_fmtp_line: "".to_owned(),
rtcp_feedback: vec![],
},
payload_type: 102,
..Default::default()
},
RTPCodecType::Video,
)?;
m.register_codec(
RTCRtpCodecParameters {
capability: RTCRtpCodecCapability {
mime_type: MIME_TYPE_OPUS.to_owned(),
clock_rate: 48000,
channels: 2,
sdp_fmtp_line: "".to_owned(),
rtcp_feedback: vec![],
},
payload_type: 111,
..Default::default()
},
RTPCodecType::Audio,
)?;
// Register default codecs
m.register_default_codecs()?;
// Create a InterceptorRegistry. This is the user configurable RTP/RTCP Pipeline.
// This provides NACKs, RTCP Reports and other features. If you use `webrtc.NewPeerConnection`
// this is enabled by default. If you are manually managing You eUST create a InterceptorRegistry
// for each PeerConnection.
let mut registry = Registry::new();
// Use the default set of Interceptors
registry = register_default_interceptors(registry, &mut m)?;
// Create the API object with the MediaEngine
let api = APIBuilder::new()
.with_media_engine(m)
.with_interceptor_registry(registry)
.build();
// Prepare the configuration
let config = RTCConfiguration {
ice_servers: vec![RTCIceServer {
// urls: vec!["stun:stun.l.google.com:19302".to_owned()],
..Default::default()
}],
..Default::default()
};
// Create a new RTCPeerConnection
let peer_connection = Arc::new(api.new_peer_connection(config).await?);
// Create a datachannel with label 'data'
let data_channel = peer_connection.create_data_channel("data", None).await?;
peer_connection
.add_transceiver_from_kind(RTPCodecType::Video, Some(RTCRtpTransceiverInit {
direction: RTCRtpTransceiverDirection::Sendrecv,
send_encodings: vec![],
}))
.await?;
let notify_tx = Arc::new(Notify::new());
let notify_rx = notify_tx.clone();
// Set a handler for when a new remote track starts, this handler saves buffers to disk as
// an ivf file, since we could have multiple video tracks we provide a counter.
// In your application this is where you would handle/process video
let pc = Arc::downgrade(&peer_connection);
peer_connection.on_track(Box::new(move |track, _, _| {
// Send a PLI on an interval so that the publisher is pushing a keyframe every rtcpPLIInterval
let media_ssrc = track.ssrc();
let pc2 = pc.clone();
tokio::spawn(async move {
let mut result = Result::<usize>::Ok(0);
while result.is_ok() {
let timeout = tokio::time::sleep(Duration::from_secs(3));
tokio::pin!(timeout);
tokio::select! {
_ = timeout.as_mut() =>{
if let Some(pc) = pc2.upgrade(){
result = pc.write_rtcp(&[Box::new(PictureLossIndication{
sender_ssrc: 0,
media_ssrc,
})]).await.map_err(Into::into);
}else {
break;
}
}
};
}
});
let notify_rx2 = Arc::clone(&notify_rx);
let h264_writer2 = Arc::clone(&h264_writer);
let ogg_writer2 = Arc::clone(&ogg_writer);
Box::pin(async move {
let codec = track.codec();
let mime_type = codec.capability.mime_type.to_lowercase();
if mime_type == MIME_TYPE_OPUS.to_lowercase() {
println!("Got Opus track, saving to disk as output.opus (48 kHz, 2 channels)");
tokio::spawn(async move {
let _ = save_to_disk(ogg_writer2, track, notify_rx2).await;
});
} else if mime_type == MIME_TYPE_H264.to_lowercase() {
println!("Got h264 track, saving to disk as output.h264");
tokio::spawn(async move {
let _ = save_to_disk(h264_writer2, track, notify_rx2).await;
});
}
})
}));
let (done_tx, mut done_rx) = tokio::sync::mpsc::channel::<()>(1);
// Set the handler for Peer connection state
// This will notify you when the peer has connected/disconnected
peer_connection.on_peer_connection_state_change(Box::new(move |s: RTCPeerConnectionState| {
println!("Peer Connection State has changed: {s}");
if s == RTCPeerConnectionState::Failed {
// Wait until PeerConnection has had no network activity for 30 seconds or another failure. It may be reconnected using an ICE Restart.
// Use webrtc.PeerConnectionStateDisconnected if you are interested in detecting faster timeout.
// Note that the PeerConnection may come back from PeerConnectionStateDisconnected.
println!("Peer Connection has gone to failed exiting");
let _ = done_tx.try_send(());
}
Box::pin(async {})
}));
// Register channel opening handling
let d1 = Arc::clone(&data_channel);
data_channel.on_open(Box::new(move || {
println!("Data channel '{}'-'{}' open. Random messages will now be sent to any connected DataChannels every 5 seconds", d1.label(), d1.id());
let d2 = Arc::clone(&d1);
Box::pin(async move {
let mut result = Result::<usize>::Ok(0);
while result.is_ok() {
let timeout = tokio::time::sleep(Duration::from_secs(5));
tokio::pin!(timeout);
tokio::select! {
_ = timeout.as_mut() =>{
let message = math_rand_alpha(15);
println!("Sending '{message}'");
result = d2.send_text(message).await.map_err(Into::into);
}
};
}
})
}));
// Register text message handling
let d_label = data_channel.label().to_owned();
data_channel.on_message(Box::new(move |msg: DataChannelMessage| {
println!("Message!!!");
let msg_str = String::from_utf8(msg.data.to_vec()).unwrap();
println!("Message from DataChannel '{d_label}': '{msg_str}'");
Box::pin(async {})
}));
// Create an offer to send to the browser
let offer = peer_connection.create_offer(None).await?;
// Create channel that is blocked until ICE Gathering is complete
let mut gather_complete = peer_connection.gathering_complete_promise().await;
// Sets the LocalDescription, and starts our UDP listeners
peer_connection.set_local_description(offer).await?;
// Block until ICE Gathering is complete, disabling trickle ICE
// we do this because we only can exchange one signaling message
// in a production application you should exchange ICE Candidates via OnICECandidate
let _ = gather_complete.recv().await;
let mut line = "".to_string();
// Output the answer in base64 so we can paste it in browser
if let Some(local_desc) = peer_connection.local_description().await {
let json_str = serde_json::to_string(&local_desc)?;
println!("{json_str}");
let ip = "192.168.88.93";
let token = ";
match post_offer(&ip, &token, &local_desc.sdp).await {
Ok(Some(json)) => {
line = json.to_string();
println!("Received response: {}", line);
},
Ok(None) => println!("No response received."),
Err(e) => println!("Error occurred: {}", e),
}
} else {
println!("generate local_description failed!");
}
// Wait for the answer to be pasted
// let line = signal::must_read_stdin()?;
let desc_data = line; // signal::decode(line.as_str())?;
let answer = serde_json::from_str::<RTCSessionDescription>(&desc_data)?;
// Apply the answer as the remote description
peer_connection.set_remote_description(answer).await?;
println!("Press ctrl-c to stop");
tokio::select! {
_ = done_rx.recv() => {
println!("received done signal!");
}
_ = tokio::signal::ctrl_c() => {
println!();
}
};
peer_connection.close().await?;
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment