test_peerConnection_nonDefaultRate.html (5751B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <script type="application/javascript" src="mediaStreamPlayback.js"></script> 5 </head> 6 <body> 7 <pre id="test"> 8 <script type="application/javascript"> 9 createHTML({ title: "PeerConnection feed to a graph with non default rate", bug: "1387454" }); 10 /** 11 * Run a test to verify that when we use the streem with nonDefault rate to/from a PC 12 * the connection fails. (PC is always on default rate). 13 */ 14 15 let pc1; 16 let pc2; 17 18 const offerOptions = { 19 offerToReceiveAudio: 1, 20 }; 21 22 function getName(pc) { 23 return (pc === pc1) ? 'pc1' : 'pc2'; 24 } 25 26 function getOtherPc(pc) { 27 return (pc === pc1) ? pc2 : pc1; 28 } 29 30 function onAddIceCandidateSuccess(pc) { 31 ok(true, getName(pc) + ' addIceCandidate success'); 32 } 33 34 function onAddIceCandidateError(pc, error) { 35 ok(false, getName(pc) + ' failed to add ICE Candidate: ' + error.toString()); 36 } 37 38 function onIceCandidate(pc, event, done) { 39 if (!event.candidate) { 40 ok(pc.iceGatheringState === 'complete', getName(pc) + " ICE gathering state has reached complete"); 41 done(); 42 return; 43 } 44 getOtherPc(pc).addIceCandidate(event.candidate) 45 .then(() => { 46 onAddIceCandidateSuccess(pc); 47 }, 48 (err) => { 49 onAddIceCandidateError(pc, err); 50 }); 51 info(getName(pc) + ' ICE candidate: ' + event.candidate.candidate); 52 } 53 54 function onIceStateChange(pc, event) { 55 if (pc) { 56 info(getName(pc) + ' ICE state: ' + pc.iceConnectionState); 57 info('ICE state change event: ', event); 58 } 59 } 60 61 function onCreateOfferSuccess(desc) { 62 info('Offer from pc1\n' + desc.sdp); 63 info('pc1 setLocalDescription start'); 64 65 pc1.setLocalDescription(desc) 66 .then(() => { 67 onSetLocalSuccess(pc1); 68 }, 69 onSetSessionDescriptionError); 70 71 info('pc2 setRemoteDescription start'); 72 pc2.setRemoteDescription(desc).then(() => { 73 onSetRemoteSuccess(pc2); 74 }, 75 onSetSessionDescriptionError); 76 77 info('pc2 createAnswer start'); 78 79 // Since the 'remote' side has no media stream we need 80 // to pass in the right constraints in order for it to 81 // accept the incoming offer of audio and video. 82 pc2.createAnswer() 83 .then(onCreateAnswerSuccess, onCreateSessionDescriptionError); 84 } 85 86 function onSetSessionDescriptionError(error) { 87 ok(false, 'Failed to set session description: ' + error.toString()); 88 } 89 90 function onSetLocalSuccess(pc) { 91 ok(true, getName(pc) + ' setLocalDescription complete'); 92 } 93 94 function onCreateSessionDescriptionError(error) { 95 ok(false, 'Failed to create session description: ' + error.toString()); 96 } 97 98 function onSetRemoteSuccess(pc) { 99 ok(true, getName(pc) + ' setRemoteDescription complete'); 100 } 101 102 function onCreateAnswerSuccess(desc) { 103 info('Answer from pc2:\n' + desc.sdp); 104 info('pc2 setLocalDescription start'); 105 pc2.setLocalDescription(desc).then(() => { 106 onSetLocalSuccess(pc2); 107 }, 108 onSetSessionDescriptionError); 109 info('pc1 setRemoteDescription start'); 110 pc1.setRemoteDescription(desc).then(() => { 111 onSetRemoteSuccess(pc1); 112 }, 113 onSetSessionDescriptionError); 114 } 115 116 async function getRemoteStream(localStream) { 117 info("got local stream") 118 const audioTracks = localStream.getAudioTracks(); 119 120 const servers = null; 121 122 pc1 = new RTCPeerConnection(servers); 123 info('Created local peer connection object pc1'); 124 const iceComplete1 = new Promise((resolve, reject) => { 125 pc1.onicecandidate = (e) => { 126 onIceCandidate(pc1, e, resolve); 127 }; 128 }); 129 130 pc2 = new RTCPeerConnection(servers); 131 info('Created remote peer connection object pc2'); 132 const iceComplete2 = new Promise((resolve, reject) => { 133 pc2.onicecandidate = (e) => { 134 onIceCandidate(pc2, e, resolve); 135 }; 136 }); 137 138 pc1.oniceconnectionstatechange = (e) => { 139 onIceStateChange(pc1, e); 140 }; 141 pc2.oniceconnectionstatechange = (e) => { 142 onIceStateChange(pc2, e); 143 }; 144 145 const remoteStreamPromise = new Promise((resolve, reject) => { 146 pc2.ontrack = (e) => { 147 info('pc2 received remote stream ' + e.streams[0]); 148 resolve(e.streams[0]); 149 }; 150 }); 151 152 localStream.getTracks().forEach((track) => { 153 pc1.addTrack(track, localStream); 154 }); 155 info('Added local stream to pc1'); 156 157 info('pc1 createOffer start'); 158 pc1.createOffer(offerOptions) 159 .then(onCreateOfferSuccess,onCreateSessionDescriptionError); 160 161 let promise_arr = await Promise.all([remoteStreamPromise, iceComplete1, iceComplete2]); 162 return promise_arr[0]; 163 } 164 165 runTest(async () => { 166 // Local stream operates at non default rate (32000) 167 const nonDefaultRate = 32000; 168 const nonDefault_ctx = new AudioContext({sampleRate: nonDefaultRate}); 169 oscillator = nonDefault_ctx.createOscillator(); 170 const dest = nonDefault_ctx.createMediaStreamDestination(); 171 oscillator.connect(dest); 172 oscillator.start(); 173 174 // Wait for remote stream 175 const remoteStream = await getRemoteStream(dest.stream) 176 ok(true, 'Got remote stream ' + remoteStream); 177 178 // remoteStream now comes from PC so operates at default 179 // rates. Verify that by adding to a default context 180 const ac = new AudioContext; 181 const source_default_rate = ac.createMediaStreamSource(remoteStream); 182 183 // Now try to add the remoteStream on a non default context 184 nonDefault_ctx.createMediaStreamSource(remoteStream); 185 ok(true, "Connect stream with graph of different sample rate is ok"); 186 187 // Close peer connections to make sure we don't get error: 188 // "logged result after SimpleTest.finish(): pc1 addIceCandidate success" 189 // See Bug 1626814. 190 pc1.close(); 191 pc2.close(); 192 }); 193 </script> 194 </pre> 195 </body> 196 </html>