Javascript 连续播放麦克风音频

Javascript 连续播放麦克风音频,javascript,dom,audio,html5-audio,audio-streaming,Javascript,Dom,Audio,Html5 Audio,Audio Streaming,我看到很多关于如何录制音频、停止录制、播放音频或将其保存到文件的问题,但这些都不是我想要的 tl;dr,简而言之,我的问题是:“如何立即播放从用户麦克风录制的音频?”也就是说,我不想保存录制并在用户点击“播放”按钮时播放,我不想将录制保存到用户计算机上的文件中,我也不想使用WebRTC在任何地方播放音频。我只想对着麦克风说话,听到扬声器里传出我的声音 我所要做的就是制作一个非常简单的“回声”页面,立即播放从麦克风录制的音频。我开始使用mediaRecorder对象,但这不起作用,而且从我所知道的

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

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.");
    });
}
DOMException [NotSupportedError: "The media resource indicated by the src attribute or assigned media provider object was not suitable."
code: 9
nsresult: 0x806e0003]
它可以记录非平凡的音频数据(即并非每个采集都会以
新Float32Array(2048)
调用生成的
Blob
结束),但它无法播放。它从不点击“无法获取用户媒体”捕捉,但总是点击“播放失败…”捕捉。错误打印如下:

<!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.");
    });
}
DOMException [NotSupportedError: "The media resource indicated by the src attribute or assigned media provider object was not suitable."
code: 9
nsresult: 0x806e0003]
此外,消息
媒体资源blob:null/无法解码。
被反复打印到控制台

这里可能会发生两件事,就我所知(可能两者都有):

  • 我没有对音频进行编码。我不确定这是否是一个问题,因为我认为从麦克风收集的数据是自动使用“ogg”编码的,我尝试将我的
    Blob
    s的
    type
    属性保留为空,但没有任何效果。如果这是错误的,我不知道如何对
    audioprocess
    事件提供给我的音频块进行编码,这就是我需要知道的
  • 一个
    ,它似乎工作得很好

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

    查看

    需要从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.")}
      );
    }
    

    你的问题不是很清楚,怎么会这样?我能做些什么来让它更清楚呢?看看@K3N我不确定这会有什么帮助,因为我不想制作循环音频源,当我切换到服务器/中继系统时,引入手动延迟似乎不是个好主意。我相信@anoneemus希望在录制时播放音频-换句话说,听到正在录制的输入。有人能解决这个问题吗?