331 votes

Effets sonores en JavaScript / HTML5

J'utilise HTML5 pour programmer des jeux. L'obstacle que je rencontre actuellement est de savoir comment jouer des effets sonores.

Les exigences spécifiques sont peu nombreuses :

  • Jouez et mélangez plusieurs sons,
  • Jouer le même échantillon plusieurs fois, éventuellement en le faisant se chevaucher,
  • Interrompre la lecture d'un échantillon à n'importe quel moment,
  • Jouez de préférence des fichiers WAV contenant du PCM brut (de basse qualité), mais je peux les convertir, bien sûr.

Ma première approche a été d'utiliser le HTML5 <audio> et définir tous les effets sonores de ma page. Firefox lit les fichiers WAV comme sur des roulettes, mais en appelant #play multiple times ne joue pas vraiment l'échantillon plusieurs fois. D'après ce que je comprends de la spécification HTML5, l'option <audio> suit également l'état de la lecture, ce qui explique pourquoi.

J'ai immédiatement pensé à cloner les éléments audio, et j'ai donc créé la minuscule bibliothèque JavaScript suivante pour le faire à ma place (elle dépend 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;
      };
    });
  }
};

Donc maintenant je peux faire Snd.boom(); à partir de la console Firebug et jouer snd/boom.wav mais je ne peux toujours pas lire le même échantillon plusieurs fois. Il semble que le <audio> est davantage une fonction de streaming qu'un outil permettant de jouer des effets sonores.

Existe-t-il un moyen astucieux de réaliser cette opération que je n'ai pas trouvé, de préférence en utilisant uniquement HTML5 et JavaScript ?

Je dois également mentionner que, mon environnement de test est Firefox 3.5 sur Ubuntu 9.10. Les autres navigateurs que j'ai essayés - Opera, Midori, Chromium, Epiphany - ont donné des résultats variables. Certains ne jouent rien, d'autres lèvent des exceptions.

0 votes

Hah ! Je suis aussi en train de porter un vieux jeu Macintosh en HTML5. Vous voulez bien révéler lequel vous clonez ?

1 votes

C'est le projet ARASHI, un clone de Tempest.

0 votes

Qu'entend-on par "mélanger" les sons ?

468voto

porneL Points 42805

HTML5 Audio objets

Vous n'avez pas besoin de vous embêter avec <audio> éléments. HTML 5 vous permet d'accéder Audio objets directement :

var snd = new Audio("file.wav"); // buffers automatically when created
snd.play();

Il n'y a pas de support pour le mélange dans la version actuelle de la spécification.

Pour jouer le même son plusieurs fois, créez plusieurs instances de la fonction Audio objet. Vous pouvez également définir snd.currentTime=0 sur l'objet après qu'il ait fini de jouer.


Comme le constructeur JS ne prend pas en charge le fallback <source> vous devez utiliser les éléments

(new Audio()).canPlayType("audio/ogg; codecs=vorbis")

pour vérifier si le navigateur prend en charge Ogg Vorbis.


Si vous écrivez un jeu ou une application musicale (plus qu'un simple lecteur), vous voudrez utiliser la fonction API audio Web plus avancée qui est maintenant supporté par la plupart des navigateurs .

0 votes

C'est exactement ce que je fais maintenant, merci pour le pointeur ! J'utilise toujours les éléments <audio>, car ils me permettent a) d'autobuffer et b) de toujours spécifier toutes les ressources dans la page HTML. Je lis simplement leurs attributs 'src' comme avant pour instancier l'audio. Firebug ne montre pas de requêtes supplémentaires, donc le cache fonctionne, et tout va bien !

18 votes

Audio sont autobuffés. Ils sont conçus de manière analogue à Image Les techniques classiques de préchargement d'images fonctionnent donc aussi avec l'audio.

6 votes

Cela fonctionne également sur iOS. Notez cependant que vous besoin de d'utiliser une action de l'utilisateur (par exemple, un clic sur un bouton) pour déclencher le son. Vous ne pouvez pas simplement faire un snd.play() sur window.load().

42voto

Chris Jaynes Points 1527

API Audio Web

Edit : À partir de décembre 2021, l'API audio Web est essentiellement supporté par dans Chrome, Firefox, Safari et tous les autres principaux navigateurs (à l'exception d'IE, bien sûr).

En juillet 2012, le API Audio Web est désormais pris en charge par Chrome, et au moins partiellement par Firefox, et il est prévu de l'ajouter à IOS à partir de la version 6.

Bien que le Audio est suffisamment robuste pour être utilisé par programme pour des tâches de base, il n'a jamais été conçu pour fournir un support audio complet pour les jeux et autres applications complexes. Il a été conçu pour permettre l'intégration d'un seul élément multimédia dans une page, à l'instar de l'élément img tag. Il y a beaucoup de problèmes à essayer de l'utiliser pour les jeux :

  • Les dérapages sont fréquents avec Audio éléments
  • Vous avez besoin d'un Audio pour chaque instance d'un son
  • Les événements de charge ne sont pas totalement fiables, mais
  • Aucun contrôle de volume commun, aucun fondu, aucun filtre/effet.

Voici quelques bonnes ressources pour commencer à utiliser l'API audio Web :

3 votes

Cette réponse est meilleure que celle qui a été acceptée, car elle se concentre sur la bonne solution au problème (API WebAudio) et sur les raisons pour lesquelles les éléments audio ne sont pas une bonne solution, plutôt que d'essayer de bricoler une mauvaise solution avec des éléments audio.

35voto

d13 Points 667

howler.js

Pour la création de jeux, l'une des meilleures solutions consiste à utiliser une bibliothèque qui résout les nombreux problèmes auxquels nous sommes confrontés lorsque nous écrivons du code pour le web, tels que howler.js . howler.js abstrait le grand (mais bas niveau) API Audio Web dans un cadre facile à utiliser. Il tentera de se rabattre sur Élément audio HTML5 si l'API audio Web n'est pas 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

Une autre grande bibliothèque est wad.js Il est particulièrement utile pour produire des sons synthétiques, tels que de la musique et des effets. Par exemple :

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

Son pour les jeux

Une autre bibliothèque similaire à Wad.js est " Son pour les jeux ", il se concentre davantage sur la production d'effets, tout en fournissant un ensemble similaire de fonctionnalités par le biais d'une API relativement distincte (et peut-être plus concise) :

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?]
  );
}

Résumé

Chacune de ces bibliothèques vaut le coup d'œil, que vous ayez besoin de lire un simple fichier sonore ou de créer votre propre éditeur de musique, générateur d'effets ou jeu vidéo basé sur le langage HTML.

0 votes

Je ne peux pas faire de commentaires sur le développement de jeux, mais je l'utilise pour quelques retours audio mineurs dans une interface et pour cela, il fonctionne à merveille. Rapide, facile et simple.

0 votes

Un cadre de travail vraiment agréable, qui fonctionne bien sur les téléphones portables. Vous devez le déclencher avec touchstart... mais une fois que c'est fait, il fonctionne sans problème :)

0 votes

Howler.js est génial, jusqu'à présent.

9voto

Rob Points 654

Vous pouvez également l'utiliser pour détecter l'audio HTML 5 dans certains cas :

http://diveintohtml5.ep.io/everything.html

HTML 5 JS Fonction de détection

function supportsAudio()
{
    var a = document.createElement('audio'); 
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
}

0 votes

Merci de l'avoir noté. J'ai appris cette méthode à partir de has.js, mais je trouve qu'elle a quelques problèmes dans Firefox, et apparemment dans Opera aussi selon le code source de has.js. (réf : github.com/phiggins42/has.js/issues/48 github.com/phiggins42/has.js/blob/master/detect/audio.js#L19 )

4voto

Raul Agrait Points 3177

Jetez un coup d'œil à la jai (-> miroir ) (interface audio en javascript). En regardant leur source, ils semblent appeler play() à plusieurs reprises, et ils mentionnent que leur bibliothèque pourrait être appropriée pour une utilisation dans des jeux basés sur HTML5.

Vous pouvez déclencher plusieurs événements audio simultanément, ce qui peut être utilisé pour créer des jeux Javascript, ou faire parler une voix sur une musique de fond

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X