subir manejo leer example etiquetas contenido archivos archivo html5 client-side web-audio

html5 - manejo - Usando el archivo local para Web Audio API en Javascript



manejo de archivos en javascript (4)

Intento trabajar con sonido en mi iPhone usando la API de Web Audio. El problema es que esta aplicación es completamente del lado del cliente. Quiero almacenar mis archivos MP3 en una carpeta local (y sin que el usuario los active), así que no puedo usar XMLHttpRequest para leer los datos. Estuve investigando el uso de FileSystem pero Safari no lo admite.

¿Hay alguna alternativa?

Editar: Gracias por las respuestas a continuación. Lamentablemente, la API de audio es terriblemente lenta para los juegos. Lo tuve funcionando y la latencia solo hace que la experiencia del usuario sea inaceptable. Para aclarar, lo que necesito es algo así como ...

var request = new XMLHttpRequest(); request.open(''GET'', ''file:///./../sounds/beep-1.mp3'', true); request.responseType = ''arraybuffer''; request.onload = function() { context.decodeAudioData(request.response, function(buffer) { dogBarkingBuffer = buffer; }, onError); } request.send();

Pero esto me da los errores -

XMLHttpRequest no puede cargar el archivo: ///sounds/beep-1.mp3. Las solicitudes de origen cruzadas solo son compatibles con HTTP. Error no detectado: NETWORK_ERR: XMLHttpRequest Exception 101

Entiendo los riesgos de seguridad con la lectura de archivos locales, pero seguramente dentro de tu propio dominio debería estar bien?


Use la etiqueta de audio HTML5 para reproducir archivos de audio en el navegador.

La solicitud de Ajax funciona con el protocolo http, por lo que cuando intente obtener un archivo de audio con el archivo: //, el navegador marcará esta solicitud como solicitud de dominio cruzado. Establezca el siguiente código en el encabezado de solicitud -

header(''Access-Control-Allow-Origin: *'');


Ok, me tomó dos días crear prototipos de diferentes soluciones y finalmente descubrí cómo puedo hacerlo sin almacenar mis recursos en un servidor. Hay algunos blogs que detallan esto, pero no pude encontrar la solución completa en un solo lugar, así que la añado aquí. Esto puede ser considerado un poco hacky por los programadores veteranos, pero es la única forma en que puedo ver que esto funciona, así que si alguien tiene una solución más elegante, me encantaría escucharla.

La solución fue almacenar mis archivos de sonido como una cadena codificada en Base64. Los archivos de sonido son relativamente pequeños (menos de 30kb), así que espero que el rendimiento no sea un problema. Tenga en cuenta que puse ''xxx'' delante de algunos de los hipervínculos, ya que mi estado n00b significa que no puedo publicar más de dos enlaces.

Paso 1: crea la fuente de sonido Base 64

Primero necesito convertir mi mp3 a una cadena codificada en Base64 y almacenarla como JSON. Encontré un sitio web que hace esta conversión para mí aquí - xxxhttp: //www.mobilefish.com/services/base64/base64.php Puede que necesite eliminar los caracteres de retorno utilizando un editor de texto, pero para cualquiera que necesite un ejemplo, encontré algunos tonos de piano aquí - xxxhttps: //raw.github.com/mudcube/MIDI.js/master/soundfont/acoustic_grand_piano-mp3.js Tenga en cuenta que para trabajar con mi ejemplo, debe eliminar los datos de la parte del encabezado : audio / mpeg; base64,

Paso 2: decodifica la fuente de sonido en ArrayBuffer

Puede implementar esto usted mismo, pero encontré una API que hace esto perfectamente (¿por qué reinventar la rueda, ¿no?) - https://github.com/danguer/blog-examples/blob/master/js/base64-binary. js Recurso tomado de - aquí

Paso 3: Agregar el resto del código

Bastante sencillo

var cNote = acoustic_grand_piano.C2; var byteArray = Base64Binary.decodeArrayBuffer(cNote); var context = new webkitAudioContext(); context.decodeAudioData(byteArray, function(buffer) { var source = context.createBufferSource(); // creates a sound source source.buffer = buffer; source.connect(context.destination); // connect the source to the context''s destination (the speakers) source.noteOn(0); }, function(err) { console.log("err(decodeAudioData): "+err); });

¡Y eso es! Tengo esto funcionando a través de mi versión de escritorio de Chrome y también corriendo en Safari móvil (iOS 6 solo, por supuesto, ya que Web Audio no es compatible con versiones anteriores). La carga del Safari móvil (en menos de 1 segundo en Chrome para computadora de escritorio) demora unos segundos, pero esto puede deberse a que le lleva mucho tiempo descargar las fuentes de sonido. También podría ser el hecho de que iOS impide que se reproduzca sonido hasta que se produzca un evento de interacción del usuario. Necesito hacer más trabajo para ver cómo funciona.

Espero que esto le salve a alguien más el dolor que sufrí.


Debido a que las aplicaciones ios son sandbox, la vista web (básicamente safari envuelto en phonegap) le permite almacenar su archivo mp3 localmente. Es decir, no hay un problema de seguridad "de dominio cruzado".

Esto es a partir de ios6 ya que las versiones anteriores de ios no eran compatibles con la API de audio web


Tuve el mismo problema y encontré esta solución muy simple.

audio_file.onchange = function(){ var files = this.files; var file = URL.createObjectURL(files[0]); audio_player.src = file; audio_player.play(); };

<input id="audio_file" type="file" accept="audio/*" /> <audio id="audio_player" />

Puede probar aquí: http://jsfiddle.net/Tv8Cm/