7.3. Early Transport Warmup Example (Esempio di riscaldamento anticipato del trasporto)
Questo esempio dimostra la tecnica di riscaldamento anticipato descritta nella sezione 4.1.10.1. Qui, l'endpoint di Alice invia un'offerta all'endpoint di Bob per avviare una chiamata audio/video. Bob risponde immediatamente con una risposta che accetta le sezioni "m=" audio/video ma le contrassegna come sendonly (dal suo punto di vista), il che significa che Alice non invierà ancora media. Ciò consente all'implementazione JSEP di iniziare immediatamente a negoziare ICE e DTLS. L'endpoint di Bob gli richiede quindi di rispondere alla chiamata e, quando lo fa, il suo endpoint invia una seconda offerta, che abilita le sezioni "m=" audio e video, e quindi la trasmissione media bidirezionale. Il vantaggio di tale flusso è che non appena viene ricevuta la prima risposta, l'implementazione può procedere con la negoziazione ICE e DTLS e stabilire il trasporto di sessione. Se la configurazione del trasporto viene completata prima dell'invio della seconda offerta, il media può essere trasmesso dal destinatario immediatamente dopo aver risposto alla chiamata, riducendo al minimo il ritardo post-composizione percepito. Il secondo scambio offerta/risposta può anche modificare i codec preferiti o altri parametri di sessione.
Questo esempio fa anche uso della politica dei candidati ICE "relay" descritta nella sezione 3.5.3 per ridurre al minimo la raccolta e il controllo ICE necessari.
// set up local media state
AliceJS->AliceUA: create new PeerConnection with "relay" ICE policy
AliceJS->AliceUA: addTrack with two tracks: audio and video
AliceJS->AliceUA: createOffer to get |offer-C1|
AliceJS->AliceUA: setLocalDescription with |offer-C1|
// |offer-C1| is sent over signaling protocol to Bob
AliceJS->WebServer: signaling with |offer-C1|
WebServer->BobJS: signaling with |offer-C1|
// |offer-C1| arrives at Bob
BobJS->BobUA: create new PeerConnection with "relay" ICE policy
BobJS->BobUA: setRemoteDescription with |offer-C1|
BobUA->BobJS: ontrack events for audio and video
// a relay candidate is sent to Bob
AliceUA->AliceJS: onicecandidate (relay) |offer-C1-candidate-1|
AliceJS->WebServer: signaling with |offer-C1-candidate-1|
WebServer->BobJS: signaling with |offer-C1-candidate-1|
BobJS->BobUA: addIceCandidate with |offer-C1-candidate-1|
// Bob prepares an early answer to warm up the
// transport
BobJS->BobUA: addTransceiver with null audio and video tracks
BobJS->BobUA: transceiver.setDirection(sendonly) for both
BobJS->BobUA: createAnswer
BobJS->BobUA: setLocalDescription with answer
// |answer-C1| is sent over signaling protocol
// to Alice
BobJS->WebServer: signaling with |answer-C1|
WebServer->AliceJS: signaling with |answer-C1|
// |answer-C1| (sendonly) arrives at Alice
AliceJS->AliceUA: setRemoteDescription with |answer-C1|
AliceUA->AliceJS: ontrack events for audio and video
// a relay candidate is sent to Alice
BobUA->BobJS: onicecandidate (relay) |answer-B1-candidate-1|
BobJS->WebServer: signaling with |answer-B1-candidate-1|
WebServer->AliceJS: signaling with |answer-B1-candidate-1|
AliceJS->AliceUA: addIceCandidate with |answer-B1-candidate-1|
// ICE and DTLS establish while call is ringing
// Bob accepts call, starts media, and sends
// new offer
BobJS->BobUA: transceiver.setTrack with audio and video tracks
BobUA->AliceUA: media sent from Bob to Alice
BobJS->BobUA: transceiver.setDirection(sendrecv) for both
transceivers
BobJS->BobUA: createOffer
BobJS->BobUA: setLocalDescription with offer
// |offer-C2| is sent over signaling protocol
// to Alice
BobJS->WebServer: signaling with |offer-C2|
WebServer->AliceJS: signaling with |offer-C2|
// |offer-C2| (sendrecv) arrives at Alice
AliceJS->AliceUA: setRemoteDescription with |offer-C2|
AliceJS->AliceUA: createAnswer
AliceJS->AliceUA: setLocalDescription with |answer-C2|
AliceUA->BobUA: media sent from Alice to Bob
// |answer-C2| is sent over signaling protocol
// to Bob
AliceJS->WebServer: signaling with |answer-C2|
WebServer->BobJS: signaling with |answer-C2|
BobJS->BobUA: setRemoteDescription with |answer-C2|
L'SDP per |offer-C1| è simile a:
v=0
o=- 1070771854436052752 1 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle ice2
a=group:BUNDLE a1 v1
a=group:LS a1 v1
m=audio 9 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 0.0.0.0
a=mid:a1
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=fmtp:97 0-15
a=fmtp:98 0-15
a=maxptime:120
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=msid:bbce3ba6-abfc-ac63-d00a-e15b286f8fce
a=ice-ufrag:4ZcD
a=ice-pwd:ZaaG6OG7tCn4J/lehAGz+HHD
a=fingerprint:sha-256
C4:68:F8:77:6A:44:F1:98:6D:7C:9F:47:EB:E3:34:A4:
0A:AA:2D:49:08:28:70:2E:1F:AE:18:7D:4E:3E:66:BF
a=setup:actpass
a=tls-id:9e5b948ade9c3d41de6617b68f769e55
a=rtcp-mux
a=rtcp-mux-only
a=rtcp-rsize
m=video 0 UDP/TLS/RTP/SAVPF 100 101 102 103
c=IN IP4 0.0.0.0
a=mid:v1
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 H264/90000
a=fmtp:101 packetization-mode=1;profile-level-id=42e01f
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=100
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=101
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=msid:bbce3ba6-abfc-ac63-d00a-e15b286f8fce
a=bundle-only
|offer-C1-candidate-1| è simile a:
ufrag 4ZcD
index 0
mid a1
attr candidate:1 1 udp 255 192.0.2.100 12100 typ relay
raddr 0.0.0.0 rport 0
L'SDP per |answer-C1| è simile a:
v=0
o=- 6386516489780559513 1 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle ice2
a=group:BUNDLE a1 v1
a=group:LS a1 v1
m=audio 9 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 0.0.0.0
a=mid:a1
a=sendonly
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=fmtp:97 0-15
a=fmtp:98 0-15
a=maxptime:120
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=msid:751f239e-4ae0-c549-aa3d-890de772998b
a=ice-ufrag:TpaA
a=ice-pwd:t2Ouhc67y8JcCaYZxUUTgKw/
a=fingerprint:sha-256
A2:F3:A5:6D:4C:8C:1E:B2:62:10:4A:F6:70:61:C4:FC:
3C:E0:01:D6:F3:24:80:74:DA:7C:3E:50:18:7B:CE:4D
a=setup:active
a=tls-id:55e967f86b7166ed14d3c9eda849b5e9
a=rtcp-mux
a=rtcp-mux-only
a=rtcp-rsize
m=video 9 UDP/TLS/RTP/SAVPF 100 101 102 103
c=IN IP4 0.0.0.0
a=mid:v1
a=sendonly
a=rtpmap:100 VP8/90000
a=rtpmap:101 H264/90000
a=fmtp:101 packetization-mode=1;profile-level-id=42e01f
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=100
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=101
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=msid:751f239e-4ae0-c549-aa3d-890de772998b
|answer-C1-candidate-1| è simile a:
ufrag TpaA
index 0
mid a1
attr candidate:1 1 udp 255 192.0.2.200 12200 typ relay
raddr 0.0.0.0 rport 0
L'SDP per |offer-C2| è simile a:
v=0
o=- 6386516489780559513 2 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle ice2
a=group:BUNDLE a1 v1
a=group:LS a1 v1
m=audio 12200 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 192.0.2.200
a=mid:a1
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=fmtp:97 0-15
a=fmtp:98 0-15
a=maxptime:120
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=msid:751f239e-4ae0-c549-aa3d-890de772998b
a=ice-ufrag:TpaA
a=ice-pwd:t2Ouhc67y8JcCaYZxUUTgKw/
a=fingerprint:sha-256
A2:F3:A5:6D:4C:8C:1E:B2:62:10:4A:F6:70:61:C4:FC:
3C:E0:01:D6:F3:24:80:74:DA:7C:3E:50:18:7B:CE:4D
a=setup:actpass
a=tls-id:55e967f86b7166ed14d3c9eda849b5e9
a=rtcp-mux
a=rtcp-mux-only
a=rtcp-rsize
a=candidate:1 1 udp 255 192.0.2.200 12200 typ relay
raddr 0.0.0.0 rport 0
a=end-of-candidates
m=video 12200 UDP/TLS/RTP/SAVPF 100 101 102 103
c=IN IP4 192.0.2.200
a=mid:v1
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 H264/90000
a=fmtp:101 packetization-mode=1;profile-level-id=42e01f
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=100
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=101
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=msid:751f239e-4ae0-c549-aa3d-890de772998b
L'SDP per |answer-C2| è simile a:
v=0
o=- 1070771854436052752 2 IN IP4 0.0.0.0
s=-
t=0 0
a=ice-options:trickle ice2
a=group:BUNDLE a1 v1
a=group:LS a1 v1
m=audio 12100 UDP/TLS/RTP/SAVPF 96 0 8 97 98
c=IN IP4 192.0.2.100
a=mid:a1
a=sendrecv
a=rtpmap:96 opus/48000/2
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:97 telephone-event/8000
a=rtpmap:98 telephone-event/48000
a=fmtp:97 0-15
a=fmtp:98 0-15
a=maxptime:120
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:2 urn:ietf:params:rtp-hdrext:ssrc-audio-level
a=msid:bbce3ba6-abfc-ac63-d00a-e15b286f8fce
a=ice-ufrag:4ZcD
a=ice-pwd:ZaaG6OG7tCn4J/lehAGz+HHD
a=fingerprint:sha-256
C4:68:F8:77:6A:44:F1:98:6D:7C:9F:47:EB:E3:34:A4:
0A:AA:2D:49:08:28:70:2E:1F:AE:18:7D:4E:3E:66:BF
a=setup:passive
a=tls-id:9e5b948ade9c3d41de6617b68f769e55
a=rtcp-mux
a=rtcp-mux-only
a=rtcp-rsize
a=candidate:1 1 udp 255 192.0.2.100 12100 typ relay
raddr 0.0.0.0 rport 0
a=end-of-candidates
m=video 12100 UDP/TLS/RTP/SAVPF 100 101 102 103
c=IN IP4 192.0.2.100
a=mid:v1
a=sendrecv
a=rtpmap:100 VP8/90000
a=rtpmap:101 H264/90000
a=fmtp:101 packetization-mode=1;profile-level-id=42e01f
a=rtpmap:102 rtx/90000
a=fmtp:102 apt=100
a=rtpmap:103 rtx/90000
a=fmtp:103 apt=101
a=extmap:1 urn:ietf:params:rtp-hdrext:sdes:mid
a=extmap:3 urn:ietf:params:rtp-hdrext:sdes:rtp-stream-id
a=rtcp-fb:100 ccm fir
a=rtcp-fb:100 nack
a=rtcp-fb:100 nack pli
a=msid:bbce3ba6-abfc-ac63-d00a-e15b286f8fce