学園アイドルマスターのバックグラウンド再生が凄い　という話

## TL;DL
- ゲームアプリ「学園アイドルマスター」にはAndroid/iOS端末で楽曲のバックグラウンド再生機能がある
- Unity+CRIWareでバックグラウンド再生を行うのは障害がある
- バックグラウンド再生用にネイティブPluginを実装しないと多分実現できない、凄く手間がかかっている

## この記事の目的
学園アイドルマスターには楽曲のバックグラウンド再生機能があります。
この記事は、バックグラウンド再生の何が凄いのか、実装する上で何が障害になるかを考察する事を目的としています。

## 免責事項
筆者は株式会社バンダイナムコエンターテインメント及び株式会社QualiArtsとは無関係です。
また、筆者はスマートフォン用ゲームアプリ「学園アイドルマスター」の開発に一切関わっていません。
この記事では、「学園アイドルマスター」のゲーム内画面をスクリーンショットで引用しています。

## 学園アイドルマスターとは
https://gakuen.idolmaster-official.jp/

QualiArtsとバンダイナムコエンターテインメントが2024年5月16日から開発運営を行っている育成シミュレーションゲームです。


## 学園アイドルマスターにおけるバックグラウンド再生

学園アイドルマスターにはゲーム内楽曲の再生画面があります。

この画面内でだけ、ゲームがバックグラウンドに移動しても楽曲が再生され続けます。
バックグラウンド再生中は、通知画面上から再生の停止/再開/次へ/前への制御ができます。


![Android.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122986/3ec5ebd7-a321-b795-d7c8-bdf7f5ced135.jpeg)
![iOS.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122986/5879ad7a-66fd-c8cf-ebe6-2694e9021316.jpeg)



## 学園アイドルマスターの動作環境と使用ミドルウェア/Plugin
コピーライトにUniRxの表記があるので、恐らくUnityで作られています。



タイトル画面の右上に「CRIWARE」の表記があるので、音楽再生系の処理はCRIWAREというミドルウェアを使って制御してると推測できます。

## バックグラウンド再生を行う上で何が障害になるか
### CRIWAREとUnityは音楽のバックグラウンド再生をサポートしていない
[CRIWARE Unity Plug-in](https://game.criware.jp/manual/unity_plugin/latest/contents/index.html)は、2024年5月現在、AndroidとiOSでアプリケーションがバックグラウンドに移動した場合の音楽再生についての案内がなく、サポートしていないようです。

また、[Unity 2023](https://docs.unity3d.com/ja/2023.1/Manual/UnityManual.html)もAndroidとiOSのバックグラウンド再生の記載がなく、サポートしていないようです。


つまり、CRIWAREとUnityだけではバックグラウンド再生を実現できません。
他の手段を用いてバックグラウンド再生を行う必要があります。

### ゲーム外からの再生制御処理を入れないといけない

AndroidのGooglePlayStore、iOSのAppStoreでアプリを出す場合、ストアの規約を満たしたアプリを提出し、審査を通過する必要があります。

【Android】
Androidはアプリの品質に関する資料で、バックグラウンド再生時の注意について記載があります。
- [Android Developers - アプリの中核品質](https://developer.android.com/docs/quality-guidelines/core-app-quality?hl=ja)
    - FN-M1: アプリがバックグラウンドで音声を再生する場合は、MediaStyle でスタイル設定された通知を作成する

Androidは通知欄に操作コンソールを表示させないといけません。

【iOS】
iOSはバックグラウンド再生の制約について、Reviewガイドラインに直接の言及はありません。
- [App Reviewガイドライン](https://developer.apple.com/jp/app-store/review/guidelines/)

強いて言えば以下の項目は気をつけるべきでしょうか。

>2.4.2ASRとNR 電力を効率的に使用できるように、またデバイスを損傷させるおそれのない方法で使用できるようにアプリを設計してください。アプリが急速にバッテリーを消費すること、過度な熱を発生させること、デバイスのリソースに不必要な負荷をかけることがないようにしてください。たとえば、充電中にデバイスをマットレスや枕の下に置くよう促したり、ソリッドステートドライブに過剰な回数の書き込みを行ったりするなどが例として挙げられます。アプリでは、サードパーティの広告が表示されるものも含め、暗号通貨のマイニングのような無関係なバックグラウンドプロセスを実行することはできません。

>2.5.4ASRとNR マルチタスクアプリには、VoIP、オーディオ再生、位置情報、タスクの完了、ローカル通知など、意図された目的のためのバックグラウンドサービスのみを使用してください。


一番問題になるのは、
iOSは[バックグラウンド再生を有効にする](https://developer.apple.com/documentation/avfoundation/media_playback/configuring_your_app_for_media_playback#4182619)と、アプリがバックグラウンドに移動した際、常にコントロールセンターにPlayerが出てしまう点です。[^1]

コントロールセンター上での制御に対応していないと、品質に関してストア審査で突っ込まれる可能性が非常に高いです。

品質面では他にも、
[RemoteCommandCenter](https://developer.apple.com/documentation/mediaplayer/mpremotecommandcenter)でイヤホン等外部デバイスからの再生制御も実装しないとAppストア審査で突っ込まれる可能性があります。[^2]



つまり、バックグラウンド再生を入れようとすると、両OSともアプリ外からの制御処理が必要になります。[^3]

[^1]: 確かそういう仕様だったはずですが、ちょっとこの点に関して手元で確認できる環境が無いので有識者の方おしえてください。
[^2]: レビュー担当者によるんですが、AppStoreレビューは未実装に見える挙動について細かく突いてくる節があります。
[^3]: Androidと挙動を合わせないとユーザーに対して不公平感を与える事になるので、ビックタイトルほどOS間の挙動に差異が生まれないように気をつけるはず。


## (推測)この問題を解決するためにはどうするべきか？
### Android/iOSで音楽再生用のネイティブプラグインを用意しないといけない

結論から言えば、Android/iOSで音楽再生用のネイティブプラグインを用意するのが妥当です。

UnityとCRIWAREはリファレンスにバックグラウンド再生の記載が無いし、APIとして用意もないので対応していません。
リファレンスに載っていないということは多分UnityとCRIWAREはサポートしてくれなさそう。[^4]

Android/iOSで別々に、OSレイヤーのAPIを直接使う音楽再生の仕組みを用意しなければいけません。

### Android/iOSで音楽再生用のネイティブプラグインを用意するのはどういう事か？

通常のUnity+CRIでの音楽再生のフローは以下の画像のようなイメージです。

![normal.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122986/bc7199a7-fc13-1df7-8b20-b4555b838480.jpeg)

学園アイドルマスターの音楽再生のフローは以下の画像のようになってるのでは？と推測しています。
![gakumasu.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122986/6d8dca77-2d90-b553-a354-b8deb1fb548c.jpeg)


これはどういう事かというと、
- ミュージックルーム以外ではUnityエンジン+CRIWAREを介した音楽再生を行っている
- ミュージックルームではAndroid/iOS用音楽制御Pluginを介して音楽再生を行っている

かなと状況的に予想してます。


![Flow.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122986/d20c8ae8-9c65-83d3-2a62-e687a4b83d0f.jpeg)


[^4]: バンダイナムコ社ほどの会社ならCRIとコネクションがありそうですが、CRI側がバックグラウンド再生に対応したらさっさとSDKを更新してそうな気がします。


### Android/iOSで音楽再生用のネイティブプラグインを用意することのデメリット

#### 開発コストとQAコストが高い
Android/iOSで別々に音楽再生制御～バックグラウンド挙動を作らないといけないので、単純に×2のコストがかかります。
ゲーム業界はUnity+C#でゲームを作れる人が多くても、iOS/Androidのネイティブコードを書ける人は多くないです。若手ほど[^5]。
コア機能に掛からない機能開発の割にあんまり数がいないエンジニアを当てる必要があります。

QA(デバック)も同じくコストがかかります。
Android/iOSはもちろん、OSバージョンでも多分振る舞いは変わるし、PixelとGalaxy、iPhoneとiPadなど機種別に色々問題が見つかる可能性は高いです。
更に、SpotifyやYoutubeMusicなどのバックグラウンド再生機能のある音楽再生アプリと衝突した場合の挙動、他のゲームアプリ起動時の挙動など観点が様々あります。
検証範囲がアプリ内だけに収まらないので、ゲームQAとは別観点で検証を進める必要があります。


#### ネイティブプラグイン用に画像と音楽データを別で持たないといけない

Android/iOSで実行できるようにコンパイルするにあたって、Unityで使うデータやソースコードはAndroid/iOSの実行ファイルの中に格納されます。

Unityのデータは殆どAssetBundleの方で持ってるはずですが、Assetbundleに格納されるデータをAndroid/iOSコードで呼び出すのは結構難しいです。

後述するエンコードの問題もあるので、音楽データと再生制御コンソールに表示するアートワーク画像はAndroid/iOSコードが呼び出せる場所に置いてあると思います。

![ApplicationData.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/122986/5d99ed1c-8ad1-8f94-a281-25cff37d6534.jpeg)

ただ、ミュージックデータをバイナリにパッキングするのはアップロード容量上限の問題が出てくるので現実的ではないです(純増するのでいずれ限界が来ます)。Unityからコピーしてくるか、画面遷移のタイミングでネイティブ用のデータをDLして来てるかしてると思います。

#### CRIは独自規格であるADX/HCA/HCA-MX形式の音楽ファイルのみをサポートしていること

CRIWAREでは、ADX/HCA/HCA-MX形式の音楽ファイルでのみ音楽再生をサポートしています。
この形式はCRIの独自規格なので、Android/iOSの音楽再生APIで使えません。
Unity+CRIとは別に、バックグラウンド再生で呼び出すためにmp3等で音楽データを用意しないといけません。
容量の問題と楽曲ぶっこ抜きの対策もより考えないといけないかもしれません。

圧縮形式の差で音質の差も若干ではあるんですが発生すると思うので、IPホルダー側とその辺問題ないかを握る必要があるでしょう。


[^5]: 端末ネイティブでゲームを作ってた人、cocos2dxでゲーム作ってた人は30↑なら結構いるので、いる所にはいます。

## まとめ
現行のスマートフォン向けゲームアプリの多くはUnity+CRIで作られていることが多いです。

この開発環境だと、アプリがバックグラウンドに移動した場合の音楽再生に対応していないのですが、学園アイドルマスターはバックグラウンド再生を実現しているので本当に凄いことをやっています。
技術的な難易度もそうだし、開発/QAコストやリジェクトリスクの判断などの問題もクリアしているわけだからです。

リジェクトリスクを加味した舵取りは開発エンジニアに限らず、プロダクトオーナーやIPホルダーを含めた開発グループ内のコミュニケーションが重要になります。

バックグラウンド再生は色々なハードルを乗り越えて実装されたはずなので、この機能をリリースしたことが凄いです。