バグ修正版の配信について
AoEのArch Linux版差替対応を行っていて、SYSTEMプラグインでのNAS設定関連の不具合が見つかりましたので、
差替版を配信いたしました。
ご迷惑をおかけし申し訳ございませんでした。
なお、当該版では「SAVE QUEUE」プラグインの最終版(プレイリストのアップロード対応)も同梱しています。
プレイリスト関連はこれで対応完了という形になります。
webui-plus開発/サポート(webui-plus development/support)
AoEのArch Linux版差替対応を行っていて、SYSTEMプラグインでのNAS設定関連の不具合が見つかりましたので、
差替版を配信いたしました。
ご迷惑をおかけし申し訳ございませんでした。
なお、当該版では「SAVE QUEUE」プラグインの最終版(プレイリストのアップロード対応)も同梱しています。
プレイリスト関連はこれで対応完了という形になります。
全体的に全て手が入るまではちょっと時間がかかりそうですが、
以下の事項を行うことにしました。
「RaspberryPiでのympdデーモンのmpd通信タイミング調整」
現状のympdではmpdとの通信状態確認と各端末へのステータス送信を以下の手順で実行しています。
1)ympdが起動すると無限ループで200ミリ秒(オプションの-iで指定した数値が200のため)でポーリングから覚めます。
2)ポーリングから覚めた際にtimeで現在時刻を取得し、前に処理を行った時間と差がある場合のみ3)の処理を行います(差がない場合はそのままスリープ)
→という訳で「大体1秒単位で以下の処理に進む」。
3)ympdとmpdサーバとの通信状態を確認します。
「切断済」の場合は接続処理を行い、「切断中」と「再接続要」の場合は「切断済」にステータスを変更します。
「接続中」の場合は4)の処理を行います。
「エラー」の場合は何もしません。
4)mpdサーバ内部でのステータスを取得し、ympdに接続中の全端末にその内容を電文で通知します。
電文には以下の項目が含まれています。
現在のmpdの状態(再生中・停止中・一時停止中)
音量数値
Singleモードの状態
Consumeモードの状態
Repeatモードの状態
Randomモードの状態
再生曲のID(mpd内部ID)
再生曲の経過時間
再生曲の総時間
(その他ビットレート等)
各利用者のWebブラウザではこの電文を受信した際にその情報を元に
カウンターや各モードのフラグの見え方を変化させているというわけです。
ちょっと見では「これで問題ない」ように見えますが(現状このように動いていますし)、
実は以下の改善が必要な事項があります。
①各端末でのカウンター表示が1秒単位では無いことがある
これは楽曲再生のタイミングとステータス表示のタイミングがズレるためです。
現状ympdから送信されるステータスはympdが起動して上記のステータス送信のループを回すタイミングに基づきます。
利用者が再生ボタンを押したタイミングとympdでのステータス送信タイミングは当然同期していませんし、
何らかの原因で2)の処理タイミングがズレた場合はステータス送信がずれ込みます。
②ympdとmpd間の通信の維持方法について
今までは約1秒に1度ステータス通信のためにmpdに状態取得コマンドを送って通信を維持させる仕様でした(ちなみにタイムアウトは10秒)が、
他の類似プロジェクトやドキュメントを見る限り、
「idleコマンドを送って常時は何もしないが接続を維持させ、状態変化を受けた際にidleを解除させて処理させる」のが本来の処理方法だと判明しました。
(この方法だともしかしたらympdのCPU使用率を軽減出来ないかという皮算用もあります)
という訳で、今後の改良としては以下の事項を実施します
①各端末での再生中楽曲のカウンター表示タイミング変更
従来の電文によるステータスでカウンターを変更するのではなく、
楽曲変更時(再生開始時)にカウンターを初期化させる。
あとは端末内のタイマー処理でカウンターが変化
②各端末へのステータス送信のタイミング変更
(「定時送信」→「イベント単位で非同期化」)
これに伴い、各スイッチ操作後のレスポンスも改善出来る可能性があります。
③ympd〜mpd間通信のidleによる接続維持
②・③は恐らく一緒に書換えしないとダメでしょう。
次のリリース目標としては①は新年の早い段階で、②・③はちょっと時間を頂くかもしれません。
(先行で③の試作を行ったところ、コマンドを受け付けなくなった。)
先に次のネタと書いてあるmpdのidle対応についてですが、
手は動かし始めましたが結構難航しそうなので、
現実逃避でドキュメントを整備しようと考えていました。
その中で、「カラーテーマ」のプラグインについてまとまった文章を作ろうと思ったのですが、もしかしたら機能拡充の必要があるかとおもい、今回やってみようかなと思った次第です。
上記のうち、①・②は具体的なドキュメントを纏めれば良いのですが、
③については現状ちょっと面倒くさい手順
(スタイルシートを作成・編集してプラグインディレクトリに複写+プラグインhtmlファイルのリスト部分を書換)
を踏む必要があるため、機能拡充が必要と判断したわけです。
追加予定の機能について
最低限以下の機能を追加します。
①カラーテーマ用のスタイルシートを規定ディレクトリにファイルアップロード
②規定ディレクトリからカラーテーマ用のスタイルシートファイルを抽出してプラグインのリストに表示
これにより、新しいカラーテーマのスタイルシートをwebuiからの操作だけで追加・選択まで一元的に管理出来るようになります。
実装後の展開について
上記「カラーテーマ」用プラグインのドキュメントをほぼ同時に公開します(早ければ3日までには機能実装前の現状で先にドキュメントを纏めるかも)ので、
その後に当該スレッドの下に「私の作ったカラーテーマ」を投稿頂けると良いのかなぁと思います。
@sunatomo さん
カラーテーマの機能が拡充されると楽しみがふえそうですね。好みのカラーテーマを作れるということでしょうか。
話は変わりますが、ライブラリの管理方法がはSMPDとArch Linuxでは異なるのでしょうか?
SMPDではtag_cacheだったと思うのですが、Arch Linuxの方はこれが見当たらないのでmpd.dbになったのかなと。
ライブラリのバックアップとレストアがArch Linuxでは反映されていないようなので、調べていて???になっています。
@hiroget9 さん
mpdのデータベース名は/etc/mpd.confで変更できます。
db_file "/var/lib/mpd/mpd.db"
これを以下のように編集していただけば、tag_cacheというファイル名にすることができます。
db_file "/var/lib/mpd/tag_cache"
smpd v1.0.xのmpd(0.22)とArch Linuxのmpd(0.22.3)はバージョンも近いのでデータベースも互換性があるはずです。
@パパリウス さん、さっそくありがとうございます。
謎が解けました(^_-)-☆
@sunatomo さん
私も複雑な方法より簡略な方が使いやすいと思います。
@パパリウス さん
mpdのデータベース名を変更してみました。
webuiのリストアでsmpdのmpdのデータベースを使えるようになりました。互換性ありますね。
これでsnpdとArch Linuxでデータベースを共用できますね。
ありがとうございました。
少し前にcantataでライブラリのアップができないという件がありましたが、原因はここだったのでしょうね。
現状の進捗について
「ympdデーモンのmpd通信タイミング調整」を先週末にちょっと集中的に行っていました。
現状はデバッグメッセージてんこ盛りですがwebブラウザからの操作電文に基づいて応答を返すところまでは進みました。
解析の結果として、既存のympd内部では以下の処理が行われていることがわかりました。
メインループでmongoose(組込webサーバ)のポーリング制御(スリープ解除後にwebサーバで受信したhttpプロトコルのリクエスト処理を行い、またスリープに移行)を行っています。
ポーリング間隔は標準では200ミリ秒(これはympd.serviceのパラメータで指定された値)です。
webブラウザからwebsocketプロトコル経由で送信される電文はmongooseのコールバック関数より呼ばれ、
処理後にwebsocketプロトコルで返信します。
mpdとの通信状態はメインループで1秒以上の時間差があった場合のみ確認します。
このときに通信が切れていた場合は再接続、致命的なエラーが発生していた場合は接続しません。
また、確認の際にmpdに接続状態ならば、mpdの状態を接続中の全クライアント(webブラウザ)に通知します。
ympdサーバがmpdとの接続を維持するためには、以下のどちらかで運用する必要があります。
常にタイムアウト時間より短い間隔で通信を継続する
(現状のympdがこのやり方。約1秒単位でステータスを問い合わせする)
mpdに対してidle命令を送って通信状態はサーバに維持させ、必要に応じてクライアントからidle解除の命令を送って電文処理を行い、処理終了後にまたidle命令でidle状態に戻す。
後者の場合、idle解除の命令のキックは以下の3つになります。
webブラウザからwebcoketでmpd関連の命令が届いた場合
実はidle状態の場合、mpdに対して「idle解除」以外の電文を送信しても処理はされません。
このため、webブラウザから受信したmpd関連の電文は一度FIFOバッファに保存し、バッファにデータがあることを検知した段階でidle解除を行って電文を処理させる必要がありました。
ympdサーバから各端末のwebブラウザにステータスを送る場合
webブラウザ側でステータスを受信しないと、再生ボタンなどは機能しません。
また、ステータスにはカウンターなどの情報があるため、再生中にプログレスバーが動作しません
mpdから何らかのステータス変更を検知した場合
idle状態にした際にフラグを立てることにより、そのフラグ条件に一致した際には通知するようになっています。
現状のフラグ条件では「データベースの更新」・「キューの状態変更」・「再生状況の変更」・「リピート・コンシューム・ランダムなどのオプションの状態変更」などが受信できるようです。
このときの通知があるかどうかはpoll関数で受けるため、ポーリングをループ処理する必要があります。
ということはidleを使う場合はmpd処理部分を別スレッド化してループを回す必要があるということでした。
とりあえず手元のバージョンではmpd処理部分を50ミリ秒のpoll関数でループさせ、カウントが20回になった際はステータスをwebブラウザに送るように仕立てました。
ただし、カウンタについては前より値のバラツキ(2秒単位で更新する確立が高くなった)があること、
webブラウザからの電文を一旦FIFOバッファ格納するためにブラウザ操作→表示完了までのラグ(僅かな遅延)が見られるのが気になります。
カウンタのバラツキについては「ステータスを送るタイミングを従来の1秒間隔から0.5秒程度に増やす」か、「カウンタ値をミリ秒単位で取得して誤差を吸収させる」方法のどちらかで対応してみようと思います。
表示のラグについてはもう少し何とかしたいと思います。
最終的には今回開発したidle対応版で「ympd〜mpd間の通信の安定性」と「ympdの低負荷化により音質に優位性が確認出来た」かを皆さんにもお試しいただきたいと思いますので、もう少しお待ちくださいませ。
UIのラグは私の実力では解消出来ませんでしたので元に戻すという結論に至りました。
利用しているクライアント端末の性能によって変化はあるかもしれませんが、
私のメイン使用環境であるPCベースの場合、既存のympdでは「ボタンクリックに対してラグがなく結果を返してくれます」。
これに対し試作版(mpd_idleを有効にするためにmpd対応処理を別スレッドにした場合)は、
「ボタンクリック後にその応答が返るまでにわずかにラグが出ます」。
恐らく、「元々idle版でずっと使用していた場合は違和感にを覚えない程度」だと思うくらいなのですが、webuiを今までお使い頂いた方にとっては恐らく違和感が顕著に感じると想定されますので、「現状でのリリースは難しい」と判断しました。
以下の点で改良を行っています。
カウンター取得関数の変更
現行では同カウンタ値をmpd_status_get_elapsed_time()関数で秒単位取得しています。
この関数は現在のlibmpdclientのドキュメントでは「deplicated」扱いであることがわかったので、
mpd_status_get_elapsed_ms()関数でミリ秒単位で取得するようにしました。
カウンター取得タイミングの適切化
従来はwhile無限ループ内で毎回time関数で現在時刻を取って前回のステータス取得時と1秒以上のラグがある場合にステータス取得を行う様に記述されていました。
今回、pthreadのタイマーでステータス取得の関数を呼び出す仕様に変更しました。
正直、ここまでやっても端末側で得られるカウンター数値はバラツキがあるのが現状です。
特に通常のカウンター間隔を確認したのですが、何故か約740ミリ秒、
たまにその2倍が計測されるのため「なぜ?」というのが正直な感想ですね...
ちなみにpthreadのタイマー実装後に「ステータス取得関数の処理終了時にstderrにログ書込をさせ」、
jounalでタイムスタンプを確認した限りでは1秒間隔(誤差おおよそ1ミリ秒以下)で当該関数が間違いなく動作しているのですが...
個人的には最終手段になりますが「再生中に取得したカウンタ値が前回の値と同じならば+1する」という処理を追加するしか無いかもしれません。
(これで問題ないかのテストは必要ですが)
再生カウンタの対応を行っていて、一つ大事なことに気づきました。
カウンタ左横の「プログレスバー」に関する問題です。
現状プログレスバーでは最小値0〜最大値100の間を表示+取得可能な仕様のため、
楽曲のトータル時間が60秒を超えた場合、毎秒更新されなくなります。
(例えば10分=600秒の曲だと6秒に1回しかプログレスバーが動かない)。
また、上記のせいでドラッグ時の値が1%単位しか調整出来ません。
(10分の曲だと6秒単位のシークしか出来ない。)
プログレスバーの追加ライブラリ(bootstrap-slider)の最新仕様では
最大値に100以外の値を定義することが可能になっていますので、
ライブラリの差替後は毎秒更新+シークの秒単位実現を可能にしたいと思います。
現状対応した内容について配信させて頂きます。
①変更点
昨日の書き込みに記載したプログレスバーの修正は次回に対応します。
(差替予定の新バージョンのライブラリと現バージョンのライブラリの相違が多く、簡単な入換が無理だったため。)
また、AoE向けのArchの実行ファイル生成はこれからの作業となります。
まだ、Arch向けのパッケージ作成方法はわからないので、とりあえずZIPで実行ファイルとプラグインの差替ファイル提供となります。)