はじめに
タイトルの通り。たまに困っている人を見かけるので…。
トラブルは基本的にはphina.jsがサウンド周りに使っているWeb Audio APIの性質に起因します。
サウンドの鳴らし方そのものついては、すでにいくつか記事がありますのでここでは触れません。
原因
以下の環境・状況でサウンドを読み込もうとするとエラーで止まります。
ブラウザがインターネットエクスプローラー(IE)
IEは最新の11含め、WebAudioに一切対応していません。
その他のモダンなブラウザを使いましょう。
htmlファイルをfileスキームで表示している
htmlファイルを直接ブラウザで開くと通常http/httpsではなくfileスキームで開かれます。
(URL欄がfile://...
で始まってたらそうです。あるいは現行Chromeのようにローカルファイルであることが示されます)
詳細は割愛しますが、この状態ではセキュリティ対策により一部の機能に制約がかかり、WebAudioもその制約の影響で正常に動作しなくなります。
対策1:ローカルサーバーを使う
要はfileじゃなくてhttp/httpsスキームなら問題無いわけですが、開発中わざわざサーバーを用意してFTPソフトで都度アップロードして確認~なんてことはやってられません。そこでローカルサーバーを使います。
サーバーの立ち上げ方法は本当に様々なので詳細は「ローカルサーバー 立て方」でググってほしいのですが、例えばVSCode + Live Server拡張機能を使う方法が比較的手軽です。
ちなみにphina.jsの機能で言えばWebAudio以外にも例えば画像フィルター機能がfileスキーム環境でつまずきます。
無用のトラブルをさけるため、基本的にはローカルサーバー経由で開発を進めることを推奨します。
対策2:HTML5 Audioで代用
サーバーとかよくわからない・面倒くさい場合はあえてphinaのサウンド機能は使わず、HTML5 Audioを使うなどの代替策があります。こちらは同時再生数に制限がある・再生遅延があるなど、WebAudioよりも機能が劣りますが、fileスキームやIEでも動作し、使い方もシンプルです。
BGM再生程度ならこちらだけでいいかも。
またhowler.jsなどのサウンド専用ライブラリを別に使うという手もあります。
ただ、これらのライブラリでもWebaudioが使えない場合、HTML5 AudioやFlashで代用する処理をしていることに変わりありません。
対策3:音声データをDataURL化する
あんまりおすすめではないですが、音声ファイルをDataURL変換してから読み込む方法もあります。
const bgmDataURL = "data:audio/mpeg;base64,[base64エンコード後のめちゃくちゃ長い文字列]";
phina.main(function() {
const app = phina.game.GameApp({
startLabel: 'main',
assets: {
sound: {
// bgm: 'assets/bgm.mp3',
bgm: bgmDataURL,
}
},
});
app.run();
});
データをいちいち変換する手間がかかるのと、変換によってファイルサイズが肥大化するのであんまり利点が無いですが…。
一応そういう方法もあるんだなぁぐらいの認識で覚えておくと何かの役に立つかも知れません。
その他
- 自分自身は遭遇したことがないですが、拾い物の音源のデコードが上手くいかず止まってしまうこともあるようです。
mp3でAudioを使ったら再生出来るとの事なので、ビットレートが悪さしてるのではという気がします。自分も拾い物のmp3がWebAudioで再生出来ない事が何度かありました。その場合、再エンコードしたらassetを使う方法で再生する事が出来ました。一応ご参考まで。
— Yoshifumi Fujimoto (@minimo) September 8, 2020
- ブラウザが対応している拡張子・コーデックかどうかもチェックしておきます。mp3/aac形式あたりならまず問題無いですが、その他の形式はサポートがまちまちです。
番外:ユーザー入力を待ってから再生
エラーで止まることは無くなったが、タイミングによっては再生命令が無視される…というようなことがあります。iOS safariやAndroid chrome、PC Chromeなどのユーザーのインタラクションが無いと再生できない仕様に引っかかってると思われます。
phina.jsでの対策については**ここ**で少し触れています。
ほかにこういうトラブルがあったよ的な話がありましたらお知らせください。