RTCPeerConnection-insertable-streams-simulcast.https.html (3430B)
1 <!doctype html> 2 <meta charset=utf-8> 3 <title>RTCPeerConnection Insertable Streams Simulcast</title> 4 <script src="/resources/testharness.js"></script> 5 <script src="/resources/testharnessreport.js"></script> 6 <script src=/resources/testdriver.js></script> 7 <script src=/resources/testdriver-vendor.js></script> 8 <script src='../../mediacapture-streams/permission-helper.js'></script> 9 <script src="../../webrtc/RTCPeerConnection-helper.js"></script> 10 <script src="../../webrtc/third_party/sdp/sdp.js"></script> 11 <script src="../../webrtc/simulcast/simulcast.js"></script> 12 <script> 13 // Test based on wpt/webrtc/simulcast/basic.https.html 14 promise_test(async t => { 15 const rids = [0, 1, 2]; 16 const pc1 = new RTCPeerConnection({encodedInsertableStreams:true}); 17 t.add_cleanup(() => pc1.close()); 18 const pc2 = new RTCPeerConnection({encodedInsertableStreams:true}); 19 t.add_cleanup(() => pc2.close()); 20 21 exchangeIceCandidates(pc1, pc2); 22 23 const metadataToBeLoaded = []; 24 let receiverSSRCs = [] 25 pc2.ontrack = t.step_func(e => { 26 const receiverTransformer = new TransformStream({ 27 async transform(encodedFrame, controller) { 28 let ssrc = encodedFrame.getMetadata().synchronizationSource; 29 if (receiverSSRCs.indexOf(ssrc) == -1) 30 receiverSSRCs.push(ssrc); 31 controller.enqueue(encodedFrame); 32 } 33 }); 34 const receiverStreams = e.receiver.createEncodedStreams(); 35 receiverStreams.readable 36 .pipeThrough(receiverTransformer) 37 .pipeTo(receiverStreams.writable); 38 39 const stream = e.streams[0]; 40 const v = document.createElement('video'); 41 v.autoplay = true; 42 v.srcObject = stream; 43 v.id = stream.id 44 metadataToBeLoaded.push(new Promise((resolve) => { 45 v.addEventListener('loadedmetadata', () => { 46 resolve(); 47 }); 48 })); 49 }); 50 51 await setMediaPermission("granted", ["camera"]); 52 const stream = await navigator.mediaDevices.getUserMedia({video: {width: 1280, height: 720}}); 53 t.add_cleanup(() => stream.getTracks().forEach(track => track.stop())); 54 const transceiver = pc1.addTransceiver(stream.getVideoTracks()[0], { 55 streams: [stream], 56 sendEncodings: rids.map(rid => {rid}), 57 }); 58 const senderStreams = transceiver.sender.createEncodedStreams(); 59 let senderSSRCs = []; 60 const senderTransformer = new TransformStream({ 61 async transform(encodedFrame, controller) { 62 if (senderSSRCs.indexOf(encodedFrame.getMetadata().synchronizationSource) == -1) 63 senderSSRCs.push(encodedFrame.getMetadata().synchronizationSource); 64 controller.enqueue(encodedFrame); 65 } 66 }); 67 senderStreams.readable 68 .pipeThrough(senderTransformer) 69 .pipeTo(senderStreams.writable); 70 71 const offer = await pc1.createOffer(); 72 await pc1.setLocalDescription(offer), 73 await pc2.setRemoteDescription({ 74 type: 'offer', 75 sdp: swapRidAndMidExtensionsInSimulcastOffer(offer, rids), 76 }); 77 const answer = await pc2.createAnswer(); 78 await pc2.setLocalDescription(answer); 79 await pc1.setRemoteDescription({ 80 type: 'answer', 81 sdp: swapRidAndMidExtensionsInSimulcastAnswer(answer, pc1.localDescription, rids), 82 }); 83 assert_equals(metadataToBeLoaded.length, 3); 84 await Promise.all(metadataToBeLoaded); 85 // Ensure that frames from the 3 simulcast layers are exposed. 86 assert_equals(senderSSRCs.length, 3); 87 assert_equals(receiverSSRCs.length, 3); 88 }, 'Basic simulcast setup with three spatial layers'); 89 </script>