play - Efectos de sonido en JavaScript/HTML5
play() javascript (16)
Objetos de Audio
HTML5
No necesitas molestarte con <audio>
elementos <audio>
. HTML 5 le permite acceder a objetos de Audio
directamente:
var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();
No hay soporte para mezclar en la versión actual de la especificación.
Para reproducir el mismo sonido varias veces, cree varias instancias del objeto de Audio
. También puede establecer snd.currentTime=0
en el objeto después de que termine de reproducirse.
Como el constructor JS no admite elementos de <source>
reserva, debe usar
(new Audio()).canPlayType("audio/ogg; codecs=vorbis")
para probar si el navegador soporta Ogg Vorbis.
Si está escribiendo un juego o una aplicación de música (más que solo un reproductor), querrá utilizar una API de audio web más avanzada , que ahora es compatible con la mayoría de los navegadores .
Estoy usando HTML5 para programar juegos; el obstáculo que me he encontrado ahora es cómo reproducir efectos de sonido.
Los requisitos específicos son pocos en número:
- Juega y mezcla múltiples sonidos,
- Reproduce la misma muestra varias veces, posiblemente reproducciones superpuestas,
- Interrumpe la reproducción de una muestra en cualquier punto,
- Preferiblemente, reproducir archivos WAV que contengan PCM en bruto (de baja calidad), pero puedo convertirlos, por supuesto.
Mi primer enfoque fue usar el elemento HTML5 <audio>
y definir todos los efectos de sonido en mi página. Firefox reproduce los archivos WAV solo peachy, pero llamar a #play
varias veces realmente no reproduce la muestra varias veces. Desde mi entendimiento de la especificación HTML5, el elemento <audio>
también rastrea el estado de reproducción, por lo que explica por qué.
Mi pensamiento inmediato fue clonar los elementos de audio, así que creé la siguiente pequeña biblioteca de JavaScript para hacer eso por mí (depende de jQuery):
var Snd = {
init: function() {
$("audio").each(function() {
var src = this.getAttribute(''src'');
if (src.substring(0, 4) !== "snd/") { return; }
// Cut out the basename (strip directory and extension)
var name = src.substring(4, src.length - 4);
// Create the helper function, which clones the audio object and plays it
var Constructor = function() {};
Constructor.prototype = this;
Snd[name] = function() {
var clone = new Constructor();
clone.play();
// Return the cloned element, so the caller can interrupt the sound effect
return clone;
};
});
}
};
Así que ahora puedo hacer Snd.boom();
desde la consola Firebug y juegue snd/boom.wav
, pero todavía no puedo reproducir la misma muestra varias veces. Parece que el elemento <audio>
es en realidad más una función de transmisión en lugar de algo para reproducir efectos de sonido.
¿Hay alguna forma inteligente de hacer que esto suceda y me estoy perdiendo, preferiblemente usando solo HTML5 y JavaScript?
También debo mencionar que mi entorno de prueba es Firefox 3.5 en Ubuntu 9.10. Los otros navegadores que probé (Opera, Midori, Chromium, Epiphany) produjeron diferentes resultados. Algunos no juegan nada, y algunos lanzan excepciones.
WebAudio API por W3C
A partir de julio de 2012, la API de WebAudio ahora es compatible con Chrome, y al menos parcialmente con Firefox, y está programada para ser agregada al IOS a partir de la versión 6.
Aunque es lo suficientemente robusto como para ser utilizado programáticamente para tareas básicas, el elemento de audio nunca fue diseñado para proporcionar soporte de audio completo para juegos, etc. Fue diseñado para permitir que una sola pieza de medios se incruste en una página, similar a un img etiqueta. Hay muchos problemas al tratar de usar la etiqueta de audio para juegos:
- Los intervalos de tiempo son comunes con los elementos de audio.
- Necesitas un elemento de Audio para cada instancia de un sonido.
- Los eventos de carga no son totalmente confiables, aún
- Sin controles de volumen comunes, sin atenuación, sin filtros / efectos
Utilicé este artículo de Getting Started With WebAudio para comenzar con la API de WebAudio. El estudio de caso de FieldRunners WebAudio también es una buena lectura.
howler.js
Para la creación de juegos, una de las mejores soluciones es utilizar una biblioteca que resuelva los muchos problemas que enfrentamos al escribir código para la web, como howler.js . howler.js abstrae la gran Web Audio API (pero de bajo nivel) en un marco fácil de usar. Intentará recurrir al elemento de audio HTML5 si la API de audio web no está disponible.
var sound = new Howl({
urls: [''sound.mp3'', ''sound.ogg'']
}).play();
// it also provides calls for spatial/3d audio effects (most browsers)
sound.pos3d(0.1,0.3,0.5);
wad.js
Otra gran biblioteca es wad.js , que es especialmente útil para producir audio sintetizado, como música y efectos. Por ejemplo:
var saw = new Wad({source : ''sawtooth''})
saw.play({
volume : 0.8,
wait : 0, // Time in seconds between calling play() and actually triggering the note.
loop : false, // This overrides the value for loop on the constructor, if it was set.
pitch : ''A4'', // A4 is 440 hertz.
label : ''A'', // A label that identifies this note.
env : {hold : 9001},
panning : [1, -1, 10],
filter : {frequency : 900},
delay : {delayTime : .8}
})
Sonido para juegos
Otra biblioteca similar a Wad.js es " Sound for Games ", que se centra más en la producción de efectos, al tiempo que proporciona un conjunto similar de funcionalidad a través de una API relativamente distinta (y quizás más concisa):
function shootSound() {
soundEffect(
1046.5, //frequency
0, //attack
0.3, //decay
"sawtooth", //waveform
1, //Volume
-0.8, //pan
0, //wait before playing
1200, //pitch bend amount
false, //reverse bend
0, //random pitch range
25, //dissonance
[0.2, 0.2, 2000], //echo array: [delay, feedback, filter]
undefined //reverb array: [duration, decay, reverse?]
);
}
Resumen
Vale la pena ver cada una de estas bibliotecas, ya sea que necesite reproducir un solo archivo de sonido o quizás crear su propio editor de música, generador de efectos o videojuego basado en html.
Aquí hay un método para hacer posible reproducir incluso el mismo sonido simultáneamente. Combínalo con el precargador y estarás listo. Esto funciona con Firefox 17.0.1 al menos, aún no lo he probado con nada más.
// collection of sounds that are playing
var playing={};
// collection of sounds
var sounds={step:"knock.ogg",throw:"swing.ogg"};
// function that is used to play sounds
function player(x)
{
var a,b;
b=new Date();
a=x+b.getTime();
playing[a]=new Audio(sounds[x]);
// with this we prevent playing-object from becoming a memory-monster:
playing[a].onended=function(){delete playing[a]};
playing[a].play();
}
Enlazar esto a una tecla del teclado, y disfrutar:
player("step");
Aquí hay una idea. Cargue todo su audio para una cierta clase de sonidos en un solo elemento de audio individual donde los datos src son todas sus muestras en un archivo de audio contiguo (probablemente desee un poco de silencio entre ellos para poder capturar y cortar las muestras con un tiempo de espera con menos tiempo). riesgo de sangrado a la siguiente muestra). Luego, busque la muestra y reprodúzcala cuando sea necesario.
Si necesita más de uno de estos para reproducir, puede crear un elemento de audio adicional con el mismo src para que se almacene en caché. Ahora, efectivamente tienes múltiples "pistas". Puede utilizar grupos de pistas con su esquema de asignación de recursos favorito como Round Robin, etc.
También puede especificar otras opciones como poner en cola los sonidos en una pista para reproducir cuando ese recurso esté disponible o cortar una muestra que se esté reproduciendo actualmente.
Eche un vistazo al sitio jai (-> mirror ) (interfaz de audio javascript). Al observar su fuente, parecen estar llamando a play()
repetidamente, y mencionan que su biblioteca podría ser apropiada para su uso en juegos basados en HTML5.
Puedes disparar múltiples eventos de audio simultáneamente, que podrían usarse para crear juegos de Javascript o tener una voz que habla sobre música de fondo.
La respuesta seleccionada funcionará en todo excepto en IE. Escribí un tutorial sobre cómo hacer que funcione cross browser = http://www.andy-howard.com/how-to-play-sounds-cross-browser-including-ie/index.html
Aquí está la función que escribí;
function playSomeSounds(soundPath)
{
var trident = !!navigator.userAgent.match(/Trident//7.0/);
var net = !!navigator.userAgent.match(/.NET4.0E/);
var IE11 = trident && net
var IEold = ( navigator.userAgent.match(/MSIE/i) ? true : false );
if(IE11 || IEold){
document.all.sound.src = soundPath;
}
else
{
var snd = new Audio(soundPath); // buffers automatically when created
snd.play();
}
};
También debe agregar la siguiente etiqueta a la página html:
<bgsound id="sound">
Finalmente puedes llamar a la función y simplemente pasar por el camino aquí:
playSomeSounds("sounds/welcome.wav");
Me encontré con esto mientras programaba un generador de tarjetas musicbox. Comenzó con diferentes bibliotecas, pero cada vez que había un problema técnico de alguna manera. El retraso en la implementación de audio normal fue malo, no se hicieron múltiples reproducciones ... finalmente se terminó usando la biblioteca lowlag + soundmanager:
http://lowlag.alienbill.com/ y http://www.schillmania.com/projects/soundmanager2/
Puede consultar la implementación aquí: http://musicbox.grit.it/
Generé archivos wav + ogg para reproducciones de múltiples navegadores. Este reproductor de musicbox funciona con capacidad de respuesta en ipad, iphone, Nexus, mac, pc, ... funciona para mí.
No es posible hacer una toma múltiple con un solo elemento <audio>
. Necesitas usar múltiples elementos para esto.
Para reproducir la misma muestra varias veces, ¿no sería posible hacer algo como esto:
e.pause(); // Perhaps optional
e.currentTime = 0;
e.play();
( e
es el elemento de audio)
Tal vez malinterpreté completamente tu problema, ¿quieres que el efecto de sonido se reproduzca varias veces al mismo tiempo? Entonces esto es completamente incorrecto.
Recomendaría usar SoundJS , una biblioteca que he ayudado a desarrollar. Le permite escribir una única base de código que funciona en todas partes, con SoundJS seleccionando el audio web, el audio html o el audio flash, según corresponda.
Te permitirá hacer todo lo que quieras:
- Juega y mezcla múltiples sonidos,
- Reproduce la misma muestra varias veces, posiblemente reproducciones superpuestas
- Interrumpe la reproducción de una muestra en cualquier punto.
- Reproduce archivos WAV que contienen (según el soporte del navegador)
Espero que ayude.
Sé que esto es un hack total, pero pensé que debería agregar esta biblioteca de audio de código abierto de muestra que puse en github hace un tiempo ...
https://github.com/run-time/jThump
Después de hacer clic en el enlace de abajo, escriba las teclas de la fila de inicio para reproducir un riff de blues (también escriba varias teclas al mismo tiempo, etc.)
Ejemplo utilizando la biblioteca jThump >> http://davealger.com/apps/jthump/
Básicamente funciona al hacer elementos invisibles <iframe>
que cargan una página que reproduce un sonido en Listo ().
Ciertamente, esto no es lo ideal, pero podría hacer +1 en esta solución solo por la creatividad (y por el hecho de que es de código abierto y funciona en cualquier navegador en el que lo haya probado).
:)
Siempre puede probar AudioContext
que tiene soporte limitado, pero es parte del borrador de trabajo de la API de audio web . Podría valer la pena si planea lanzar algo en el futuro. Y si solo estás programando para Chrome y Firefox eres oro.
Suena como lo que quieres es un sonido multicanal. Supongamos que tiene 4 canales (como en juegos muy antiguos de 16 bits), todavía no he podido jugar con la función de audio HTML5, pero no necesita 4 elementos <audio>, y el ciclo que se usa para reproducir el siguiente efecto de sonido? ¿Has probado eso? ¿Lo que pasa? Si funciona: para reproducir más sonidos simultáneamente, simplemente agregue más elementos <audio>.
Lo he hecho antes sin el elemento <audio> HTML5, usando un pequeño objeto Flash de http://flash-mp3-player.net/ - escribí un cuestionario de música ( http://webdeavour.appspot.com/ ) y lo usó para reproducir clips de música cuando el usuario hizo clic en el botón de la pregunta. Inicialmente tenía un jugador por pregunta, y era posible jugarlos uno encima del otro, así que lo cambié, así que solo había un jugador, lo que apuntaba a diferentes clips de música.
También es posible que desee utilizar esto para detectar el audio HTML 5 en algunos casos:
http://diveintohtml5.ep.io/everything.html
Función de detección de HTML 5 JS
function supportsAudio()
{
var a = document.createElement(''audio'');
return !!(a.canPlayType && a.canPlayType(''audio/mpeg;'').replace(/no/, ''''));
}
http://robert.ocallahan.org/2011/11/latency-of-html5-sounds.html
http://people.mozilla.org/~roc/audio-latency-repeating.html
Funciona bien en Firefox y Chrome para mí.
Para detener un sonido que comenzó, haga var sound = document.getElementById ("shot"). CloneNode (true); sound.play (); y luego sound.pause ();