web-dev-qa-db-ja.com

JavaScript / HTML 5の効果音

私はHTML 5を使ってゲームをプログラムしています。今私が遭遇した障害は、効果音を再生する方法です。

具体的な要件は数が少ないです。

  • 複数のサウンドを再生してミックスする
  • 同じサンプルを複数回再生します。
  • いつでもサンプルの再生を中断
  • できれば(低品質の)生の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;
      };
    });
  }
};

だから今私はFirebugコンソールからSnd.boom();を実行してsnd/boom.wavをプレイすることができますが、それでも同じサンプルを複数回プレイすることはできません。 <audio>要素は、実際には効果音を再生するためのものではなく、ストリーミング機能のようなものです。

私が見逃していることを実現するための賢い方法はありますか?できればHTML5とJavaScriptだけを使うのですか?

私のテスト環境はUbuntu 9.10上のFirefox 3.5です。私が試した他のブラウザ - オペラ、ミドリ、クロミウム、エピファニー - は様々な結果を生み出した。何もしないものもあれば、例外をスローするものもあります。

310
Stéphan Kochen

HTML5 Audioオブジェクト

<audio>要素を気にする必要はありません。 HTML 5では Audio objects に直接アクセスできます:

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 、現在は ほとんどのブラウザでサポートされている) を使用することをお勧めします。

441
Kornel

W3CによるWebAudioAPI

2012年7月現在、 WebAudio API は現在Chromeでサポートされており、少なくとも一部はFirefoxでサポートされており、IOSバージョン6以降。

それは基本的なタスクのためにプログラム的に使用されるのに十分頑強ですが、Audio要素はゲームなどのための完全なオーディオサポートを提供することを意図するものではありませんでした。タグ。ゲームにAudioタグを使用しようとすると多くの問題があります。

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

私はこの WebAudio入門 の記事を使ってWebAudio APIを始めました。 FieldRunners WebAudioのケーススタディ も参考になります。

36
Chris Jaynes

howler.js

ゲームのオーサリングには、 howler.js のように、Web用のコードを書くときに直面する多くの問題を解決するライブラリを使用するのが最善の解決策の1つです。 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ベースの音楽エディタ、エフェクトジェネレータ、またはビデオゲームを作成する必要があるかにかかわらず、一見の価値があります。

28
d13

場合によっては、これを使用して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/, ''));
}
9
Rob

これは、同じサウンドでも同時に再生できるようにするための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");
5
F-3000

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

http://flash-mp3-player.net/ - からの小さなFlashオブジェクトを使用して、私は以前にHTML5 <audio>要素なしでこれを行いました - 私は音楽クイズを書いて( http://webdeavour.appspot.com/ )、ユーザーが次のボタンをクリックしたときに音楽のクリップを再生しました。質問。最初は1人の質問につき1人のプレーヤーがいました、そして、互いの上にそれらを重ねて演奏することは可能でした、それで私は私が異なった音楽クリップを指した1人のプレーヤーだけがいるようにそれを変えました。

4
Lee Kowalkowski

を見てくださいジャイ ( - > )(Javascriptオーディオインターフェース)サイト。彼らの情報源を見ると、彼らはplay()を繰り返し呼び出しているように見え、そして彼らのライブラリはHTML5ベースのゲームでの使用に適しているかもしれないと述べています。

Javascriptゲームを作成したり、BGMを使って音声を話したりするために使用できる、複数のオーディオイベントを同時に発生させることができます。

4
Raul Agrait

これがアイデアです。 srcデータが連続したオーディオファイル内のすべてのサンプルである単一の個々のオーディオ要素に特定のクラスのサウンドのすべてのオーディオをロードします(おそらく、間の無音が必要なので、タイムアウトなしでサンプルを見つけてカットできます次のサンプルに出血する危険性があります。次に、サンプルを探して、必要に応じてそれを演奏します。

これらを再生するのに複数が必要な場合は、同じsrcを持つ追加のオーディオ要素を作成して、それがキャッシュされるようにすることができます。今、あなたは事実上複数の "トラック"を持っています。あなたはラウンドロビンなどのようなあなたの好きなリソース割り当て方式でトラックのグループを利用することができます.

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

3
digitalicarus

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

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

eはオーディオ要素です)

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

3
adamse

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.play();そして後でsound.pause();

2

私は SoundJS 、私が開発を手助けするライブラリを使うことを勧めます。 SoundJSが必要に応じてWebオーディオ、HTMLオーディオ、またはフラッシュオーディオを選択して、どこでも機能する単一のコードベースを作成できます。

それはあなたがあなたが望むすべてのことをすることを可能にするでしょう:

  • 複数のサウンドを再生してミックスする
  • 同じサンプルを複数回再生します。
  • いつでもサンプルの再生を中断
  • を含むWAVファイルを再生します(ブラウザのサポートによる)

それが役立つことを願っています。

2
OJay

単一の<audio>要素を使ってマルチショットプレイすることはできません。これには複数の要素を使用する必要があります。

1
Eli Grey

オルゴールカードジェネレータをプログラムしている間、私はこれに遭遇しました。別のライブラリから始めましたが、どういうわけかグリッチがありました。通常のオーディオ実装の遅れは悪く、マルチプレイもありませんでした...最終的にはlowlag library + soundmanagerを使用しました。

http://lowlag.alienbill.com/ および http://www.schillmania.com/projects/ soundmanager2 /

あなたはここで実装をチェックアウトすることができます: http://musicbox.grit.it/

私はマルチブラウザプレイ用にwav + oggファイルを生成しました。このオルゴールプレーヤーは、ipad、iphone、Nexus、mac、pcに応答して動作します。

1
Grit

選択された答えは、IE以外のすべてで機能します。私はそれをクロスブラウザで動作させる方法についてのチュートリアルを書きました= http://www.andy-howard.com/how-to-play-sounds-cross-browser-including-ie/ index.html

これが私が書いた関数です。

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");

私はこれが完全なハックであることを知っていますが、私はしばらく前に私がgithubに置いたこのサンプルオープンソースオーディオライブラリを追加するべきであると思いました...

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

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

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

基本的には、onReady()でサウンドを再生するページを読み込む不可視の<iframe>要素を作成することによって機能します。

これは確かに理想的ではありませんが、創造性だけに基づいてこのソリューションを+1することができます(そしてそれはオープンソースであり、私が試したすべてのブラウザで動作します)これにより、他の人が少なくともいくつかのアイデアを検索できるようになります。

:)

0
DaveAlger

あなたはいつでも試すことができます AudioContext それは限られたサポートを持っていますが、それは ウェブオーディオAPIの一部です 作業中のドラフト。将来何かをリリースするつもりなら、それは価値があるかもしれません。そして、あなたがクロムとFirefoxのためだけにプログラミングしているならば、あなたは黄金です。

0
haelmic
var AudioContextFunc = window.AudioContext || window.webkitAudioContext;
var audioContext = new AudioContextFunc();
var player=new WebAudioFontPlayer();
var instrumVox,instrumApplause;
var drumClap,drumLowTom,drumHighTom,drumSnare,drumKick,drumCrash;
loadDrum(21,function(s){drumClap=s;});
loadDrum(30,function(s){drumLowTom=s;});
loadDrum(50,function(s){drumHighTom=s;});
loadDrum(15,function(s){drumSnare=s;});
loadDrum(5,function(s){drumKick=s;});
loadDrum(70,function(s){drumCrash=s;});
loadInstrument(594,function(s){instrumVox=s;});
loadInstrument(1367,function(s){instrumApplause=s;});
function loadDrum(n,callback){
  var info=player.loader.drumInfo(n);
  player.loader.startLoad(audioContext, info.url, info.variable);
  player.loader.waitLoad(function () {callback(window[info.variable])});
}
function loadInstrument(n,callback){
  var info=player.loader.instrumentInfo(n);
  player.loader.startLoad(audioContext, info.url, info.variable);
  player.loader.waitLoad(function () {callback(window[info.variable])});
}
function uhoh(){
  var when=audioContext.currentTime;
  var b=0.1;
  player.queueWaveTable(audioContext, audioContext.destination, instrumVox, when+b*0, 60, b*1);
  player.queueWaveTable(audioContext, audioContext.destination, instrumVox, when+b*3, 56, b*4);
}
function applause(){
  player.queueWaveTable(audioContext, audioContext.destination, instrumApplause, audioContext.currentTime, 54, 3);
}
function badumtss(){
  var when=audioContext.currentTime;
  var b=0.11;
  player.queueWaveTable(audioContext, audioContext.destination, drumSnare, when+b*0, drumSnare.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumLowTom, when+b*0, drumLowTom.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumSnare, when+b*1, drumSnare.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumHighTom, when+b*1, drumHighTom.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumSnare, when+b*3, drumSnare.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumKick, when+b*3, drumKick.zones[0].keyRangeLow, 3.5);
  player.queueWaveTable(audioContext, audioContext.destination, drumCrash, when+b*3, drumCrash.zones[0].keyRangeLow, 3.5);
}
<script src='https://surikov.github.io/webaudiofont/npm/dist/WebAudioFontPlayer.js'></script>
<button onclick='badumtss();'>badumtss</button>
<button onclick='uhoh();'>uhoh</button>
<button onclick='applause();'>applause</button>
<br/><a href='https://github.com/surikov/webaudiofont'>More sounds</a>
0
user1024

Web Audio APIはこの仕事にぴったりのツールです。サウンドファイルのロードと再生には、少し作業が必要です。幸いなことに、仕事を簡単にするたくさんのライブラリがあります。音に興味があるので、私は musquito というライブラリも作成しました。

現在それはフェージング効果音のみをサポートし、私は3D空間化のような他のことに取り組んでいます。

0
VJAI