foobar2000コンポーネント作成、進捗

曲(トラック)再生完了時のイベントを補足することができるようになった。

static_api_ptr_t()->set_stop_after_current(true);

これを新規トラックの再生開始時に実行するよう記述しておくと、そのトラック再生終了時に、on_stop()が、EOFで呼び出されるようになる。しかし、そこで再生が止まってしまい、プレイリストの再生を続ける方法がわからない。plbayback_controlへのポインタを上記コードで取得し、つかっているので、それで再生させれば、と思ったが、再生終了後にはplaybackのクラス(要するに、実装しているトラック再生開始などのイベントを補足するクラス)のオブジェクトが破棄されるようなコメントがSDKのソースから読めたので、それで実行時エラーになるようだ。

しかたないので、on_timeでポーリングする、今までのスタイルでトラック終了の補足は実装してしまうことにした。様子見になるが、仕方ない。

で、これを調査していたら、foobar2000 SDKに、HTTP CLIENTのクラスが存在することを知った。POSTも使えるようだ。Last.fm用のコンポーネントも利用しているみたいだ。質問が英語のコミュニティに上がっていて、サンプルコード(質問者のコード)もあったので、通信はこっちを使うことにした。CALLBACKを使わなくて良くなったのですっきりした。

.NETのライブラリのようにすっきり書けるようになったが、パラメータのエスケープは、パラメータ名は自前で、パラメータはクラスでやってくれるようだ。パラメータを自分のエスケープコードを通して送ったらエラーになった。逆にパラメータ名が配列になっているので、[]を%5B, %5Dにしてハードコードしているのだが、それはそのまま残しておいて、このクラスを使ってもエラーにならずにPHPのサーバスクリプトが正常に動作している。よくわからない動きだ。

再生完了時に再生回数と最後に再生した日時を、その情報をサーバに送信して正常終了したあとで送信日時をSQLiteを更新しているのだが、同一レコードを続けて更新するので、今までのコードではクリティカルなタイミングになるようで、送信日時の更新でエラーになることが結構あった。それも偶発的で、発生するときとしない時があるという、見えない現象で一番困る状況だった。

しかし、今回の通信部分の改修で、通信がコールバックでは無くなったため、再生完了→再生情報DB更新→自宅サーバと通信→自宅サーバとの通信履歴DB更新と処理が完全にシーケンシャルになったため、エラーにならなくなった。といっても「今のところ」としか言えないのであるが。

iPodの部分は修正をしていないので、同じ修正を加えればいいはずだが、リアルタイムに再生しているときは1トラック固定なのにたいして、iPodの時は何トラック来るかわからない。今、iTunes用に動かしているものは50トラック単位で処理しているのでそれに合わせる予定だが。

また、iTunes用のものはスマートプレイリストに対するポーリングでやっているため、エラー処理が要らない。通信エラーになった場合、次のポーリングでまとめて処理される作りになっているためである。iTunesで再生したものとiPodで再生したものの区別さえしていない。そのかわり、最後に再生した一回分しかサーバに送れないという制限がついているが。

現状、通信エラーになった場合の処理、バッファリングやリトライを計算に入れていないので、そこをどう作るか、という問題が残る。配布しなければ、サーバが落ちているか、LANケーブルが抜ける、程度しか考えられないが不意のアップデート&リブート程度のタイミングは耐えられる作りにはしたい。正常系が動くようになったら考えよう。

コメント