2011-11-04 11 views
7

Por razones de seguridad mayormente, no tengo permitido almacenar un archivo WAV en el servidor al que se accede mediante un navegador. Lo que tengo es una matriz de bytes que contiene datos de audio (creo que la parte de datos de un archivo WAV) en el servidor, y quiero que se reproduzcan en un navegador a través de JavaScript (o Applet, pero se prefiere JS), puedo usar JSON- PRC para enviar todo el byte [], o puedo abrir un socket para transmitirlo, pero en cualquier caso, ¿no sé a quién tocar el byte [] dentro del navegador?Cómo jugar matriz de bytes de audio (¡no archivo!) Con JavaScript en un navegador

Respuesta

0

sospecho que puede lograr esto con API HTML5 de audio con bastante facilidad:

https://developer.mozilla.org/en/Introducing_the_Audio_API_Extension

Esta biblioteca puede ser útil también, aunque no estoy seguro de si refleja los últimos comportamientos del navegador:

https://github.com/jussi-kalliokoski/audiolib.js

+0

Gracias! Pero esto parece usar una muestra flotante, mi audio wav de datos brutos es mono 16K Hz y base64 bytes, ¿necesito convertirlo? ¿Cómo? –

+0

El primer enlace dice que esta función ahora está en desuso, y el reemplazo https://developer.mozilla.org/en-US/docs/Web_Audio_API#Browser_compatibility no es compatible con Internet Explorer. ¿Hay alguna solución que funcione para todos los navegadores? –

+3

@Pi Por supuesto que no. Es un estándar ahora. ¿Por qué IE implementaría un estándar? No seas tonto! – Rushyo

5

El siguiente código reproducirá la onda sinusoidal en 0.5 y 2.0. Llame a la función play_buffersource() en su botón o en cualquier lugar que desee.

Probado usando Chrome con el indicador de Web Audio habilitado. Para su caso, todo lo que necesita hacer es simplemente mezclar sus bytes de audio al buf.

<script type="text/javascript"> 
const kSampleRate = 44100; // Other sample rates might not work depending on the your browser's AudioContext 
const kNumSamples = 16834; 
const kAmplitute = 440; 
const kPI_2  = Math.PI * 2; 

function play_buffersource() { 
    if (!window.AudioContext) { 
     if (!window.webkitAudioContext) { 
      alert("Your browser sucks because it does NOT support any AudioContext!"); 
      return; 
     } 
     window.AudioContext = window.webkitAudioContext; 
    } 

    var ctx = new AudioContext(); 

    var buffer = ctx.createBuffer(1, kNumSamples, kSampleRate); 
    var buf = buffer.getChannelData(0); 
    for (i = 0; i < kNumSamples; ++i) { 
     buf[i] = Math.sin(kAmplitute * kPI_2 * i/kSampleRate); 
    } 

    var node = ctx.createBufferSource(0); 
    node.buffer = buffer; 
    node.connect(ctx.destination); 
    node.noteOn(ctx.currentTime + 0.5); 

    node = ctx.createBufferSource(0); 
    node.buffer = buffer; 
    node.connect(ctx.destination); 
    node.noteOn(ctx.currentTime + 2.0); 
} 
</script> 

Referencias:

Si necesita volver a muestrear el audio, se puede utilizar una resampleador JavaScript: https://github.com/grantgalitz/XAudioJS

Si necesita decodificar los datos de base64, hay muchos del decodificador JavaScript base64: https://github.com/carlo/jquery-base64

+1

¡esto no funciona en Firefox! ¿No hay una manera de hacerlo funcionar? – mkazma

1

Si tiene los bytes en el servidor, le sugiero que cree algún tipo de controlador en el servidor que transmita los bytes a la respuesta como un archivo wav. Este "archivo" solo estaría en la memoria en el servidor y no en el disco. Entonces el navegador puede manejarlo como un archivo wav normal. Se necesitarán más detalles sobre la pila del servidor para proporcionar más información sobre cómo se podría hacer esto en su entorno.

0

Lo logré mediante el siguiente código. Paso en una matriz de bytes que contiene los datos del archivo wav a la función playByteArray. Mi solución es similar a la de Peter Lee, pero no pude hacer que la suya funcionara en mi caso (la salida fue distorsionada) mientras que esta solución funciona bien para mí. Verifiqué que funciona en Firefox y Chrome.

window.onload = init; 
var context; // Audio context 
var buf;  // Audio buffer 

function init() { 
    if (!window.AudioContext) { 
    if (!window.webkitAudioContext) { 
     alert("Your browser does not support any AudioContext and cannot play back this audio."); 
     return; 
    } 
     window.AudioContext = window.webkitAudioContext; 
    } 

    context = new AudioContext(); 
} 

function playByteArray(byteArray) { 

    var arrayBuffer = new ArrayBuffer(byteArray.length); 
    var bufferView = new Uint8Array(arrayBuffer); 
    for (i = 0; i < byteArray.length; i++) { 
     bufferView[i] = byteArray[i]; 
    } 

    context.decodeAudioData(arrayBuffer, function(buffer) { 
     buf = buffer; 
     play(); 
    }); 
} 

// Play the loaded file 
function play() { 
    // Create a source node from the buffer 
    var source = context.createBufferSource(); 
    source.buffer = buf; 
    // Connect to the final output node (the speakers) 
    source.connect(context.destination); 
    // Play immediately 
    source.start(0); 
} 
+0

¿Qué está destinado a hacer bufferView? – patrickdamery

+0

@patrickdamery es una composición sobre el búfer que se usa para mutar su contenido (es por eso que no ve más uso después de que finaliza la iteración) –

Cuestiones relacionadas