Audio distorsionado en iOS 7.1 con WebAudio API

En iOS 7.1, sigo recibiendo un sonido zumbido / ruidoso / distorsionado al reproducir audio usando la Web Audio API. Suena distorsionado así , en lugar de lo normal .

Los mismos files están bien cuando se usa audio HTML5. Todo funciona bien en el escritorio (Firefox, Chrome, Safari).

EDITAR:

  • El audio está distorsionado en las versiones de iOS Simulator iOS 7.1, 8.1, 8.2. El zumbido a menudo comienza antes de que reproduzco algo.
  • El audio está distorsionado en un iPhone físico con iOS 7.1, tanto en Chrome como en Safari.
  • El audio está bien en un iPhone físico con iOS 8.1, tanto en Chrome como en Safari.

es decir: el zumbido del audio está en iOS 7.1. solamente.

Howler.js no es el problema. El problema todavía está ahí usando JS puro como:

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() */ 

Una versión en vivo de este código está disponible aquí: Web Audio API – Hello world

Google no mostró ningún resultado sobre un problema de sonido tan distorsionado en iOS 7.1.

¿Alguien más se topa con eso? ¿Debo presentar un informe de error a Apple?

Creo que el problema se debe a restablecer el atributo audioContext.sampleRate, que parece suceder después de que el browser / sistema operativo reproduce algo grabado con una frecuencia de muestreo diferente.

He ideado la siguiente solución, que básicamente reproduce silenciosamente un file WAV corto grabado en la frecuencia de muestreo en la que el dispositivo actualmente reproduce:

 "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 ); } ); }; 

Obviamente, si algunos de los dispositivos tienen diferentes tasas de muestreo, necesitaría detectar y usar un file específico para cada tasa.

parece que iOS6 + Safari tiene una tasa de muestreo pnetworkingeterminada de 48000. Si escribes esto en la console del desarrollador cuando abras Safari por primera vez, obtendrás 48000:

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

Más reference: https://forums.developer.apple.com/thread/20677

Luego, si cierra el context inicial en load: ctx.close() , el próximo context creado usará la frecuencia de muestreo que usan la mayoría de los otros browseres (44100) y el sonido se reproducirá sin distorsión.

Crédito a esto por apuntarme en la dirección correcta (y en caso de que lo anterior ya no funcione en el futuro): https://github.com/Jam3/ios-safe-audio-context/blob/master/index.js

function a partir de la date de publicación:

 function createAudioContext (desinetworkingSampleRate) { var AudioCtor = window.AudioContext || window.webkitAudioContext desinetworkingSampleRate = typeof desinetworkingSampleRate === 'number' ? desinetworkingSampleRate : 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 !== desinetworkingSampleRate) { var buffer = context.createBuffer(1, 1, desinetworkingSampleRate) 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 }