[JavaScript] Web Audio API を利用してサウンドを再生する (Microsoft Edge, Google Chrome用)

このページのタグ:[JavaScript] [サウンド] [Web Audio API]
Web Audio API を利用してサウンドを再生するコードを紹介します。

注意

Web Audio APIはInternet Explorerでは利用できないため、Microsoft Edge, FireFox, Chrome などのWebブラウザを利用します。

方法1:ページ表示時にサウンドのHttpRequestを初期化する方法

ページ表示時にサウンドを取得するHttpRequestを初期化する方法です。再生するサウンドが決まっている場合はこの方法を用いると初期化がページ表示時に完了するため、素早くサウンドの再生ができます。

コード

以下のHTMLファイルを作成します。

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
	<meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, user-scale=yes, initial-scale=1.0, maximum-scale=5.0" />

  <script type="text/javascript">
    var request, source;

    window.onload = function () {
      request = new XMLHttpRequest();
      request.open("GET", "sound2.mp3", true);
      request.responseType = "arraybuffer";
      request.onload = completeOnLoad;
      request.send();
    };

    function completeOnLoad() {
      window.AudioContext = window.AudioContext || window.webkitAudioContext;
      context = new AudioContext();
      context.createBufferSource().start(0);

      // オーディオをデコード
      context.decodeAudioData(request.response, function (buf) {
        source.buffer = buf;
        source.loop = false;

      });

      source = context.createBufferSource();

      var elem = document.getElementById("Play");
      elem.addEventListener("click", playStart, false);
    }

    function playStart() {
      source.connect(context.destination);
      source.start(0);
    }
  </script>

</head>
<body>
  <a id="Play" href="javascript:void(0);">再生</a><br />
</body>
</html>

解説


  window.onload = function () {
    request = new XMLHttpRequest();
    request.open("GET", "sound2.mp3", true);
    request.responseType = "arraybuffer";
    request.onload = completeOnLoad;
    request.send();
  };
ページ表示時に、HttpRequestを準備します。このHttpRequestでサウンドファイルにアクセスします。onloadイベントにcompleteOnLoad()関数を設定し、サウンドファイルの読み込みの完了後にcompleteOnLoad()関数を実行させます。


  function completeOnLoad() {
    window.AudioContext = window.AudioContext || window.webkitAudioContext;
    context = new AudioContext();

    // オーディオをデコード
    context.decodeAudioData(request.response, function (buf) {
      source.buffer = buf;
      source.loop = false;
    });

    source = context.createBufferSource();

    var elem = document.getElementById("Play");
    elem.addEventListener("click", playStart, false);
  }
サウンドファイルの読み込み後、completeOnLoad関数が実行されます。new AudioContext();により、新しい、AucioContextオブジェクトを作成します。
context.decodeAudioData()はデコード処理を記述します。
context.createBufferSource()メソッドを呼び出し、サウンドの再生バッファソースを作成します。また、addEventListener()メソッドを呼び出し、再生リンクにclickイベントを設定しています。


  function playStart() {
    source.connect(context.destination);
    source.start(0);
  }
リンクがクリックされたときは、バッファへ接続し、サウンドの再生を開始します。

補足1

Microsoft Edge, Google Chromeで動作させる場合は下記のコードでも動作します。(Mobile Safari では動作しません)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <meta charset="utf-8" />
  <script type="text/javascript">  
    var request, source;

    //Microsoft Edge用
    window.onload = function initSound() {
      request = new XMLHttpRequest();
      request.open("GET", "sound2.mp3", true);
      request.responseType = "arraybuffer";
      request.onload = completeOnLoad;
      request.send();
    }

    function completeOnLoad() {
      context = new AudioContext();
      source = context.createBufferSource();

      context.decodeAudioData(request.response, function (buf) {
        source.buffer = buf;
      });
      var elem = document.getElementById("Play");
      elem.addEventListener("click", PlayStart, false);
      source.connect(context.destination);
    }

    function PlayStart() {
      // オーディオをデコード
      source.start(0);
    }
  </script>
</head>
<body>
  <a id="Play" href="javascript:void(0);">再生</a><br />
</body>
</html>

補足2

Microsoft Edge, Google Chromeで動作させる場合は下記のコードでも動作します。(Mobile Safari では動作しません)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
	<meta charset="utf-8" />

  <script type="text/javascript">
    var request, context, source;

    function initSound() {
      request = new XMLHttpRequest();
      request.open("GET", "sound2.mp3", true);
      request.responseType = "arraybuffer";
      request.onload = completeOnLoad;
      request.send();
    }

    //Microsoft Edge用 (2)
    function completeOnLoad() {
      context = new AudioContext();
      source = context.createBufferSource();

      var elem = document.getElementById("Play");
      elem.addEventListener("click", PlayStart, false);
    }

    function PlayStart() {
      // オーディオをデコード
      context.decodeAudioData(request.response, function (buf) {
        source.buffer = buf;
        source.connect(context.destination);
        source.start(0);
      });
    }
  </script>

</head>
<body onload="initSound();">
  <a id="Play" href="javascript:void(0);" onclick="playSound();">再生</a><br />
</body>
</html>

方法2:リンククリックなどのアクションでHttpRequestを初期化する方法

方法1のページ表示時にHttpRequestを初期化する方法では再生ファイルが少ない場合は良いですが、再生するファイルの選択肢が増えるとすべてのサウンドに対してページ表示時に初期化する必要があり、ファイル数の数だけHttpRequestを用意する必要があります。再生できるサウンドの選択肢が多い場合は、リンクなどのアクション発生時にHttpRequestを初期化します。

コード


<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
  <title></title>
  <meta charset="utf-8" />

  <script type="text/javascript">
    var request, context, source;
    
    //Microsoft Edge用 (1)
    function playSound() {
      request = new XMLHttpRequest();
      request.open("GET", "sound2.mp3", true);
      request.responseType = "arraybuffer";
      request.onload = completeOnLoad;
      request.send();
    }

    function completeOnLoad() {
      context = new AudioContext();
      source = context.createBufferSource();

      // オーディオをデコード
      context.decodeAudioData(request.response, function (buf) {
        source.buffer = buf;
      });

      source.connect(context.destination);
      source.start(0);
    }
  </script>

</head>
<body onload="initSound();">
  <a id="Play" href="javascript:void(0);" onclick="playSound();">再生</a><br />
</body>
</html>

解説

動作は、先の場合と同様です。HttpRequestの初期化が、再生リンクをクリックし、playSound()関数が実行されたタイミングで処理されます。初期化後、サウンドファイルの読み込みが完了し、completeOnLoad()関数が呼び出されると、デコード処理を設定し、バッファソースへの接続と再生を開始します。
また、このコードはMobile Safari ではタップの制約により動作しません。詳細は「[JavaScript] iOSのMobile Safari でWeb Audio API を利用したサウンドが再生されない (タッチ制約による制限)」の記事を参照してください。

補足1

Microsoft Edge, Google Chromeで動作させる場合は下記のコードでも動作します。(Mobile Safari では動作しません)

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <title></title>
	<meta charset="utf-8" />
  <meta name="viewport" content="width=device-width, user-scale=yes, initial-scale=1.0, maximum-scale=5.0" />

  <script type="text/javascript">

    //iOS版
    var request;
    
    function clickPlay() {
        status = 1;
        request = new XMLHttpRequest();
        request.open("GET", "sound2.mp3", true);
        request.responseType = "arraybuffer";
        request.onload = completeOnLoad;
        request.send();
    };

    function completeOnLoad() {
      var elem = document.getElementById("Play");
      elem.innerText = "再生中";

      window.AudioContext = window.AudioContext || window.webkitAudioContext;
      context = new AudioContext();
      context.createBufferSource();

      source = context.createBufferSource();
      // オーディオをデコード
      context.decodeAudioData(request.response, function (buf) {
        source.buffer = buf;
        source.loop = false;
        source.connect(context.destination);
        source.start(0);
      });
      
    }
  </script>

</head>
<body>
  <a id="Play" href="javascript:void(0);" onclick="clickPlay();">読み込み</a><br />
  <div>iOS Mobile Safariではブロックされてしまう例です。正しく動作しません。</div>
</body>
</html>
登録日 :2015-10-17    最終更新日 :2015-12-17
このページのタグ:[JavaScript] [サウンド] [Web Audio API]
Japanese
プライバシー    iPentecについて
iPentec all rights reserverd. (ISDC)