iOS 7.1中使用WebAudio API的音频失真



在iOS 7.1上,当使用Web audio API播放音频时,我会听到嗡嗡声/嘈杂声/失真声。它听起来像这样扭曲,而不是像这样正常。

当使用HTML5音频时,相同的文件也可以。它在桌面上运行良好(Firefox、Chrome、Safari。)

编辑:

  • 在iOS模拟器版本iOS 7.1、8.1和8.2中,音频失真。嗡嗡声经常在我播放任何东西之前就开始了
  • 在运行iOS 7.1的物理iPhone上,Chrome和Safari中的音频都会失真
  • 在运行iOS 8.1的物理iPhone上,无论是Chrome还是Safari,音频都很好

即:嗡嗡作响的音频在iOS 7.1上。只有


Howler.js不是问题所在。使用纯JS的问题仍然存在,比如

var context;
var sound;
var extension = '.' + ( new Audio().canPlayType( 'audio/ogg' ) !== '' ? 'ogg' : 'mp3');

/** Test for WebAudio API support **/
try {
// still needed for Safari
window.AudioContext = window.AudioContext || window.webkitAudioContext;
// create an AudioContext
context = new AudioContext();
} catch(e) {
// API not supported
throw new Error( 'Web Audio API not supported.' );
}
function loadSound( url ) {
var request = new XMLHttpRequest();
request.open( 'GET', url, true );
request.responseType = 'arraybuffer';
request.onload = function() {
// request.response is encoded... so decode it now
context.decodeAudioData( request.response, function( buffer ) {
sound = buffer;
}, function( err ) {
throw new Error( err );
});
}
request.send();
}
function playSound(buffer) {
var source = context.createBufferSource();
source.buffer = buffer;
source.connect(context.destination);
source.start(0);
}
loadSound( '/tests/Assets/Audio/En-us-hello' + extension );

$(document).ready(function(){ 
$( '#clickme' ).click( function( event ) {
playSound(sound);
});

}); /* END .ready() */

此代码的实时版本在这里可用:Web Audio API-Hello world


谷歌没有在iOS 7.1上提出任何关于这种失真声音问题的结果。

有其他人碰到它吗?我应该向苹果公司提交错误报告吗?

我认为问题是由于重置audioContext.sampleRate道具引起的,这似乎是在浏览器/OS播放以不同采样率录制的内容之后发生的。

我设计了以下解决方法,基本上是无声地播放以设备当前播放的采样率记录的短波文件:

"use strict";
var getData = function( context, filePath, callback ) {
var source = context.createBufferSource(),
request = new XMLHttpRequest();
request.open( "GET", filePath, true );
request.responseType = "arraybuffer";
request.onload = function() {
var audioData = request.response;
context.decodeAudioData(
audioData,
function( buffer ) {
source.buffer = buffer;
callback( source );
},
function( e ) {
console.log( "Error with decoding audio data" + e.err );
}
);
};
request.send();
};
module.exports = function() {
var AudioContext = window.AudioContext || window.webkitAudioContext,
context = new AudioContext();
getData(
context,
"path/to/short/file.wav",
function( bufferSource ) {
var gain = context.createGain();
gain.gain.value = 0;
bufferSource.connect( gain );
gain.connect( context.destination );
bufferSource.start( 0 );
}
);
};

显然,如果某些设备具有不同的采样率,则需要针对每个采样率检测并使用特定的文件。

看起来iOS6+Safari默认采样率为48000。如果你在第一次打开移动safari时将其输入开发者控制台,你将获得48000:

var ctx = new window.webkitAudioContext();
console.log(ctx.sampleRate);

进一步参考:https://forums.developer.apple.com/thread/20677

然后,如果在加载时关闭初始上下文:ctx.close(),则下一个创建的上下文将使用大多数其他浏览器使用的采样率(44100),并且声音将在不失真的情况下播放。

感谢你为我指明了正确的方向(以防以上内容在未来不再有效):https://github.com/Jam3/ios-safe-audio-context/blob/master/index.js

截至发布日期的功能:

function createAudioContext (desiredSampleRate) {
var AudioCtor = window.AudioContext || window.webkitAudioContext
desiredSampleRate = typeof desiredSampleRate === 'number'
? desiredSampleRate
: 44100
var context = new AudioCtor()
// Check if hack is necessary. Only occurs in iOS6+ devices
// and only when you first boot the iPhone, or play a audio/video
// with a different sample rate
if (/(iPhone|iPad)/i.test(navigator.userAgent) &&
context.sampleRate !== desiredSampleRate) {
var buffer = context.createBuffer(1, 1, desiredSampleRate)
var dummy = context.createBufferSource()
dummy.buffer = buffer
dummy.connect(context.destination)
dummy.start(0)
dummy.disconnect()
context.close() // dispose old context
context = new AudioCtor()
}
return context
}

最新更新