I'm using Selenium to emulate an user on a web that has audio chat. I need to emulate the user speaking through the microphone.
I only got questions about listening to the microphone in javascript, but none about sending sound through the microphone using javascript.
My current attempt looks like this:
First I check that AudioContext is available
private boolean isAudioContextSupported() {
JavascriptExecutor js = (JavascriptExecutor) getDriver();
Object response = js.executeAsyncScript(
"var callback = arguments[arguments.length - 1];" +
"var context;" +
"try {" +
" window.AudioContext = window.AudioContext||window.webkitAudioContext;" +
" context = new AudioContext();" +
" callback('');" +
"}" +
"catch(e) {" +
" callback('Web Audio API is not supported in this browser');" +
"}");
String responseAsString = response == null?"":(String)response;
return responseAsString.isEmpty();
}
Second I try to do this to get audio from an url
JavascriptExecutor js = (JavascriptExecutor) getDriver();
Object response = js.executeAsyncScript(
"var callback = arguments[arguments.length - 1];" +
"window.AudioContext = window.AudioContext || window.webkitAudioContext;" +
"var context = new AudioContext();" +
"var url = '<ogg file url>';" +
"var request = new XMLHttpRequest();" +
"request.open('GET', url, true);" +
"request.responseType = 'arraybuffer';" +
"request.onload = function() {" +
" context.decodeAudioData(request.response, function(buffer) {" +
" <send the buffer data through the microphone>" +
"}, callback(request.statusText));" +
"};" +
"request.send();" +
"callback('OK');"
);
The part I'm missing is how to send the buffer data (obtained from the ogg file) through the microphone.
EDIT:
The answer in Chrome: fake microphone input for test purpose does not answer this question, I already read that one.
EDIT 2:
There are some things to be considered:
1) The solution I'm looking can include using another language or tool.
2) I can't use hardware to emulate mic input (eg: output sound via speakers so the microphone can pick it up)
I think you don't need to use JavascriptExecutor.
There is a hack for your problem.
Solution:
Use java instead.
Step 1:
Execute the chat voice listener.
Step 2:
Now play a random voice programmatically.
Use: import javazoom.jl.player.Player;
public void playAudio(String audioPath) {
try {
FileInputStream fileInputStream = new FileInputStream(audioPath);
Player player = new Player((fileInputStream));
player.play();
System.out.println("Song is playing");
}catch (Exception ex) {
System.out.println("Error with playing sound.");
ex.printStackTrace();
}
}
Step 3:
To enable microphone access, kindly use the below argument:
options.addArguments("use-fake-ui-for-media-stream");
Above code will play the sound for you and your chat listener can listen the played audio.
I don't know much about running Selenium with Java. But it looks like you can execute arbitrary JavaScript code before running the tests. I guess your code does at some point call getUserMedia()
to get the microphone input. Therefore it might work if you just replace that function with a function that returns a MediaStream
of your audio file.
navigator.mediaDevices.getUserMedia = () => {
const audioContext = new AudioContext();
return fetch('/your/audio/file.ogg')
.then((response) => response.arrayBuffer())
.then((arrayBuffer) => audioContext.decodeAudioData(arrayBuffer))
.then((audioBuffer) => {
const audioBufferSourceNode = audioContext.createBufferSource();
const mediaStreamAudioDestinationNode = audioContext.createMediaStreamDestination();
audioBufferSourceNode.buffer = audioBuffer;
// Maybe it makes sense to loop the buffer.
audioBufferSourceNode.loop = true;
audioBufferSourceNode.start();
audioBufferSourceNode.connect(mediaStreamAudioDestinationNode);
return mediaStreamAudioDestinationNode.stream;
});
};
Maybe you also have to disable the autoplay policy in order to make it work.
Unfortunately the code for Safari needs to be a bit more complicated because decodeAudioData()
doesn't return a promise in Safari. I did not add the workaround here to keep the code as simple as possible.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.