324

私はHTML5を使用してゲームをプログラムしています。私が今遭遇した障害は、効果音をどのように演奏するかです。

特定の要件は数が少ないです:

  • 複数のサウンドを再生してミックスし、
  • 同じサンプルを複数回再生し、再生が重複する可能性があります。
  • いつでもサンプルの再生を中断し、
  • できれば(低品質の)生のPCMを含むWAVファイルを再生しますが、もちろんこれらを変換することもできます。

私の最初のアプローチは、HTML5<audio>要素を使用して、ページ内のすべての効果音を定義することでした。FirefoxはWAVファイルをほんの少しだけ再生しますが、#play複数回呼び出すと実際にはサンプルが複数回再生されるわけではありません。HTML5仕様の私の理解から、<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のみを使用して、これを実現するための賢い方法はありますか?

また、私のテスト環境はUbuntu9.10上のFirefox3.5です。私が試した他のブラウザ(Opera、Midori、Chromium、Epiphany)では、さまざまな結果が得られました。何も再生しないものもあれば、例外をスローするものもあります。

4

18 に答える 18

458

HTML5Audioオブジェクト

<audio>要素を気にする必要はありません。HTML 5 では、Audioオブジェクトに直接アクセスできます。

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

現在のバージョンの仕様では混合はサポートされていません。

同じサウンドを複数回再生するには、Audioオブジェクトの複数のインスタンスを作成します。snd.currentTime=0再生が終了した後でオブジェクトを設定することもできます。


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

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

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


ゲームや音楽アプリ (単なるプレーヤーではありません) を作成している場合は、現在ほとんどのブラウザーでサポートされている、より高度な Web Audio APIを使用することをお勧めします。

于 2009-12-19T22:37:51.183 に答える
39

WebオーディオAPI

編集: 2021年12月の時点で、Web Audio APIは基本的、Chrome、Firefox、Safari、およびその他すべての主要なブラウザー(もちろん、IEを除く)でサポートされています。

2012年7月の時点で、Web Audio APIはChromeでサポートされ、少なくとも部分的にFirefoxでサポートされており、バージョン6でIOSに追加される予定です。

このAudio要素は、基本的なタスクにプログラムで使用できるほど堅牢ですが、ゲームやその他の複雑なアプリケーションに完全なオーディオサポートを提供することを意図したものではありませんでした。imgこれは、タグと同様に、単一のメディアをページに埋め込むことができるように設計されています。それをゲームに使おうとすると多くの問題があります:

  • タイミングスリップはAudio要素で一般的です
  • Audioサウンドのインスタンスごとに要素が必要です
  • ロードイベントは完全に信頼できるわけではありませんが、
  • 一般的なボリュームコントロール、フェード、フィルター/エフェクトはありません

WebAudioAPIの使用を開始するための優れたリソースは次のとおりです。

于 2012-07-18T21:39:26.047 に答える
35

howler.js

ゲーム オーサリングの最適な解決策の 1 つは、 howler.jsなど、Web 用のコードを記述するときに直面する多くの問題を解決するライブラリを使用することです。howler.js は、優れた (しかし低レベルの) Web Audio APIを使いやすいフレームワークに抽象化します。Web Audio API が利用できない場合、 HTML5 Audio Elementにフォールバックしようとします。

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

もう 1 つの優れたライブラリはwad.js です。これは、音楽やエフェクトなどのシンセ オーディオの作成に特に役立ちます。例えば:

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

ゲーム用サウンド

Wad.js に似たもう 1 つのライブラリは " Sound for Games " です。効果の生成により重点を置いていますが、比較的明確な (そしておそらくより簡潔な) API を介して同様の機能セットを提供します。

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

概要

単一のサウンド ファイルを再生する必要がある場合でも、独自の html ベースの音楽エディター、エフェクト ジェネレーター、またはビデオ ゲームを作成する必要がある場合でも、これらの各ライブラリは一見の価値があります。

于 2013-10-23T15:06:30.217 に答える
9

場合によっては、これを使用して HTML 5 オーディオを検出することもできます。

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

HTML 5 JS 検出機能

function supportsAudio()
{
    var a = document.createElement('audio'); 
    return !!(a.canPlayType && a.canPlayType('audio/mpeg;').replace(/no/, ''));
}
于 2011-01-01T14:07:35.397 に答える
5

同じ音でも同時に再生できるようにする方法の 1 つを次に示します。プリローダーと組み合わせると、準備完了です。これは、少なくとも Firefox 17.0.1 で動作しますが、他のものではまだテストしていません。

// 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();
}

これをキーボードのキーにバインドして、お楽しみください。

player("step");
于 2012-12-24T14:04:31.523 に答える
4

あなたが望むものはマルチチャンネルサウンドのように聞こえます。あなたが4つのチャンネルを持っているとしましょう(本当に古い16ビットゲームのように)、私はまだHTML5オーディオ機能で遊ぶことに慣れていませんが、4つの<audio>要素と使用されるサイクルが必要ではありません次の効果音を再生するには?あなたはそれを試しましたか?何が起こるのですか?動作する場合:同時により多くのサウンドを再生するには、<audio>要素を追加するだけです。

以前、HTML5 <audio>要素を使用せずに、http://flash-mp3-player.net/の小さなFlashオブジェクトを使用してこれを実行しました。音楽クイズ(http://webdeavour.appspot.com/)を作成しました。ユーザーが質問のボタンをクリックしたときに音楽のクリップを再生するために使用しました。最初は質問ごとに1人のプレーヤーがいましたが、それらを重ねて再生することができたので、1人のプレーヤーだけになるように変更し、さまざまなミュージッククリップをポイントしました。

于 2009-12-19T20:55:02.010 に答える
4

同じサンプルを複数回再生するには、次のようなことはできません。

e.pause(); // Perhaps optional
e.currentTime = 0;
e.play();

eオーディオ要素です)

おそらく私はあなたの問題を完全に誤解しました、あなたは効果音を同時に複数回再生したいですか?それならこれは完全に間違っています。

于 2009-12-19T20:19:58.633 に答える
4

jai(-> mirror)(javascript audio interface)サイトをご覧ください。ソースを見ると、繰り返し呼び出しているように見えplay()、ライブラリがHTML5ベースのゲームでの使用に適している可能性があると述べています。

複数のオーディオイベントを同時に発生させることができます。これは、Javascriptゲームを作成したり、バックグラウンドミュージックで音声を話したりするために使用できます。

于 2009-12-19T20:25:16.533 に答える
3

これがアイデアです。特定のクラスのサウンドのすべてのオーディオを単一の個別のオーディオ要素にロードします。ここで、src データは連続したオーディオ ファイル内のすべてのサンプルです (おそらく、タイムアウトが少ないサンプルをキャッチしてカットできるように、その間にある程度の無音が必要です)。次のサンプルに出血するリスクがあります)。次に、サンプルを探して、必要に応じて再生します。

これらを複数再生する必要がある場合は、同じ src を持つ追加のオーディオ要素を作成してキャッシュすることができます。これで、効果的に複数の「トラック」ができました。ラウンドロビンなど、お気に入りのリソース割り当てスキームでトラックのグループを利用できます。

リソースが使用可能になったときに再生するトラックにサウンドをキューに入れたり、現在再生中のサンプルをカットしたりするなど、他のオプションを指定することもできます。

于 2011-04-04T05:21:34.853 に答える
2

http://robert.ocallahan.org/2011/11/latency-of-html5-sounds.html

http://people.mozilla.org/~roc/audio-latency-repeating.html

私にとってはFirefoxとChromeで問題なく動作します。

開始したサウンドを停止するには、var sound = document.getElementById("shot").cloneNode(true); を実行します。サウンド.プレイ(); それ以降は sound.pause();

于 2012-01-11T23:58:17.743 に答える
0

選択した回答は、IE 以外のすべてで機能します。クロスブラウザで動作させる方法についてのチュートリアルを書きました。ここに私が書いた関数があります:

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

また、次のタグを html ページに追加する必要があります。

<bgsound id="sound">

最後に、関数を呼び出して、ここでパスを渡すだけです。

playSomeSounds("sounds/welcome.wav");
于 2014-05-13T08:01:27.337 に答える
0

AudioContextサポートは限定されていますが、いつでも試すことができますが、これはWeb オーディオ APIのワーキング ドラフトの一部です。将来的に何かをリリースする予定がある場合は、価値があるかもしれません。また、Chrome と Firefox 用にのみプログラミングしている場合は、最適です。

于 2016-08-29T03:23:52.540 に答える
0

これが完全なハックであることはわかっていますが、少し前に github に置いたこのサンプル オープン ソース オーディオ ライブラリを追加する必要があると考えました...

https://github.com/run-time/jThump

下のリンクをクリックした後、ホーム行のキーを入力してブルースのリフを演奏します (複数のキーを同時に入力するなども可能です)。

jThump ライブラリを使用したサンプル >> http://davealger.com/apps/jthump/

基本的に<iframe>は、サウンドを再生するページをロードする非表示の要素を作成することで機能します onReady()。

これは確かに理想的ではありませんが、創造性だけに基づいてこのソリューションを +1 することができます (そして、それがオープン ソースであり、私が試したどのブラウザーでも動作するという事実)。

:)

于 2013-03-28T23:25:49.090 に答える