javascript - 连续播放麦克风音频

标签 javascript dom audio html5-audio audio-streaming

我看到很多关于如何录制音频然后停止录制,然后播放音频或将其保存到文件的问题,但这都不是我想要的。

tl; dr 简而言之,这是我的问题:“我怎样才能立即播放从用户麦克风录制的音频?”也就是说,我不想保存录音并在用户点击“播放”按钮时播放它,我不想将录音保存到用户计算机上的文件中,我不想使用 WebRTC在任何地方流式传输音频。我只想对着我的麦克风说话,听我的声音从扬声器里传出来。

我要做的只是制作一个非常简单的“回声”页面,它会立即播放从麦克风录制的音频。我开始使用 mediaRecorder对象,但这不起作用,据我所知,这是用于录制完整的音频文件,所以我切换到 AudioContext基于的方法。
一个非常简单的页面看起来像这样:

<!DOCTYPE html>
<head>
    <script type="text/javascript" src="mcve.js"></script>
</head>
<body>
    <audio id="speaker" volume="1.0"></audio>
</body>

脚本如下所示:
if (navigator.mediaDevices) {
    var constrains = {audio: true};

    navigator.mediaDevices.getUserMedia(constrains).then(
        function (stream) {
            var context = new AudioContext();
            var source = context.createMediaStreamSource(stream);
            var proc = context.createScriptProcessor(2048, 2, 2);

            source.connect(proc);

            proc.onaudioprocess = function(e) {
                console.log("audio data collected");
                let audioData = new Blob(e.inputBuffer.getChannelData(0), {type: 'audio/ogg' } )
                    || new Blob(new Float32Array(2048), {type: 'audio/ogg'});

                var speaker = document.getElementById('speaker');

                let url = URL.createObjectURL(audioData);
                speaker.src = url;
                speaker.load();
                speaker.play().then(
                    () => { console.log("Playback success!"); }, 
                    (error) => { console.log("Playback failure... ", error); }
                );
            };
        }
    ).catch( (error) => {
        console.error("couldn't get user media.");
    });
}

它可以记录重要的音频数据(即不是每个集合都以 Blobnew Float32Array(2048) 调用结束),但它不能播放它。它永远不会遇到“无法获取用户媒体”的问题,但它总是会遇到“播放失败...”的问题。错误打印如下:
DOMException [NotSupportedError: "The media resource indicated by the src attribute or assigned media provider object was not suitable."
code: 9
nsresult: 0x806e0003]

此外,消息 Media resource blob:null/<long uuid> could not be decoded.反复打印到控制台。

据我所知,这里可能会发生两件事(也许两者兼而有之):
  • 我没有对音频进行编码。我不确定这是否是个问题,因为我认为从麦克风收集的数据自动带有“ogg”编码,我尝试离开 type我的 Blob 的属性(property)s 空白无济于事。如果这是问题所在,我不知道如何编码 audioprocess 给我的一段音频。事件,这就是我需要知道的。
  • 一个 <audio>即使正确编码,元素也基本上无法播放音频片段。也许由于没有完整的文件,有一些违反编码标准的丢失或无关的元数据,并阻止浏览器理解我。如果是这种情况,也许我需要一个不同的元素,甚至是一个完全脚本化的解决方案。或者我应该为每个音频数据 block 就地构造一个类似文件的对象?

  • 我已经在 MDN 和 SO 答案的示例上构建了这段代码,我应该提到我已经在 this example demo 测试了我的麦克风它似乎工作得很好。

    这里的最终目标是通过 websocket 将此音频流式传输到服务器并将其中继给其他用户。如果可能的话,我不想使用 WebRTC,因为我不想将自己限制在 Web 客户端上——一旦它工作正常,我也会制作一个桌面客户端。

    最佳答案

    检查示例 https://jsfiddle.net/greggman/g88v7p8c/来自 https://stackoverflow.com/a/38280110/351900
    需要从 HTTPS 运行

    navigator.getUserMedia = navigator.getUserMedia ||navigator.webkitGetUserMedia || navigator.mozGetUserMedia;
        
    var aCtx;
    var analyser;
    var microphone;
    if (navigator.getUserMedia) {
      navigator.getUserMedia(
        {audio: true}, 
        function(stream) {
          aCtx = new AudioContext();
          microphone = aCtx.createMediaStreamSource(stream);
          var destination=aCtx.destination;
          microphone.connect(destination);
        },
        function(){ console.log("Error 003.")}
      );
    }
    

    关于javascript - 连续播放麦克风音频,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46059863/

    相关文章:

    javascript - 在 window[]、html/javascript 中显示变量(或所有内容)的名称

    Android - 在连接蓝牙扬声器的内部电话扬声器上播放音频

    javascript - firebase:angularfire 0.8.0 升级在记录中保存 ref.name

    javascript - jQuery - 查找下一个选择元素

    javascript - 如何在 Polymer 中设置后备图像

    javascript - 在 jqgrid 中完成编辑

    dom - 是否可以使用像PHP中的DOMDocument这样的DOM操作工具来请求一个url并解析nodejs中的html内容?

    javascript - MutationObserver 回调何时被触发?

    audio - 最好的语言来操纵声音?

    android - MediaPlayer为WAV文件抛出IOException