自作ソフト2個※の改良をしていて間が開いた。プログラムの変更・修正は面倒だが、動作確認に時間が掛かるものは大変だ。これは そのうちの1個で、動作確認が比較的短かく済んだものだ。
※面倒なことを同時にするつもりはなく、片方が片付いてから もう片方を始めたのだが、片付いたつもりがミスが見付かったりして、結局 同時進行になってしまった。途中で、いろいろなことが同時に起こり、頭がおかしくなりそうになって全部ぶちまけたくなるような、危ない場面もあった・・・
はじめに・概要
題は当たり前のことだけど難しい。: 以前 自作ソフト(Spotifyのミニプレーヤ Minisp)を新版(現行)のSpotifyアプリに対応させた時に手を抜いた※ために いくつかの問題(問題Aとする)が起こったが、別の問題(問題Bとする: PCのスリープからの復帰後にMinispがハングすることがある。: これも手抜きが発端の可能性がある)を直すために試行錯誤したら、そもそもの問題Bについては不明なものの、問題Aは直せた。 (ここの記述は いくら手直ししても、自分で読んでも分かりにくかったので、下のように時系列のリストにした。: 6/5 6:03)
- 以前 自作ソフト(Spotifyのミニプレーヤ Minisp)を新版(現行)のSpotifyアプリに対応させた時に手を抜いた。
- 元々動いていたものがSpotifyの都合で動かなくなったので、そういう しょうもないことのためにSpotifyを使って居る訳ではないので、時間・手を掛けたくなかったのだ。
- いくつかの問題(→ 問題A)が起こったが、暫定対処(手抜き)で しのいで居た。
- 問題の内容は下の「経緯・詳細」を参照のこと。
- その後見付かった別の問題(→ 問題B)を直すために試行錯誤した。
- PCのスリープからの復帰後にMinispがハングすることがある。: これも手抜きが発端の可能性がある。
- 問題Bについては不明なものの、問題Aは直せた。
Minispは結構前に作ったので、細かいことを忘れていて、なかなか苦労した。ただ、そのおかげで、作った当時の思い込み・誤解がクリアされて居て、再度考え・調査して作ったので「ちゃんと」できた。けれど、プログラム自体は ぐちゃぐちゃだ。綺麗にしたいが、やっぱり面倒だ。
また、以前書いたことで、現行のSpotifyアプリは旧版に比べてDbusの動作がおかしい(特に、再生開始や一時停止のイベントが来ない)というのは、僕のプログラムの問題による誤解で、若干の動作の変化はあるものの、Spotifyアプリに問題は なかった。
結局、現行版対応時の手抜き以外に、元からの問題(一部のDbusイベントを捨ててしまう)があり、それが現行版で顕著になったようだ。
経緯・詳細
Minispを現行のSpotifyアプリに対応させた時にDbus(正確にはMPRIS)の動作仕様が変わったと思い込んで以下の対処をしたが、正しくなかった。アプリの動作の変化以外に僕の誤り(Dbusイベントのフィルタがキツ過ぎたなど)があった。
- Dbusイベントのフォーマットが違う。 → △ デコード処理を変更し、情報が足りない場合はSpotifyのAPIで取るようにした。
- → イベントのフィルタがキツ過ぎて落としていたのと、イベント書式がNuvola Player(以前のもの, 今は不明)に近いことが分かった(単に、イベント内の情報の順序が旧版と違っているだけかも)ので、その処理を改良・追加した。
- Dbusのデータの解釈を ちゃんとすれば※ こういう問題は起こらないのだが、なかなか難しくて手を抜いたので、こういう羽目になっている。
- ※Dbusのデータフォーマット(JSONに似ているが、違う)の解釈をするコマンドなどが ありそうだと思って検索したが、見付からなかった。
- 再生開始や一時停止のイベントが来ない。 → × 定期的(1.5秒)にSpotifyのAPIやDbus(修正初期)で状態を取得するようにした。
- 新版で出なくなったと思い込んでいた。
- → 実はイベントが出る(フィルタがキツ過ぎて落としていた)ので、それを利用することにして定期的に状態をチェックする必要が なくった。
- APIを使っていた時(修正前)は、下のシークとともに数秒ごとに呼び出していたので、API呼び出し回数が激増した(この作業をするまで気付かなかった)。 (→ グラフ: 左側)
- API呼び出しは無料だが(頻度の制限はある)、無駄に実行するのは良くない。
- シークがDbusでは取れない。 → × SpotifyのAPIを使って(無理やり)取るようにした。
- → 実はイベントが出るので、取れるようになった(プロパティでも取れる)。今は、曲が変わる時だけAPI呼び出しをするようにできたので、回数は激減した。定期的な再生位置の較正はローカル(d-busだけ)で出来るようになった。
なお、誤りに気付く前はSpotifyアプリのログファイルからイベントを取ることも考えたが、不要になった。
ログを使うほうが簡単・確実ではあるが、書式が いつ変わるか分からないので、良くない。
それから、そもそもの問題(スリープからの復帰後にMinispがハングすることがある)の原因は分からないので直接の対処は していないものの、再発していない。※ ただ、おそらく、頻繁にAPI呼び出しをしていたため、たまたま呼び出し中にスリープした場合、復帰後しばらくは それが終わらないためではないかと推測している。
※2週間以上様子を見ているが、まだ問題が起こっていない。
効果・おまけ
上記修正前後のSpotify API実行回数の変化のグラフを示す。
- Spotify API実行回数の変化: 再生状態(player)
- 同、曲とアーティスト情報(tracks, artists)
修正前は、気付かずに再生状態の取得(player)を一日に3万回くらいも実行していた※のが、0になった。曲とアーティスト情報の取得(tracks, artists)は、修正・動作確認中は増えたものの、以降は元々と同様の妥当な回数(= 1日の曲の再生回数)に落ち着いている。
※こんなに頻繁アクセスして良くエラーにならなかったと逆に感心した。ただ、たまにアルバム画像や曲情報の表示が遅いことがあったのは、実行頻度制限のためだったかと推測している。
それから、現行のSpotifyアプリには謎がある。: 曲の再生開始後、数回シークイベントが来るが、その位置がふらつく(前後する)のだ。※ なぜ、再生しているだけなのにシークイベントが来るのかもも分からないが、再生処理の状態(通信も?)で較正しているのだろうか? その較正の結果でふらつくのかと推測している。
※現行と書いたものの、実際には旧版からあったのかも知れず、そのふらつき(少なくとも、連続して複数のイベントが出るのは分かっていた気がする)が嫌で、Minispではシークイベントを捨ててしまっていて、そのために必要なイベントも捨てたりユーザのシークが検出できずに苦労し、処理が複雑化したりAPI呼び出しが多くなっていた。
なぜ、こんなことに気付き気にしたかと言うと、Minispの再生位置のバー(→ 参照: ジャケット画像下の灰色の部分)の位置を決めるのにアプリからのシークイベントも使って居るため、そのふらつきでバーもふらつくからである。まあ、ふらつくと言っても1秒程度なので注視して居ない限り分からず、僕はそんな面倒なことは しないので、気分の問題である。
- Minispのウインドウ: 再生位置のバーはジャケット画像下の灰色
- MinispとSpotifyアプリの再生位置が合っている様子 (再生中に それぞれの位置を気にせずキャプチャした)
- Spotifyアプリのリストと再生位置部で曲の長さが異なることがある。: ピンクの下線部
細かく書くと、バーは曲の再生開始後、Spotifyアプリとは独立に定期的に(約0.7秒ごと)動かしている。が、それだと時間が経つとアプリとズレる*ので、時々(数十秒ごと)、アプリの再生位置を取得して較正している。 (→ 参照: 再生位置が合っている様子) その較正に アプリから来るシークイベントも使って居る。
*ズレると言っても、アプリとMinispを同時に注視する(やっぱり、そんな面倒なことは しない)か、曲の最後でなければ分からないので、これも気分の問題である。
気分の問題と言えば、そもそも再生位置なんて分かる必要はないので、この動くバー自体が無用のものなのだが、技術的に おもしろそうなので付けた。
とはいえ、僕は「この曲が終わったら*しよう」とかいうことが多く、その目安には使えるから、全くの無駄でもなさそうだ。
もう一個のおまけ: 本当に現行Spotifyアプリの問題: 曲によっては、アプリ内のリストでの長さと再生位置表示での長さが異なる。 (→ 参照: ピンクの下線部) 秒未満の部分の丸めの問題だと思う(Minispでも起こった)。まさに気分の問題で何の実害もないので、全然問題視していない。単に詰めが甘いと思っただけだ。
まとめ的なもの
結局、手抜きは良くないが、いつも正しくやっていたら時間や手間が掛かり過ぎるので、
「ちゃんとする価値・必要性のあるものか」、「テキトーにやって あとで問題が出た場合、どういう影響が出るか」、「問題が起こる頻度は どのくらいか」、「その対処にどのくらい苦労するか・手間が掛かるか」
(あるいは、天使の声と悪魔の声の どちらに従うかw)
のような判断は必要で、その判断を しないと・誤ると今回のようなことになる。だから、手抜き自体が悪いのでなく、テキトーに手抜きすることが問題なのだろう。
(と、いかにも もっともらしいことを書いたw)