ios11 上未调用 onaudioprocess
onaudioprocess not called on 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,此回调从未被调用。
我还应该做些什么来尝试在 iOS 11 上使用 Safari 调用它吗?
只是想知道...您是否在 Safari 设置中启用了该设置?它在 iOS11 中默认启用,但也许您只是在没有注意到的情况下禁用了它。
在iOS 11.0.1 上试过了,不幸的是这个问题仍然没有解决。
作为解决方法,我想知道用从自助餐中获取蒸汽数据然后每 x 毫秒处理一次的函数替换 ScriptProcessor 是否有意义。但这对功能来说是一个很大的变化。
有两个问题。最主要的是 iOS 11 上的 Safari 似乎会自动暂停不是响应点击而创建的新 AudioContext
。您可以 resume()
它们,但只能响应点击。
(更新:Chrome 移动设备也这样做,Chrome 桌面设备将从 70 版/2018 年 12 月开始具有相同的限制。)
因此,您必须在获得 MediaStream
之前创建它,或者让用户稍后再次点击。
您的代码的另一个问题是 AudioContext
在 Safari 中的前缀为 webkitAudioContext
。
这是一个工作版本:
<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
回调,但是在用户批准麦克风访问之前您会得到空缓冲区。)
哦,还有一个需要注意的 iOS 错误:iPod touch 上的 Safari(从 iOS 12.1.1 开始)报告说它没有麦克风(它有) .因此,如果您在那里请求音频,getUserMedia 将错误地拒绝 Error: Invalid constraint
。
仅供参考:我在 npm 上维护 microphone-stream 包,它会为您执行此操作并以 Node.js 样式的 ReadableStream 提供音频。如果您或其他任何人更愿意在原始代码上使用它,它包括此修复程序。
我正在尝试从 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,此回调从未被调用。
我还应该做些什么来尝试在 iOS 11 上使用 Safari 调用它吗?
只是想知道...您是否在 Safari 设置中启用了该设置?它在 iOS11 中默认启用,但也许您只是在没有注意到的情况下禁用了它。
在iOS 11.0.1 上试过了,不幸的是这个问题仍然没有解决。
作为解决方法,我想知道用从自助餐中获取蒸汽数据然后每 x 毫秒处理一次的函数替换 ScriptProcessor 是否有意义。但这对功能来说是一个很大的变化。
有两个问题。最主要的是 iOS 11 上的 Safari 似乎会自动暂停不是响应点击而创建的新 AudioContext
。您可以 resume()
它们,但只能响应点击。
(更新:Chrome 移动设备也这样做,Chrome 桌面设备将从 70 版/2018 年 12 月开始具有相同的限制。)
因此,您必须在获得 MediaStream
之前创建它,或者让用户稍后再次点击。
您的代码的另一个问题是 AudioContext
在 Safari 中的前缀为 webkitAudioContext
。
这是一个工作版本:
<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
回调,但是在用户批准麦克风访问之前您会得到空缓冲区。)
哦,还有一个需要注意的 iOS 错误:iPod touch 上的 Safari(从 iOS 12.1.1 开始)报告说它没有麦克风(它有) .因此,如果您在那里请求音频,getUserMedia 将错误地拒绝 Error: Invalid constraint
。
仅供参考:我在 npm 上维护 microphone-stream 包,它会为您执行此操作并以 Node.js 样式的 ReadableStream 提供音频。如果您或其他任何人更愿意在原始代码上使用它,它包括此修复程序。