JavaScript / HTML5の効果音


316

ゲームのプログラミングにHTML5を使用しています。私が今遭遇している障害は、効果音を再生する方法です。

特定の要件は少数です。

  • 複数のサウンドを再生してミックスし、
  • 同じサンプルを複数回再生し、場合によっては再生を重ねて、
  • 任意の時点でサンプルの再生を中断し、
  • できれば(低品質の)RAW 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のみを使用してください。

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


はぁ!また、古いMacintoshゲームをHTML5に移植しています。どれをクローンしているのかを明らかにしますか?
有料オタク、

1
嵐のクローン、Project ARASHIです。
ステファンKochen

サウンドの「ミキシング」とはどういう意味ですか?
Mads Skjern

2
終わった?見えますか?
enyo 2012年

4
残念ながら、違います。暇な時間のプロジェクトを終わらせないコツがあります。:(そこにのためのgitのレポですが、私は年間でそれに触れていない。github.com/stephank/arashi-js
STEPHAN Kochen

回答:


448

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オーディオAPIを使用する必要があります。これは現在、ほとんどのブラウザーでサポートされています


18
Audioオブジェクトは自動バッファリングされます。それらはImageオブジェクトに類似して設計されているため、オールドスクールの画像プリロード手法はオーディオでも機能します。
Kornel

5
これはiOSでも機能します。ただし、サウンドを開始するには、ある種のユーザーアクション(ボタンのクリックなど)を使用する必要があることに注意してください。単にsnd.play()window.load()を実行することはできません。
ハスキー

1
<audio>タグはより制御しやすいため、引き続き使用しています。しかし、とにかく情報をありがとう!
Derek━會功夫

2
<audio> html5要素が複数のソースを許可するという事実がなければ、この方法をお勧めします。そのため、ブラウザーがmp3をサポートしていない場合は、ogg / wavにフォールバックできます。同じことを行うには、JavaScriptでのトリックが必要です。
joelmdev

2
iOS 6では自動再生がサポートされています。window.load()の単純なsnd.play()でサウンドを開始できます。
Pietro Polsinelli、2013

36

W3CによるWebAudio API

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

プログラムで基本的なタスクに使用できるほど堅牢ですが、Audio要素はゲームなどに完全なオーディオサポートを提供することを意図したものではありません。imgのように、1つのメディアをページに埋め込むことができるように設計されました鬼ごっこ。ゲームでオーディオタグを使用しようとすると、多くの問題があります。

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

このWebAudio入門記事を使用して、WebAudio APIを使い始めました。FieldRunners WebAudio事例も良い読み物です。


これは、問題の正しい解決策(WebAudio API)に焦点を当てているため、承認されたものよりも良い回答であり、Audio要素がAudio要素と一緒に悪いソリューションをハックしようとするのではなく、Audio要素が適切なソリューションではない理由
アノマリー

29

howler.js

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

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に似た別のライブラリは「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ベースの音楽エディター、エフェクトジェネレーター、またはビデオゲームを作成する必要がある場合でも、これらの各ライブラリは一見の価値があります。


ゲーム開発についてコメントすることはできませんが、私はこれをインターフェイス内のいくつかのマイナーなオーディオフィードバックに使用しています。すばやく簡単でシンプル。
Iculousを2014

本当に素晴らしいフレームワークで、モバイルでもうまく動作します。touchstartでトリガーする必要があります...しかし、それが完了すると、箱から出してすぐに動作します:)
Philip

9

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

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

HTML 5 JS Detect関数

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

ご指摘いただきありがとうございます。has.jsからこの方法を学びましたが、has.jsソースコードによると、FirefoxとOperaにも問題があるようです。(参考文献:github.com/phiggins42/has.js/issues/48 github.com/phiggins42/has.js/blob/master/detect/audio.js#L19
ステファンKochen

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

いいえ。個々のサウンド再生ごとに新しいオブジェクトを作成することは、解決策だとはまったく思いません。これは迅速で汚れた回避策ですが、これはより適切に実行できます。
Pawel

@Pawel True、これはサウンドを再生する主な方法として使用すべきではありませんが、私が知る限り、この例の原則は、同じサウンドを複数回同時に再生する、またはOPが表現する唯一の方法です、 「重複再生」。(ブラウザープラグインは必要ありません。)現在のプロジェクトの実際の実装は、投稿したサンプルコードよりもはるかに洗練されています。
F-3000

4

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

これまでに、HTML5 <audio>要素なしで、http://flash-mp3-player.net/の小さなFlashオブジェクトを使用してこれを行いました-音楽クイズ(http://webdeavour.appspot.com/)を書き、ユーザーが質問のボタンをクリックしたときに音楽のクリップを再生するために使用しました。最初は質問ごとに1人のプレーヤーがいましたが、お互いを重ねて再生することが可能だったので、プレーヤーを1人だけにして、別のミュージッククリップに向けました。


&lt; audio&gt;を使用するのは興味深い考えです。チャネルとしての要素。私は、ページ上の2つの要素を入れたときに、私がすることができ、それらを同時に再生します。元のコードでは2つのサンプルを再生することもできるので、私が実行しているクローン作成では実際に期待どおりの結果が得られないようです。同じサンプルの2倍ではありません。私はこれをもう少し実験する必要があります、そして結果を取り戻すでしょう!
ステファンKochen

ええ、コピーではなくクローンと呼ばれる微妙な理由があるかもしれません。おそらく、クローンはまだオリジナルと共有しているため、両方が同時に再生できません。
Lee Kowalkowski、2009

参考までに、少なくともFirefoxでは、同じ<audio>要素を再利用しても機能しません。'src'属性を設定できますが、実際には別のサンプルをロードしません。
ステファンKochen

4

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

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


3

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

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

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

たぶん私はあなたの問題を完全に誤解しました、サウンドエフェクトを同時に複数回再生したいですか?次に、これは完全に間違っています。


その通りです。同じサンプルを同時に複数回再生する必要があります。
ステファンKochen

はい、これは同じインスタンスを複数回再生しますが、この回答を見る人にとっては、OPが言っているように、これが「重複再生」を引き起こさないことに注意してください。
Patrick Roberts

3

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

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

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



2

私が開発を支援したライブラリであるSoundJSの使用をお勧めします。これにより、SoundJSが適切にWebオーディオ、htmlオーディオ、またはFlashオーディオを選択して、どこでも機能する単一のコードベースを記述できます。

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

  • 複数のサウンドを再生してミックスし、
  • 同じサンプルを複数回再生し、重複する可能性のある再生
  • 任意の時点でサンプルの再生を中断する
  • を含むWAVファイルを再生する(ブラウザのサポートに依存)

お役に立てば幸いです。


そのライブラリはかなり素晴らしいです、私は本当にsfxジェネレーターを掘ります。興味のある方のために
RozzA

1

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


1

オルゴールカードジェネレーターのプログラミング中にこれに遭遇しました。さまざまなライブラリから始めましたが、いつかなんらかの不具合がありました。通常のオーディオ実装のラグは悪く、複数の再生はありませんでした...最終的には、lowlagライブラリ+ soundmanagerを使用してしまいました:

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

ここで実装を確認できます:http : //musicbox.grit.it/

マルチブラウザー再生用のwav + oggファイルを生成しました。このミュージックボックスプレーヤーは、iPad、iPhone、Nexus、Mac、PCなどで動作します。


それは素晴らしいミュージックボックスアプリです!gitリポジトリはありますか?子供と一緒に使うかも!
icarito 2017年

0

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

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

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

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

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

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

:)


なぜ誰かがこれに反対票を投じたのですか?私にとっては実行可能なオプションのようです。
jtrick 2014年

それはかなりハッキーな解決策ですが、私はこのライブラリを使用してサンプルhtml 5キャンバスゲームを作成し、それでもなお機能し
DaveAlger

0

選択した回答は、IE以外のすべてで機能します。私はそれをクロスブラウザで動作させる方法についてのチュートリアルを書いた= http://www.andy-howard.com/how-to-play-sounds-cross-browser-includeing-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");

0

いつでも試すAudioContextことができますが、サポートに制限がありますが、これはWebオーディオAPIワーキングドラフトの一部です。将来リリースする予定がある場合は、価値があるかもしれません。そして、もしあなたがクロムとFirefoxのためだけにプログラミングしているなら、あなたは黄金です。


0

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

Web Audio APIは、この仕事に適したツールです。サウンドファイルの読み込みと再生に伴う作業はほとんどありません。幸いにも、作業を簡単にするライブラリはたくさんあります。音に興味を持って、私はmusquitoというライブラリも作成しました。これもチェックできます。

現在はフェードサウンドエフェクトのみをサポートしており、3D空間化などの他の作業を行っています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.