[英]onaudioprocess not called on ios11
I am trying to get audio capture from the microphone working on Safari on iOS11 after support was recently added 最近添加了支持后,我正在尝试从在 iOS11 上的 Safari 上工作的麦克风获取音频捕获
However, the onaudioprocess
callback is never called.但是,永远不会调用
onaudioprocess
回调。 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>
On most platforms, you will see items being added to the messages list as the onaudioprocess
callback is called.在大多数平台上,当
onaudioprocess
回调被调用时,您会看到项目被添加到消息列表中。 However, on iOS, this callback is never called.但是,在 iOS 上,永远不会调用此回调。
Is there something else that I should do to try and get it called on iOS 11 with Safari?我还应该做些什么来尝试使用 Safari 在 iOS 11 上调用它?
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.主要的一点是 iOS 11 上的 Safari 似乎会自动挂起不是为了响应点击而创建的新
AudioContext
。 You can resume()
them, but only in response to a tap.您可以
resume()
它们,但只能响应点击。
(Update: Chrome mobile also does this, and Chrome desktop will have the same limitation starting in version 70 / December 2018.) (更新:Chrome 移动版也执行此操作,从 70 版 / 2018 年 12 月开始,Chrome 桌面版将具有相同的限制。)
So, you have to either create it before you get the MediaStream
, or else get the user to tap again later.因此,您必须在获得
MediaStream
之前创建它,或者让用户稍后再次点击。
The other issue with your code is that AudioContext
is prefixed as webkitAudioContext
in Safari.您的代码的另一个问题是
AudioContext
在 Safari 中以webkitAudioContext
为前缀。
Here's a working version:这是一个工作版本:
<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>
(You can set the onaudioprocess
callback sooner, but then you get empty buffers until the user approves of microphone access.) (您可以更快地设置
onaudioprocess
回调,但是在用户批准麦克风访问之前,您会获得空缓冲区。)
Oh, and one other iOS bug to watch out for: the Safari on iPod touch (as of iOS 12.1.1) reports that it does not have a microphone (it does).哦,还有一个需要注意的 iOS 错误:iPod touch 上的 Safari(从 iOS 12.1.1 开始)报告说它没有麦克风(它有)。 So, getUserMedia will incorrectly reject with an
Error: Invalid constraint
if you ask for audio there.因此,如果您在那里请求音频, getUserMedia 将错误地拒绝并显示
Error: Invalid constraint
。
FYI: I maintain the microphone-stream package on npm that does this for you and provides the audio in a Node.js-style ReadableStream.仅供参考:我在 npm 上维护了麦克风流包,它为您执行此操作并以 Node.js 样式的 ReadableStream 提供音频。 It includes this fix, if you or anyone else would prefer to use that over the raw code.
如果您或其他任何人更愿意在原始代码上使用它,它包括此修复程序。
Tried it on iOS 11.0.1, and unfortunately this problem still isn't fixed.在 iOS 11.0.1 上试过了,可惜这个问题还是没有解决。
As a workaround, I wonder if it makes sense to replace the ScriptProcessor with a function that takes the steam data from a buffet and then processes it every x milliseconds.作为一种解决方法,我想知道用一个函数替换 ScriptProcessor 是否有意义,该函数从自助餐中获取蒸汽数据,然后每 x 毫秒处理一次。 But that's a big change to the functionality.
但这对功能来说是一个很大的变化。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.