test_setSinkId_preMutedElement.html (3280B)
1 <!DOCTYPE HTML> 2 <html> 3 <head> 4 <script src="mediaStreamPlayback.js"></script> 5 </head> 6 <body> 7 <pre id="test"> 8 <script type="application/javascript"> 9 createHTML({ 10 title: "Test changing sink and muting before the MediaStream is set", 11 bug: "1651049", 12 visible: true 13 }); 14 15 let getOutputDeviceId = async () => { 16 let devices = await navigator.mediaDevices.enumerateDevices(); 17 let audios = devices.filter(d => d.kind == "audiooutput"); 18 ok(audios.length, "One or more output devices found."); 19 return audios[0].deviceId; 20 } 21 22 let verifyAudioTone = async (ac, stream, freq) => { 23 const toneAnalyser = new AudioStreamAnalyser(ac, stream); 24 return toneAnalyser.waitForAnalysisSuccess(array => { 25 const lowerFreq = freq / 2; 26 const upperFreq = freq + 1000; 27 const lowerMag = array[toneAnalyser.binIndexForFrequency(lowerFreq)]; 28 const freqMag = array[toneAnalyser.binIndexForFrequency(freq)]; 29 const upperMag = array[toneAnalyser.binIndexForFrequency(upperFreq)]; 30 info("Audio tone expected. " 31 + lowerFreq + ": " + lowerMag + ", " 32 + freq + ": " + freqMag + ", " 33 + upperFreq + ": " + upperMag); 34 return lowerMag < 50 && freqMag > 200 && upperMag < 50; 35 }); 36 } 37 38 let verifyNoAudioTone = async (ac, stream, freq) => { 39 const toneAnalyser = new AudioStreamAnalyser(ac, stream); 40 // repeat check 100 times to make sure that it is muted. 41 let retryCnt = 0; 42 return toneAnalyser.waitForAnalysisSuccess(array => { 43 const lowerFreq = freq / 2; 44 const upperFreq = freq + 1000; 45 const lowerMag = array[toneAnalyser.binIndexForFrequency(lowerFreq)]; 46 const freqMag = array[toneAnalyser.binIndexForFrequency(freq)]; 47 const upperMag = array[toneAnalyser.binIndexForFrequency(upperFreq)]; 48 info("No audio tone expected. " 49 + lowerFreq + ": " + lowerMag + ", " 50 + freq + ": " + freqMag + ", " 51 + upperFreq + ": " + upperMag); 52 return lowerMag == 0 && freqMag == 0 && upperMag == 0 && ++retryCnt == 100; 53 }); 54 } 55 56 runTest(async () => { 57 let audioDevice = SpecialPowers.getCharPref("media.audio_loopback_dev", ""); 58 if (!audioDevice) { 59 todo(false, "No loopback device set by framework. Try --use-test-media-devices"); 60 return; 61 } 62 63 await pushPrefs(["media.setsinkid.enabled", true]); 64 65 // Implicitly expose the loopback device sink by opening the source in the 66 // same group. 67 const verifyStream = await getUserMedia({audio: true}); 68 69 let sinkId = await getOutputDeviceId(); 70 isnot(sinkId, "", "SinkId is not null"); 71 72 let audioElement = createMediaElement('audio', 'audioElement'); 73 audioElement.muted = true; 74 await audioElement.setSinkId(sinkId); 75 isnot(audioElement.sinkId, "", "sinkId property of the element is not null"); 76 77 // The test stream is a sine tone of 1000 Hz 78 let ac = new AudioContext(); 79 const frequency = 2000; 80 let stream = createOscillatorStream(ac, frequency); 81 await verifyAudioTone(ac, stream, frequency); 82 83 audioElement.srcObject = stream; 84 audioElement.play(); 85 86 // Verify the silent output using the loopback device. 87 await verifyNoAudioTone(ac, verifyStream, frequency); 88 info("output is muted"); 89 90 // Clean up 91 audioElement.pause(); 92 audioElement.srcObject = null; 93 verifyStream.getTracks()[0].stop(); 94 }); 95 </script> 96 </pre> 97 </body> 98 </html>