審査のないブラウザアプリは色々制限されている
いま2014年に作成したhtmlアプリ(webViewにhtmlゲームを表示するだけの構造)をブラウザでも遊べるように改造中なのですが、音の再生に躓いたのでメモ。
スマホアプリをストアに掲載するには審査が必要ですが、ブラウザアプリには審査がありません。そのためアプリよりも制限が厳しくなっています(ブラウザの自由度が高いと悪用される危険があるため)。しかし、まさかBGM再生のようなことまで制限があるとは…
七並べを頑張ると良い占いの結果が出る占いアプリを作成しました。 Android版は配信停止
スマホのブラウザは音再生に制限
html5にはサウンド再生に関連するaudioタグが存在します。これを利用すれば簡単なjavaScriptだけでボタンのクリック音などを簡単に設定することができます(BGMのような流しっぱなしのサウンドはJavaScriptなしで再生できます「属性:autoplay」の利用)。
→参考:MDN – <audio>: 埋め込み音声要素
ただしスマホ(iOS/Android)のブラウザではユーザーの操作時にしかサウンドを再生できないという制限があります。つまりクリック音などは問題ないのですが、BGMのような自動的に音を再生するような処理はできませんし、弾が敵に当たったときに再生する爆発音などもダメです(ユーザーの関与外での通信量の増大を考慮しての仕様だそうです)。
ツール系のアプリならBGMが無くても問題ありませんがゲームでBGMが再生できないのは寂しいので調べることにしました。
以下のサイトはaudioではなくvideoタグですが、この問題を回避するヒントを提供してくれています。しかしサウンド再生にここまでコードを書くのはツライのでさらに別の方法を探すことにしました。
Androidでは、clickイベントはユーザーのアクションがないと発火しないようですが、clickされなかったときも発火させたいです。
Web Audio API
MDNのaudoiタグの説明ページに「使用上の注意」の項目があり、そこでWeb Audio APIの紹介がありました。AudioタグがIEに対応しているのに対し、Web Audio APIはIEに対応していないのが気になりますが、とりあえず調査しました。
→参考:MDN – Web Audio API
→参考:Can i use. – Web Audio API
→参考:Can i use. -Audio element
MDNの説明は難しいので他のページを検索。以下のサイトが分かりやすかったです。
Web Audio API の Getting Started, 最小サンプルを作っていきたいと思います
iOSではユーザーの操作が必要
AndroidではWeb Audio APIを利用するとユーザー操作の必要なくBGMを再生できることを確認しました。しかしiOSはやはりユーザーの操作が必要なようです。ただし一度でもユーザー操作によって音を再生すれば以降は自由に再生可能なようです。
ということで参考になった2つのURLをメモ。
→参考:Qiita : iOSでのオーディオ再生制限の解除方法いろいろ
→参考:Qiita : WebAudio::AudioBufferSourceNode does not play on first touchstart event.
Audioタグでもイケルのでは?
Web Audio APIを利用しても制限(iOS)があり、しかもIEで利用できません。あと音を鳴らすだけならWeb Audio APIは少しオーバースペック(ピッチ変更など音声の加工もできる!)な気がします。記述しなければならないコード量も多いし…。
audioタグとWeb Audio APIを両方とも学んで、何となく制限はAudioタグやWeb Audio APIよりも深いところが原因な気がしました。ということは前項のWeb Audio APIでの制限の解除方法である「一度でもユーザー操作によって音を再生すれば以降は自由に再生可能」はaudioタグでも有効なような気がします。
ということで検索条件を絞って調査すると見つかりました!。これでwebアプリでもサウンドを再生する目処が立ちそうです!。今回は時間切れなので実証は次回に。
→参考:iOS/Android で HTML5 の audio/video を任意のタイミングで再生する方法
iframeの利用
今回の制限以外に1つ問題があります。それはhtmlを切り替えるときにサウンドが中断されることです。今回のアプリは以下のようにメニューとゲーム部分が別htmlになっているのですが、メニューでボタンを押したときのクリック音がhtmlの切換で中断されてしまうのです。とすればBGMもhtmlを跨いで再生させることはできません…
この問題を回避するためにはiframeを利用し、サウンドの管理を親htmlで行い、子htmlをmenu.htmlやgame.htmlに切り替えるような構成にするしか有りません(たぶん)。少し面倒かもしれませんが、その方が最終的には効率も良く汎用性の高い構造になる気がします。ということで次回はiframeを利用した構成について書こうと思います(失敗しても書くよ)。
ということで、今回はこれにてお仕舞い。
twitterを本格的に初めてみた。ブログの更新記事をつぶやくのがメイン。あとCocos2dやUnity、その他アプリ開発に関連するツイッターの方をフォローして情報も集められたらなぁと思います。
— 柳澤@ゲーム作るよ (@designdrill) 2015, 12月 28