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で鳴らすだけです。
全ソースコードです。
<!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の中身)";