• webui-plus開発/サポート(webui-plus development/support)

    @sunatomo さま
    Scrobbleできることを確認しました。
    これでCantataを使用せずともympdでlast.fmにScrobbleできるようになりました。
    ありがとうございました。

  • @kens さま
    無事使えて何よりです。
    先にも書きましたが、デバッグにお付き合いさせて誠に恐れ入ります。


    さて、昨日(正確には本日)配信しましたが、Scrobble設定方法を一部変更します。
    (既に現行の仕組でセッションキーを取得済みの方は今のキーで継続してお使い頂けます。)

    「事前になぜ調べなかったのか?」との指摘は受けますが、
    Tokenとブラウザによる認証を省いて「username」・「password」をプラグインのフォームに入力し
    "auth.getMobileSession"でセッションキーを受信する仕様にいたします。
    これならば「Get Session」ボタン1発だけでセッションキー生成を行えるので、
    わかりやすいし、last.fmとの通信も1回で済みます。

    次回のリリースは現状のソースコードの無駄な部分の削ぎ落とし等が終わる見通しの5日あたりにしようと思います。

  • webuiでのバグについて

    寝る前にちょっと聞いていた際にとあるバグが判明しましたので、
    周知です(次回のリリース時にはFixします)

    バグの詳細:
     再生キュー内に同一曲名(綴りが完全一致)が連続した場合、楽曲の情報が更新されない。
     (曲名が完全一致したが、アーティスト・アルバムが異なる場合です)
     気づいた原因は手元のライブラリに「Fly Me To The Moon」が3曲あり聴き比べをしたところ、
     情報が更新されないことがあり「あれ?」となってでした。

    原因:
     再生しないときに楽曲情報を表示させないように改修した際、
     楽曲情報の更新を省略するように処理を追加したのですが、
     その際に上記の状況では更新しない仕様にしてしまいました。

    対策:
     楽曲名・アーティスト名・アルバム名のどれか一つでも一致しない場合は
     情報更新するように処理を修正いたします。

    ご不便おかけしますが、よろしくお願いします。

  • 2020-12-06版の配信について

    内容としては2020-11-27版とほぼ変わりありません。

    予告通り、scrobbleのためのセッションキー取得方法を、ID・パスワードを入力して頂き、問い合わせ1回にしています。
    (以前のトークン型でセッションキーを取得済みの方はそのままお使いください。)

    また、楽曲切り替わり時の情報更新がされないバグも修正しております。

    また、通知としてscrobbleの情報とセッションキーの取得を止めました。
    (webuiプラグインが手狭になってきたため、次バージョンではlast.fm関連設定プラグインとして機能を切り出ししようかと思います。)

    1点だけ、現在の時点で既存のバグがあります。
    現象:
    キュー内のアルバムを削除し、つぎのアルバムの局がいきなり再生状態になった際に、その局はscrobble操作されない。

    例えばAとBというアルバムをキューに登録していて、
    A内の楽曲を再生中にBが聞きたくなりAをまるごと削除した場合、
    楽曲再生はBの1トラック目から始まりますがNowPlayingとScrobbleは伝送されません。

    恐らく、シャッフル再生なども含めて内部フラグの立て方に問題が有ると思いますので、
    もう少し時間をかけて修正させて頂きます。

  • 次期リリースの対応事項について

    Scrobbleの挙動に関する不具合を先に対応いたしますが、
    その先の機能実装について以下の通り目標を作りました。
    (正直今まで、あまり自分が使っていなかった機能+手を入れると
    ちょっと時間がかかりそうだったため、後回しにしていました。)

    • プレイリスト向け機能の拡充
      標準機能でプレイリストの追加は可能ですが、削除・編集については未対応なためこのあたりに手を入れるつもりです。
      最低限、プレイリストのファイルダウンロードと削除のためのインターフェースは用意したいと思います。

    • キュー向け機能の拡充
      「可能であれば」の条件付きになりますが、そろそろ考えてみても良いかなと。
      実はympd本体側ではwebuiからのキュー内楽曲の移動用電文は既に実装ずみですが、webui側の画面+機能実装が結構難航しそうで手を付けていませんでした。

    どちらにせよ、私個人的なプライオリティとしては以下の順で進めていく予定ですが、年末年始向けて上記2点を少しは進捗させたいなと思います。

    現時点の個人的なプライオリティ(上から順に)
     1.「サポート」の「基本操作」ドキュメント拡充
     2.開発済みソースコードのリポジトリ戻し作業
     3.webuiでの不具合対応
     4.次期リリース向けのソフトウェア改良

  • AoEのあたり、動きが活発化していますね。
    私の手元にはPi4は現用機しか無いため、当面はスレッドを追いかけるだけになってしまいますね。
    (もしかしたら、将来的には現行のスタンドアローン構成は要らなくなるかも?)

    さて、プレイリスト関連ですが、手を動かす前に方向性について考えてみました。
    この方針で開発を進めていきたいと思います。
    とりあえず、「SAVE QUEUE」プラグインへ機能追加するつもりです。

    • プレイリストファイルのダウンロード方法
      プレイリストファイルはライブラリとは別のディレクトリに有るため、通常のwebuiの設定ではアクセス出来ません。
      (webuiのドキュメントルートがmpdのライブラリに指定されているため)
      組込Webサーバのmongooseのサンプルソースコードを見てみたところ、
      mg_send_file で直接パスを指定すればダウンロードは可能のようです。
      ということで、「ファイル指定後ボタンクリックでダウンロード」という形になるのではないかなぁと。

    • プレイリストファイルの削除方法
      /usr/local/bin/ympd_event.shでコマンドを実行するか、
      Cのpopenで直接実行する方法のどちらかで実装予定です。
      こちらも「ファイル指定後ボタンクリックで削除」という操作系になるのではと。

    • プレイリストファイルのアップロード方法
      既にRAMディスクにファイルをアップロードする仕組はありますので、
      これを一部改変して対応はできそうですね。
      ↑上記2つの対応後にしたいと思いますが...

    • おまけ(組み込みWebサーバの変更の可能性)
      今まで名前は何度か私の方で出していましたが、webui(ympdのsymphonic-mpd専用版)では、
      mongooseという組込向けWebサーバを利用しています。
      ただし元々のympdが長らく開発が止まっているせいもあり、
      mongoose自体もv5.6というかなり古いバージョンのものが使用されています。
      mongoose自体は既にv6が最新版なのですが、
      v6になった時点で従来の関数とは構成がガラッと変わっているためそのまま移植が出来ない状況で「そのまま使い続けるしかないかな」と思っていました。
      実は、今日になってcivetwebというフォークプロジェクトを見つけることが出来ました。
      civetwebの方は現在も開発が続いているようですので、
      こちらが適用出来るかの確認はやってみようかと思います。
      (かなり改変が必要そうなら、あっさり降りるかもしれませんが...)

  • 現状のソースコードでのリリースについて
    以下の作業を行っており、テスト版としては行けそうな感じですが、
    今年の最終リリースとしては27日を予定したいと思います。

    機能は以下の通り
    ・プレイリストのダウンロード
     SAVE QUEUEにボタンを用意します。
     /var/lib/mpd/playlists配下のプレイリストを一覧から選択し、ボタンを押す形になります。

    ・プレイリストの削除
     ダウンロードとほぼ同じです。
    (現状用意していませんが、ボタン押し下げ後ダイアログを表示して確認してから削除するようにします。)

    ・last.fm関連プラグインの追加
     WebUIプラグインから分離しました。

    ・Dateタグへの対応
     rootからタグ直接表示させる項目としてDateタグに対応させました。
     また、SearchプラグインでもDateを選択した場合は楽曲のDateタグの検索が可能になります。

    ・mpd接続関連での最終fixへの布石
     主に再生に入ろうとした際などにmpdサーバとympd間の接続が落ちることがあるため、
     現状で調べた限りの対応を行っています。
     もし、これでも解決しない場合は以下の対応を行って見たいと思います。
     ①当方開発環境でのmpdデバッグ情報出力での動作検証
     ②ympd内部で「エラー解除されるまでループを回す」処理を行っている
      場所があるため、これの解除
     ③他のlibmpdclientを使用しているアプリと同じ処理への変更)

  • ちょっとwebui(ympd)のソースコードとmympd(ympdのフォーク)を比べて見たところ、
    ステータスの取得方法が異なることがわかりました。
    ympd:
    内蔵httpサーバ(mongoose)のポーリングでおおよそ1秒単位でmpdのステータスを確認(正確にはポーリング内部のtime()で前回実行時と時刻が異なる場合のみ実行)

    mympd:
    mpdのidleで状態変化があった場合に処理をさせる(idleはループで回し、状態変化がなければ何もしない)

    ループの回し方としてはmympdのidleのほうが適切に処理出来そうなため、
    次の改良としてこのあたりに手を入れてみようかと思います。

  • 2020/12/27 版のwebui-plus配信について

    以下の改良、機能拡張を行いました。

    • lastfm機能のweb-uiプラグインから分離
      2020-12-27_lastfm.jpg
      新たに/opt/plugins/15-lastfmフォルダに必要ファイルは保存しています。
      機能に変更はありません。

    • list itemプレイリスト向け機能の実装(第1弾)
      「SAVE QUEUE」プラグインへの機能追加として、プレイリストのダウンロードと削除に対応させました。
      2020-12-27_save-queue.jpg
      上半分は従来通り、現在キューに格納された楽曲群をプレイリストとして保存します。
      下半分が今回拡張した機能にあります。
      テキストボックスから現在/var/lib/mpd/playlistsフォルダに格納されているプレイリストファイルを選択し、「download」・「delete」ボタンを押すと指定の操作を行えます。
      編集済みファイルのアップロードは後程対応予定です。
      ※本機能でSAVE QUEUEのプラグインのうちform.htmlを書き換えしています。
      もし、webui-plusを止めて元に戻す際は、当該ファイルを不可逆的に書き換えするため、事前に以下の通りバックアップを取ることをお勧めします。

    #バックアップ
    cd /opt/plugins/12-save_queue
    cp form.html form.html.org
    
    #レストア
    cd /opt/plugins/12-save_queue
    cp form.html.org form.html
    
    • Dateタグへの対応
      予告通り/root/でブラウズした際にタグ検索してリストを表示する項目として
      Dateタグに対応させました。
      なお、Dateタグの内容については全く編集していません。
      (id3タグのv2.4に対応していている方は日付で入力されているでしょうし、
      それ以前のタグ管理の場合は恐らくリリース年しか入っていないと思います)

    • ympd本体でのmpdとの通信部分安定化のための改良
      webブラウザからの電文を分類して処理する部分において、
      「mpdサーバとの通信が必要なもの」・「mpdサーバーと通信状態だと出来ないもの」・「mpdとの通信状態に関係ないもの」の3パターンに処理を明確化
      「mpdサーバとの通信が必要なもの」について、mpdとのコマンド処理でエラーが出た場合のログ記録を強化
      同上において、mpdとのコマンド処理終了による変数・接続解除忘れがないように再確認

    なお、年末年始の宿題としては、以下の3つのうちどれかはちょっとやってみたいと思います。

    • mpdとの接続状態確認ループのイベント化
      mympdと同じようなmpdからのイベントを待って処理を行う方法に変更。

    • mpdが吐くログ上でのエラーをympdが受ける方法の確認
      これはラジオ等の再生時音声が鳴らない場合など「ympdは正常にmpdに電文を送れたとしてもmpd内部でエラーが発生したことはわからない」対策になります。
      ↑
      例えば、ffmpegプラグインやcurlプラグインでエラーがあり、mpd.logには記録は残りますが、ympd〜mpd間通信は正常終了であるため現状の仕組では検知出来ない。

    • mongooseのフォークプロジェクト、tibetwebの対応
      現段階での調査ではtibetwebのフォーク時期はmongooseのv3の頃らしく、ympdで使用しているv5.6の構文とは違う部分があるため
      すぐには出来なさそう。

  • 2020/12/28版のwebui-plus配信について

    年末年始の宿題、
    「mpd.logに記録されるエラーログをympd(webブラウザ側)で受信する」ことが一応出来ましたので昨日の配信版を差替いたします。

    どうやったかというと、libmpdclientが提供するmpd_status_get_error()でエラーメッセージを受信するだけで済みました。

    (libmpdclientはAPIドキュメントは確かにあるのですが、
    引数と戻り値以外の関数の詳細説明が少なく試行錯誤が多すぎる...)

    ffmpegのエラーというか、コーデック変換時のcautionは表示されるかはまだ不明ですが、
    最低限インターネットラジオの再生に失敗したことは分かるようになりますので「十分アリ」だと個人的には感じています。

  • バグ修正版の配信について

    AoEのArch Linux版差替対応を行っていて、SYSTEMプラグインでのNAS設定関連の不具合が見つかりましたので、
    差替版を配信いたしました。

    ご迷惑をおかけし申し訳ございませんでした。

    なお、当該版では「SAVE QUEUE」プラグインの最終版(プレイリストのアップロード対応)も同梱しています。
    2020-12-31_save-queue-final.jpg

    プレイリスト関連はこれで対応完了という形になります。

  • 次のネタについて

    全体的に全て手が入るまではちょっと時間がかかりそうですが、
    以下の事項を行うことにしました。
    「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)はバージョンも近いのでデータベースも互換性があるはずです。

  • @hiroget9 さま
    前から自由に作ることは出来ましたが、
    現状の仕組だとちょっと面倒な部分があるため、
    これを簡略化して使って頂ければと思いました。
    (というか、今までドキュメント用意できていなかったのはこちらの手落ちですね。)

    @パパリウス さま
    レスありがとうございます。
    Arch側の内部構造を解析できる余裕まだなかったので、
    これから調べてみようと思っていました。

  • @パパリウス さん、さっそくありがとうございます。
    謎が解けました(^_-)-☆

  • @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の低負荷化により音質に優位性が確認出来た」かを皆さんにもお試しいただきたいと思いますので、もう少しお待ちくださいませ。