2013/06/13

iOSにてweb audio apiの謎な現象??

久しぶりの更新になってしまいました。

もっとWEB以外のいろんなことを書きたいのですが、、、

今日はか・な・り悩み続けたことを一つ記事にしたいと思います。

ちなみにまだ解決していませんが、、、。

iOS6よりweb audio apiが使える!



前のブログの記事

HTML5でスクラッチカードもどき

でもチラッと書いたんですが、

audioタグにてBGMの再生。

正直ゲームなどのSEで使うには少々無理がありました、、、。

それがこのweb audio apiではシーケンサーのような素晴らしいループ、

やらなんやらいろいろなことができるようです!!

同時に複数音鳴らすことももちろん可能!

素晴らしい!

正直良くわかっていませんが、、、。

まぁweb audoi apiのすごさと使い方は

HTML5 ROCKS TUTORIALS Getting Started with Web Audio API

こちらを見ていただければと。

そんで、先日作ってみたゲームAnimalPuzzle(音が出ます!!)

これに早速BGMやらSEを入れてみました。

正直こんなに調子良く音がでるんだ!!と驚きました。

発生のタイミングも遅延無くばっちりでした!

これは使える。

先ほどのHTML5ROCKS様のコードをまぁほぼそのまま使わせていただきました。

そして怪奇現象起こりました。

iOS用はそもそもウェブアプリモードを想定していましたので

ホーム画面に追加して使用していました。

デバッグ中にホームボタンでアプリを消してその後すぐにまた立ち上げました。

するとどーでしょう。

フリーズ?です。

どのボタンも効きません。

できることはスクリーンショット撮るか、ボリュームの調整くらい。

なにもできない。

あえて言うなら、iOS6より追加されたシングルアップモードに近い状態です。

もはやホームボタン+スリープボタンによる強制終了しか残されていません。

なにが原因か突き詰めていったところこのweb audio apiぽいことが判明。

createBufferSource()を行ったあとアプリを落としてすぐまた立ち上げるとこの現象になりました。

ちなみに3GS、4S、iPad2、iOS6.1.2、6.1.3どの端末でも発生。

こんな素敵なAPIだからだれかしらこの問題を解決してくれてるだろうと

結構ググったんですがこのような記述はみつかりませんでした。

もしかしてこういう仕様?とか、なんかド忘れしてる、俺?とか、そもそもウェブアプリモードとかあんまり使う人実はいない?

バグ?、とか少々不安に。

でもやっぱりおかしい。

どなたかこんな不具合に遭遇した方いませんでしょうか?

ありえないっしょ!って方はよかったらお試し下さい。

web audio api(クリックで音が出ます!!)

こちらをホーム画面に追加>立ち上げる>クリックして音を出す>ホームボタンで落とす>すぐに再度立ち上げる>フリーズ

恐らく強制終了しかできなくなりますのでご注意下さい!!

それと自分は問題なかったですが端末等に何か不具合でても責任は負えませんので自己責任でお願いします、、。

コード自体はHTML5ROCKS様のコードほぼそのまま使わせてもらっているので問題ないと思うのですが、、、。

var AudioControl = function(urlList) {
    this.enable = this.flag = !(typeof window.webkitAudioContext === 'undefined');
    this.urlList = urlList;
    this.bufferList = {};
    this.count = 0;
    this.length = 0;
    this.complete = !this.flag;
};
AudioControl.prototype.load = function() {
    this.ctx = new webkitAudioContext();
    for(var key in this.urlList) {
        this.length++;
        this.loadBuffer(this.urlList[key], key);
    };
};
AudioControl.prototype.loadBuffer = function(url, key) {
    var xhr = new XMLHttpRequest();
    var loader = this;
    xhr.open('GET', url, true);
    xhr.responseType = 'arraybuffer';
    xhr.onload = function() {
        loader.ctx.decodeAudioData(xhr.response,
            function(buffer) {
                loader.bufferList[key] = null;
                loader.bufferList[key] = buffer;
                if (++loader.count == loader.length) {
                    loader.complete = true;
                    document.getElementById('loadFlag').innerHTML = 'complete';
                };
            },
            function(error) {console.log(error)}
        );
    };
    xhr.onerror = function() {
        console.log('XHR error');
        loader.enable = loader.flag = false;
    };
    try {
        xhr.send();
    } catch(e) {};
};
AudioControl.prototype.on = function(key, type, _gain) {
    this[key] = this.ctx.createBufferSource();
    this[key].buffer = this.bufferList[key];
    this[key].connect(this.ctx.destination);
    this[key].noteOn(0);
};
var urlList = {'se1': 'se1.wav'};
var audio = new AudioControl(urlList);
if(audio.enable) audio.load();

こんな感じで、、。

せっかくSEとか作ってみたんですが、

残念ながら使えない。。。

何か情報お持ちの方コメントよろしくお願いします。