webaudio tutorial the spec play examples abstracting html5 audio safari web-audio

html5 - the - web audio api tutorial



Safari 6.0.2 no llama aaudioprocess (1)

Anteriormente utilicé JavaScriptAudioNode en Web Audio API para sintetizar y mezclar audio tanto en Chrome como en Safari 6.0. Sin embargo, la última versión de Safari ya no parece funcionar porque no requiere un proceso de audio para llenar los búferes de origen.

Este es un ejemplo simplificado que solo reproduce el silencio y agrega texto al cuerpo del documento en cada llamada a onaudioprocess :

<html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function() { $("a").click(function() { var context = new webkitAudioContext(); var mixerNode=context.createJavaScriptNode(2048, 0, 2); mixerNode.onaudioprocess=function(ape) { var buffer=ape.outputBuffer; for(var s=0;s<buffer.length;s++) { buffer.getChannelData(0)[s]=0; buffer.getChannelData(1)[s]=0; } $("body").append("buffering<br/>"); }; $("body").html(""); mixerNode.connect(context.destination); return false; }); }); </script> </head> <body> <a href="#">start</a> </body> </html>

El ejemplo anterior funciona en Chrome como se esperaba, pero no en Safari de escritorio. La versión iOS de Safari tampoco funciona, pero nunca funcionó para mí en primer lugar.

Llamar a context.createJavaScriptNode devuelve un objeto adecuado de tipo JavaScriptAudioNode y al conectarlo al nodo de destino no lanza ninguna excepción. context.activeSourceCount permanece en cero, pero este también es el caso en Chrome, ya que aparentemente solo cuenta los nodos activos de tipo AudioBufferSourceNode . context.currentTime también se incrementa como se esperaba.

¿Estoy haciendo algo mal aquí o es esto un error real o una característica que falta en Safari? La documentación de Apple no menciona a JavaScriptAudioNode (ni el nuevo nombre, ScriptProcessorNode ), pero sí funcionó antes en la primera versión de Safari 6. El requisito de Safari de iOS para la entrada del usuario no parece ayudar, ya que el ejemplo anterior debería tener cuidado de eso.

El ejemplo simple se puede encontrar aquí y uno más complejo es mi reproductor de módulos Protracker que exhibe el mismo comportamiento.


Hay un par de errores en la implementación de Safari de Web Audio API que deberá tener en cuenta. El primero está en el constructor createJavaScriptNode ... parece tener problemas con el parámetro de "canales de entrada" que se establece en 0. Intente cambiarlo a esto:

createJavaScriptNode(2048, 1, 2)

El segundo problema tiene que ver con la recolección de basura (creo); una vez que su variable mixerNode está fuera del alcance, Safari parece dejar de onaudioprocess devolución de llamada de onaudioprocess . Una solución es introducir mixerNode en el ámbito de nivel superior (es decir, declarar var mixerNode; en la parte superior de la secuencia de comandos) y luego almacenar su JavaScriptNode en esa variable de nivel superior. Si planea crear dinámicamente varios mixerNodes, puede lograr el mismo efecto almacenando referencias a ellos en una variable de matriz de nivel superior.

Si realiza estos dos cambios (parámetro de canal de entrada establecido en 1, manteniendo una referencia al mixerNode), entonces su script debería funcionar en Safari como se esperaba.