修理/メンテ/改造/開発/DIY

みなさまこんにちは、うはるんです。
なんちゃってプログラマーと化したうはるん
今回は、前回の記事の続報的な内容になります。
前回の記事でお伝えした通り、私は、
- プロデュース:ワイ(うはるん)
- コード生成:Gemini / ChatGPT
というメンバー(?)で、「UH Music Player(Lite)」と名付けたオリジナルのミュージックプレイヤーアプリの開発を進めています。
Geminiはベースとなったコードを書いてくれたのですが、トラブルシューティングがあまりにも使えなくて、結局その後はチャッピーに全て任せています。
また、今回のアプリ開発は別に不特定多数に向けてPlayストアで公開することは目標としておらず、
あくまで自分自身の(AIを用いた)創作としてどこまで作りこめるか、といった自己満足を目的に行っております。

そして、早速のアプデが実装される。

実用版が完成した後も、チャッピーとおしゃべりしながらコツコツとアプリ開発を続けてきました。
そしてついに、初の大型アップデートの実装まで漕ぎつけました。
とはいっても、あらゆる箇所を追加するためにデバッグのためにAPKを生成してADBコマンドで実機にインストールして動作確認を行っているので、
初回版完成から今回のアプデ版までに、24個ほどのAPKを生成しております。

バグ潰しは困難を極めました。


今回のアプデの追加内容
- イヤホン抜去時再生停止機能の実装
- 出力先モニタリング・表示機能の実装
- 楽曲情報・再生状況取得システムの軽量化
- UIの細かな改良とバグ潰し
ひとつづつ詳しく見ていきましょう!
1.イヤホン抜去時再生停止機能

これは文字通りの機能です。というか、プレイヤーアプリならごくごく当たり前のように搭載されている機能ですが、UH Music Playerにもちゃんと組み込みました。
写真では、有線イヤホンを接続中に音楽を再生している様子ですが、ここで急にイヤホンを引っこ抜いてみます。

下部のボタン群。元々は一時停止マークだったのが、再生マークに変わっています。もちろんボタンには触れていませんよぉ?
これはつまり、アプリ側が再生中にイヤホン出力からスピーカー出力に切り替わったことを検知して、
「スピーカーから音楽は一瞬たりとも流させない!!!」
という強い意志のもとに、再生を自動で停止してくれています。

Bluetoothデバイスとの接続が解除されてしまったときに、
端末スピーカーから爆音が鳴り響いて電車の中などで恥ずかしい思いをしないように、という
安全機能なのです。

本機能は環境設定でオンオフを切り替えられるようになっておりますが、
安全機能という役割を持たせているので、アプリインストール直後のデフォルト状態でONになっています。
なので、設定してなくて電車の中で爆音が鳴り響くという心配もありません。ユーザー側が弄らない限り。
2.出力先モニタリング・表示機能

1と合わせて、端末スピーカーでの誤爆事故防止機能となっています。
ですのでこちらも、インストール直後のデフォルト状態でオンになっています。
ライブラリ画面の右上に、スライダー型の表示UIを追加しました。
これは、現在音楽が端末スピーカーかそれ以外のところか、どちらから流れるようになっているのかをリアルタイム表示してくれます。
端末スピーカーから流れる状態であれば、写真のように左側のスピーカーアイコンのところへ。

有線イヤホン・USBオーディオ・Bluetoothデバイスから流れる状態であれば、右側のヘッドホンアイコンのところへスライダーが移動します。
このUIが表示されるライブラリ画面を表示した状態で、
イヤホンを引っこ抜いたり、逆にイヤホンを接続したり、Bluetoothデバイスの接続・接続解除を行うと、
ぬらーっとしたアニメーション表示でスライダーが移動します。これは見ていてめちゃくちゃ気持ちいいですし、現在の出力先が一目でわかって超絶便利です。
神経質で心配性なうはるんは、
電車やバスの中で音楽を聴くとき、「本当にイヤホン接続されてるだろうな?」と疑いながら恐る恐る再生しています。
今回追加したこの機能があれば、そんな必要もなくなるわけですね。
ひとつ重要な仕様として、このスライダーは、
あくまで表示機能でありユーザーの手で切り替えるスイッチではないので、
タップしたい欲が出ないように、あえてスライダーを見えにくいグレーの色に設定しています。

いかにもタップして切り替えられそうな雰囲気を醸し出していたので、即刻グレーに変更しましたw

もちろん、ダークモードにも対応です。
全画面プレイヤーではさらに詳細に表示

全画面プレイヤーでは、アイコンだけでなく文字で詳細に表示される他、
- 本体スピーカー
- 有線ヘッドホン
- USBオーディオ(USB-DACやタイプC直結イヤホンなど)
- Bluetoothデバイス(イヤホンかスピーカーかの判別はなし)
の4つの属性を認識して表示してくれます。

こんな感じで、わかりやすいアイコンと文字で表示されます。
これらアイコンは全てチャッピーが生成してくれました。スピーカーとヘッドホンはチャッピーが勝手に考えてくれたものを、USBオーディオとBluetoothデバイスはワイ考案のものをチャッピーにアイコンとして出力してもらいました。

権利面をクリアにしつつわかりやすいものを考案したつもり
なお、この全画面プレイヤー用表示も再生中の出力先変化をリアルタイムでUIに反映させてくれます。

そしてもちろん、こちらもダークモード対応です。
3.楽曲情報・再生状況取得システムの軽量化
これは今回、音声の出力先を500ms(毎秒2回)ごとに監視してUIに反映するという処理を追加したために処理しなければならないことが増えてしまったために、
端末によっては動作が重くなってしまったのでそれを解決するため、既存のシステムの無駄な部分を省いて軽量化に努めました。
こちらの記事で紹介した、AQUOS EVER SH-02J(Snapdragon 430 / RAM2GB)なんかではFLACを再生すると動作が激重になっていました。
(ちなみにここから新品が買えますよ!皆さんもおひとつ、いかがですか?)
話はアプリのほうに戻りまして、
仮にもLite版を名乗っていたアプリがこの有様じゃあ絶対良くないと感じて軽量化を敢行。
まず、初回リリース版(※リリースしていません)時点での楽曲情報取得処理。
各Activity内のプレイヤーが、アプリ内に仕組んだMusicServiceから500msごとに、
- アルバム名
- アーティスト名
- ジャケット写真
- トラック情報(アルバム何曲中何曲目を再生中かの情報)
- 再生状態(メインボタンのアイコン更新のため)
- 曲の長さ(シークバー最大値・再生時間)
- リピート状態
- シャッフル状態
- 現在の曲番号
- 現在の再生位置(シークバー・経過時間の反映のため)
を取得していました。
それに加えて、今回の追加機能で現在の出力先と出力先名までもが500msループに組み込まれたため、結果としてスナドラ430機のような低性能な環境で激重を引き起こしていたのです。


特に、アーティスト名やジャケット写真なんて
絶対に、どう転んでも、たとえ天地がひっくり返ったとしても、
500ms(毎秒2回)ごとに情報を取得する必要なんてありません。
Activityが生成されるタイミングで取得すればいいだけ。
ですので、このような無駄を徹底的に省き、不要な処理を500msループから追い出すことで軽量化を図りました。
ただし軽くしたいからといって、今回追加した出力先を見る処理をActivity生成時だけにしてしまっては、リアルタイムで出力先の変化を監視しUIに反映させる目的は果たせませんし、
現在の再生位置を500msごとに取得するのをやめてしまっては、シークバーがプレイヤー画面を開いているあいだずーーっと動かずそのままになってしまいますww
というわけで、チャッピーの指示を仰ぎながら、そしてコード生成自体もすべてチャッピーに丸投げして、
現在の500msループは狙い通りの挙動を実現できる必要最低限の処理に大幅にスリム化されているのです。

いかにもアプリ開発って感じがして非常に高まりましたねぇ!
4.UIの細かな改良とバグ潰し

本アプリでは初回起動時限定で、このようなセットアップウィザード的なものを実装しています。
これはアプリを初めて触るユーザーがスムーズかつ納得しながら、ライブラリとして読み込むフォルダを指定できるようにという意図で実装しています。

でも、自己満足としてこういうのは実装したいタイプなの!!!
初回リリース版(※リリースしてません)では、ちょっとだけ粗というか意図しない挙動というか、起こりうる様々なパターンに対応出来ていなかったので、すべての動作に対して適切な処理がなされるよう設定しました。

チャッピーに、このようなフローチャートを画像化してもらってパターンを明確にし、
総当たりでデバッグを行いました。
結果、多分ですが起こりうるすべてのパターンに対して適切な処理が入っていると思われます。
絶対に抜け穴がないようにデバッグした感じですね。

その過程で、徹底的に親切設計にするべくストレージアクセス権限なし時のライブラリ画面を用意したり、

ストレージアクセス権限はあるけどライブラリフォルダ未指定時のライブラリ画面なんかも作りました。
当然このような要素を加えるだけで、デバッグ箇所は増えます。でもね。作りこみたくなっちゃうんですよね。

おわりに:今後のアップデートについて

実は既に、さらなる改良の余地を見出しています。
Geminiで開発していた時は、私が意図しないところでGeminiが勝手に、全画面プレイヤーをライブラリ画面と楽曲一覧画面のボトムシートとして下部からスライドアップして展開されていました。
そして、現在のxmlにその名残、というか残滓が組み込まれているのです。
あの時は原因がわからなかったから、スムーズに横画面プレイヤーを実装するために専用のPlayerActivityを立ち上げたのですが、
この残滓を活用した上で、正式にlandscape(横画面UI)を設定してあげれば…?

PlaylistActivityそのものを無くして構造を簡略化出来る大アップデートを実装できそう!
いやあ。AI任せと言えども、アプリ開発って楽しいものですね。
これで何か商売になったりするわけではないのですが、趣味として普通に楽しいなあと感じました。

まとめ
アプリ開発って楽しい!!!
知識や自分で出来ることが増えるのってサイコーに楽しいよね。
- 楽しい(楽しい)
- 出来ることが増えていく快感
- 手持ちの端末コレクションがすべて、異なる環境ごとのバグ検証端末になり得る=コレクションを有効活用できる
- 出来上がったアプリは非常に実用的
- デバッグが苦痛すぎる
評価
関連商品
商品情報
- メーカー
- OpenAI
- 製品名
- ChatGPT Go
- 購入価格
- ¥1,400


そしてAPK配布してほしい!