在ios11

时间:2017-09-22 10:53:59

标签: ios safari web-audio ios11

我正试图通过iOS11 after support was recently added

上的Safari上的麦克风进行音频捕获

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

<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上,永远不会调用此回调。

我是否应该尝试使用Safari在iOS 11上调用它?

3 个答案:

答案 0 :(得分:20)

有两个问题。主要的一点是,iOS 11上的Safari似乎会自动暂停新的AudioContext,而这些新的resume()是为了响应点击而创建的。您可MediaStream他们,但仅限于点按。

(更新:Chrome移动版也会执行此操作,Chrome桌面将从2018年12月的版本70开始具有相同的限制。)

因此,您必须在获得AudioContext之前创建它,或者让用户稍后再次点按。

您的代码的另一个问题是webkitAudioContext在Safari中以<html> <body> <button onclick="beginAudioCapture()">Begin Audio Capture</button> <script> function beginAudioCapture() { 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); var recievedAudio = false; processor.onaudioprocess = function (e) { // This will be called multiple times per second. // The audio data will be in e.inputBuffer if (!recievedAudio) { recievedAudio = true; console.log('got audio', e); } }; }; navigator.mediaDevices.getUserMedia({audio: true, video: false}) .then(handleSuccess); } </script> </body> </html> 为前缀。

这是一个有效的版本:

onaudioprocess

(您可以更快地设置Error: Invalid constraint回调,但在用户批准麦克风访问之前,您将获得空缓冲区。)

哦,另外还有一个需要注意的iOS漏洞:iPod touch上的Safari(从iOS 12.1.1开始)报告它没有麦克风(确实如此)。因此,如果您在那里要求提供音频,getUserMedia将拒绝{ "rules": { "users": { "$uid": { ".read": "auth !== null", ".write": "auth.uid === $uid", "name": {" }, "userName": { } } }, "users-Used": { ".read": true, ".write": "auth !== null" } } }

仅供参考:我在npm上维护microphone-stream包,为你做这件事,并在Node.js风格的ReadableStream中提供音频。我刚刚使用此修复程序更新了它,如果您或其他任何人愿意使用原始代码。

答案 1 :(得分:4)

在iOS 11.0.1上尝试过,不幸的是这个问题仍然没有解决。

作为一种解决方法,我想知道用一个函数替换ScriptProcessor是否有意义,该函数从自助餐中获取蒸汽数据,然后每隔x毫秒处理一次。但这是对功能的重大改变。

答案 2 :(得分:2)

只是想知道......你在Safari设置中启用了设置吗?它默认在iOS11中启用,但您可能只是在没有注意的情况下禁用它。

enter image description here