LoginSignup
24
23

More than 5 years have passed since last update.

オフラインでWebAudio APIを再生する

Last updated at Posted at 2014-11-03

Javascriptで音を鳴らすにはどうしたらいいかなぁと
色々調べてみました
いくつか方法がありますが

①audioタグをJavaScriptで制御する
②WebAudio APIで再生する

今回はローカルの音を鳴らすにはどうしたらいいか考えました。
①はローカルのリソースをaudioタグのsrcに指定すれば鳴らせます
②はXHRもしくはinputタグのfile属性からのファイル取得(File API)限定なため、
ブラウザの仕様上結構難しい

①でいいじゃないかという声が上がってくると思いますが
iPhoneやAndroidではaudioタグの複数同時再生ができなかったりします
逆にWebAudio APIなら複数音同時再生できます。
(上記とは別にスマホブラウザでは①、②ともに
ユーザアクションがないと再生できないという制限があります)
ちなみに②のinputタグから取得する方法だと、ページ表示時に鳴らせないため
別の方法を使います。
あっ、HTML5前提です。

パクry・・・参考元
(英語わかる人はこっち見た方が早いかも)
http://html5doctor.com/taking-web-audio-offline-in-ios-6-safari/

流れとしては次のように行います
・opensslでオーディオファイルをbase64化
・base64データをArrayBuffer化
・後はWebAudioAPIにロードさせる

MacOSX 前提ですが次のOpenSSLコマンドでオーディオファイルをbase64ファイル化します


openssl base64 -in [infile] -out [outfile]

今回はjump.wavでやってみました
(適当なオーディオファイルをご準備ください)


openssl base64 -in jump.wav -out jump.txt

base64に変換でき・・・んん?改行入っているぞ
ということで、改行も次のコマンドで除外します(※ここ重要)


cat jump.txt | tr -d '\n' > out.txt

base64→ArrayBuffer変換ですが
base64-binary.jsを使います

使い方は下みたいに使います


var sound = "base64データ";
var arrayBuff = Base64Binary.decodeArrayBuffer(sound);

後はArrayBufferからデータを取得してWebAudio APIで鳴らすだけです。

全ソースコードです。

offline_webaudio.html
<!DOCTYPE html>
<html lang="en" manifest="web.appcache"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta charset="utf-8">
<title>Offline Audio Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="./js/jump.js"></script>
<script src="./js/base64-binary.js"></script>
<script type="text/javascript">

var myAudioContext, mySource, myBuffer;

if ('AudioContext' in window) {
    myAudioContext = new AudioContext();
} else if ('webkitAudioContext' in window) {
    myAudioContext = new webkitAudioContext();
} else {
    alert('Your browser does not support yet Web Audio API');
}

function play () {

    mySource = myAudioContext.createBufferSource();
    mySource.buffer = myBuffer;
    mySource.connect(myAudioContext.destination);

    if ('AudioContext' in window) {
        mySource.start(0);
    } else if ('webkitAudioContext' in window) {
        mySource.noteOn(0);
    } 

}


window.onload = function(){

    var arrayBuff = Base64Binary.decodeArrayBuffer(sound);

    myAudioContext.decodeAudioData(arrayBuff, function(audioData) {
        // データ取得
        myBuffer = audioData;

        // 再生
        play();
    });

};

</script>
</head>

<body>
<h1>Offline Web Audio Demo</h1>
<button onclick="play();" style="height: 44px; width: 75px;">Play</button>

</body>
</html>

base64データが長いので別ファイルにしてます。
今回はjump.jsに分離しました
jump.jsにはout.txtで出力したbase64データをコピペします


 var sound="base64データ(out.txtの中身)";
24
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
24
23