通过Javascript中的麦克风发送声音

时间:2019-09-01 21:39:49

标签: javascript selenium webrtc web-audio-api

我正在使用Selenium在具有音频聊天功能的网络上模拟用户。我需要模拟用户通过麦克风讲话。

我只有关于使用javascript收听麦克风的问题,而没有关于使用javascript通过麦克风发送声音的问题。

我当前的尝试如下:

首先,我检查AudioContext是否可用

JAVA_HOME

第二,我尝试执行此操作以从网址获取音频

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();
}

我缺少的部分是如何通过麦克风发送缓冲区数据(从ogg文件获得)。

编辑:

Chrome: fake microphone input for test purpose中的答案不能回答这个问题,我已经读过这个问题。

编辑2:

有些事情要考虑:

1)我正在寻找的解决方案可以包括使用另一种语言或工具。

2)我无法使用硬件模拟麦克风输入(例如:通过扬声器输出声音,以便麦克风可以拾音)

2 个答案:

答案 0 :(得分:0)

我认为您不需要使用JavascriptExecutor。

您的问题有一个解决方法。

解决方案:

改为使用Java。

第1步:

执行聊天语音监听器。

enter image description here enter image description here

第2步:

现在以编程方式播放随机声音。

使用: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(); 

        } 
    } 

第3步:

要启用麦克风访问,请使用以下参数:

options.addArguments("use-fake-ui-for-media-stream"); 

以上代码将为您播放声音,而您的聊天听众可以收听播放的音频。

答案 1 :(得分:0)

我对使用Java运行Selenium不太了解。但是看起来您可以在运行测试之前执行任意JavaScript代码。我想您的代码有时会调用getUserMedia()来获取麦克风输入。因此,如果仅用返回音频文件MediaStream的函数替换该函数,则可能会起作用。

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;
        });
};

也许您还必须禁用自动播放策略才能使其起作用。

不幸的是,Safari的代码需要更复杂一些,因为decodeAudioData()不会在Safari中返回诺言。我没有在此处添加替代方法以使代码尽可能简单。

相关问题