1. ホーム
  2. ジャバスクリプト

[解決済み】JavaScript / HTML5での効果音について

2022-04-30 14:07:08

質問

HTML5を使ってゲームを作っているのですが、今困っているのは効果音の出し方です。

具体的な要件は、ほとんどありません。

  • 複数のサウンドを再生し、ミックスする。
  • 同じサンプルを複数回再生し、場合によっては重ねて再生することができます。
  • サンプルの再生を任意の位置で中断する。
  • できれば(低品質の)生のPCMを含むWAVファイルを再生したいが、もちろんこれらを変換することもできる。

私が最初に行った方法は、HTML5の <audio> 要素で、すべてのサウンドエフェクトをページ内に定義しています。Firefox は WAV ファイルを問題なく再生してくれますが #play を複数回再生しても、実際にはサンプルは複数回再生されません。私の理解では、HTML5の仕様では <audio> 要素も再生状態を追跡しているので、それで説明がつきます。

私はすぐにaudio要素のクローンを作ろうと思い、以下のような小さなJavaScriptライブラリを作成しました(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;
      };
    });
  }
};

というわけで、今できるのは Snd.boom(); をFirebugのコンソールから再生し snd/boom.wav が、やはり同じサンプルを複数回再生することはできません。どうやら <audio> 要素は、効果音を再生するものというより、むしろストリーミングのための機能です。

できればHTML5とJavaScriptだけを使って、私が見逃しているこれを実現する賢い方法はないでしょうか?

なお、テスト環境はUbuntu 9.10上のFirefox 3.5です。他のブラウザ(Opera、Midori、Chromium、Epiphany)を試したところ、さまざまな結果が得られました。何も再生しないものもあれば、例外を投げるものもあります。

解決するには?

HTML5 Audio オブジェクト

をわざわざ使う必要はありません。 <audio> 要素を使用します。HTML 5 では Audio オブジェクト を直接表示します。

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

現在のバージョンの仕様では、ミキシングはサポートされていません。

同じ音を複数回鳴らすには、複数の Audio オブジェクトを作成します。また snd.currentTime=0 を、再生終了後にオブジェクトに追加します。


JSのコンストラクタはフォールバックに対応していないため <source> 要素を使用する必要があります。

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

を実行して、ブラウザがOgg Vorbisをサポートしているかどうかをテストします。


ゲームや音楽アプリ(単なるプレーヤー以上のもの)を書いている場合は より高度なWeb Audio API であり、現在では ほとんどのブラウザーでサポートされている .