在ios11上没有调用onaudioprocess [英] onaudioprocess not called on ios11

查看:309
本文介绍了在ios11上没有调用onaudioprocess的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正试图通过iOS11上的Safari上的麦克风进行音频捕获最近添加了支持后

I am trying to get audio capture from the microphone working on Safari on iOS11 after support was recently added

然而,永远不会调用 onaudioprocess 回调。这是一个示例页面:

However, the onaudioprocess callback is never called. Here's an example page:

<html>
    <body>
        <button onclick="doIt()">DoIt</button>
        <ul id="logMessages">
        </ul>
        <script>
            function debug(msg) {
                if (typeof msg !== 'undefined') {
                    var logList = document.getElementById('logMessages');
                    var newLogItem = document.createElement('li');
                    if (typeof  msg === 'function') {
                        msg = Function.prototype.toString(msg);
                    } else if (typeof  msg !== 'string') {
                        msg = JSON.stringify(msg);
                    }
                    var newLogText = document.createTextNode(msg);
                    newLogItem.appendChild(newLogText);
                    logList.appendChild(newLogItem);
                }
            }
            function doIt() {
                var handleSuccess = function (stream) {
                    var context = new AudioContext();
                    var input = context.createMediaStreamSource(stream)
                    var processor = context.createScriptProcessor(1024, 1, 1);

                    input.connect(processor);
                    processor.connect(context.destination);

                    processor.onaudioprocess = function (e) {
                        // Do something with the data, i.e Convert this to WAV
                        debug(e.inputBuffer);
                    };
                };

                navigator.mediaDevices.getUserMedia({audio: true, video: false})
                        .then(handleSuccess);
            }
        </script>
    </body>
</html>

在大多数平台上,您会看到作为 onaudioprocess 调用回调。但是,在iOS上,永远不会调用此回调。

On most platforms, you will see items being added to the messages list as the onaudioprocess callback is called. However, on iOS, this callback is never called.

我还应该尝试使用Safari在iOS 11上调用它吗?

Is there something else that I should do to try and get it called on iOS 11 with Safari?

推荐答案

有两个问题。主要的一点是,iOS 11上的Safari似乎会自动挂起新的 AudioContext ,这些都是为了响应点击而创建的。你可以 resume(),但只是为了回应点击。

There are two problems. The main one is that Safari on iOS 11 seems to automatically suspend new AudioContext's that aren't created in response to a tap. You can resume() them, but only in response to a tap.

所以,你必须要么创建它在您获得 MediaStream 之前,或者让用户稍后再次点击。

So, you have to either create it before you get the MediaStream, or else get the user to tap again later.

您的另一个问题代码是 AudioContext 在Safari中以 webkitAudioContext 为前缀。

The other issue with your code is that AudioContext is prefixed as webkitAudioContext in Safari.

这是一个工作版本:

<html>
<body>
<button onclick="doIt()">DoIt</button>
<ul id="logMessages">
</ul>
<script>
  function debug(msg) {
    if (typeof msg !== 'undefined') {
      var logList = document.getElementById('logMessages');
      var newLogItem = document.createElement('li');
      if (typeof  msg === 'function') {
        msg = Function.prototype.toString(msg);
      } else if (typeof  msg !== 'string') {
        msg = JSON.stringify(msg);
      }
      var newLogText = document.createTextNode(msg);
      newLogItem.appendChild(newLogText);
      logList.appendChild(newLogItem);
    }
  }
  function doIt() {

    var AudioContext = window.AudioContext || window.webkitAudioContext;    
    var context = new AudioContext();
    var processor = context.createScriptProcessor(1024, 1, 1);
    processor.connect(context.destination);

    var handleSuccess = function (stream) {
      var input = context.createMediaStreamSource(stream);
      input.connect(processor);

      processor.onaudioprocess = function (e) {
        // Do something with the data, i.e Convert this to WAV
        debug(e.inputBuffer);
      };
    };

    navigator.mediaDevices.getUserMedia({audio: true, video: false})
      .then(handleSuccess);
  }
</script>
</body>
</html>

(您可以更快地设置 onaudioprocess 回调,但是你得到空的缓冲区,直到用户批准麦克风访问。)

(You can set the onaudioprocess callback sooner, but then you get empty buffers until the user approves of microphone access.)

哦,还有另外一个需要注意的iOS bug:iPod touch上的Safari(iOS) 11)认为它没有麦克风(确实如此)。因此,getUserMedia将拒绝错误:无效约束如果你在那里要求音频。

Oh, and one other iOS bug to watch out for: the Safari on iPod touch (iOS 11) believes that it does not have a microphone (it does). So, getUserMedia will reject with an Error: Invalid constraint if you ask for audio there.

FYI:我维持npm上的麦克风流包为您执行此操作并在节点中提供音频.js-style ReadableStream。我刚刚使用此修复程序更新了它,如果您或其他任何人愿意使用原始代码。

FYI: I maintain the microphone-stream package on npm that does this for you and provides the audio in a Node.js-style ReadableStream. I just updated it with this fix, if you or anyone else would prefer to use that over the raw code.

这篇关于在ios11上没有调用onaudioprocess的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆