• プラグイン実験室

    今後はプラグインはこのスレッドで投稿していきます。

    mpd.logを見るためのプラグインをコチラで提供します。
    作り方

    • /home/pi/plugin の下にshowlogという名前のディレクトリを以下のコマンドで作って下さい。
    mkdir /home/pi/plugin/showlog
    
    • /home/pi/plugin/showlog 配下にshowlog.sh、showlog_form.htmlの2つのファイルを作成します(←リンクは動作しません。書き込んだら勝手に埋め込まれた(^_^;))。
      showlog.shは以下の通り(2019-09-29 引数の検査対応のため、小変更しました)
    #!/bin/bash
    
    target_mpd=/var/run/mpd/mpd.log
    out=/var/lib/mpd/music/plugins/showlog/showlog_out.html
    lines=20
    expr "$1" + 1 > /dev/null 2>&1
    if [ $? -lt 2 ]; then
      if [ $1 -eq 1 ]; then
        lines=1
      fi
      if [ $1 -gt 100 ]; then
        lines=100
      else
        lines=$1
      fi
    fi
    
    echo "<p>output lines:" $lines "</p>" > $out
    echo "<pre style='font-size:10px;'>" >> $out
    tail -n $lines $target_mpd >> $out
    echo "</pre>" >> $out
    
    exit 0
    

    showlog_form.htmlは以下の通り(2019-09-29 表示行数1-100行にしたため、小変更)

    <form>
       <label class="control-label">specify the rows of log(1-100 defaut is 20)</label>
       <input class="form-control" type="text" name="param" value="20" />
    </form>
    

    各ファイルはエディタのnanoを使うと便利だと思います。また、showlog.shは以下のコマンドで実行権限を付与して下さい。

    sudo chmod +x showlog.sh
    
    • .plugin.jsonへの追記
      .plugin.jsonの末尾に以下の記述を追加して下さい。追加する際は最下行の
      ]}とその1つ上の行の}の間になります。
      {
        "menu"   :"show mpd.log",
        "author" :"sunatomo",
        "active" :"yes",
        "icon"   :"file",
        "form"   :"/plugins/showlog/showlog_form.html",
        "command":"/home/pi/plugins/showlog/showlog.sh",
        "output" :"/plugins/showlog/showlog_out.html",
        "success":"",
        "error"  :"error!"
      }
    

    上記の挿入部前の}行は必ず},に直してください。これはjsonファイルの記述書式なのですが、[]内部に配列として格納されており、各配列要素はカンマで区切られます。
    (例えばアルファベットのa~eを配列化すると[a,b,c,d,e]になります。)
    今回は配列の末尾に新しい要素が増えるため以前の最後の要素の末尾にカンマが必要ということになります。(なお参考ですが{}内部はオブジェクトという別なデータの塊であることを示します。)

    • ympdのサービスを再起動し、動作を確認してくだい。
      ympdサービスの再起動は以下のコマンドで行います。
    sudo systemctl restart ympd.service
    

    Webのメニューの最下行に「show mpd.log」と表示されたら、これを選択して下さい。
    まず、フォーム文が表示されますのでここで希望の数字を入れます(この数字はログとして出力する
    行数を指定するものです。)
    その後、指定行数を最大としてmpd.logが表示されます。

    • このプラグインの使用目的
      symphonic-mpdで対応しないファイル形式や、無効なラジオストリームのURLを登録した場合などmpd.logにエラーが記録される場合があります。この結果を確認するためです。
      (ympdなどのフロントエンドではエラーが起こっても再生されないだけのため)。
  • ラジオストリームを保存するプラグイン
     インストール済みイメージではかなりの高音質なラジオステーションが既に登録済みですが、
    自分でインターネットラジオを探してお気に入りの局を追加したい場合もあると思います。
     通常は/var/lib/mpd/music/RADIOフォルダ内に自分でplsファイルを書き出す必要がありますが、
    このプラグインを使用すると「ラジオ局名」と「ストリームURL」の2つを入力することで自動的にplsファイルを生成します。

    作り方:

    • /home/pi/pluginの下にadd_radioフォルダを作成する。

    • /home/pi/plugin/add_radio配下にadd_radio.html, add_radio.shを作成する。各ファイルは以下の通り。
      add_radio.html
      (2019-11-15
      フォーム内の各テキストボックスは確実にパラメータを渡すことが出来るようにした。
      また、テキストボックス選択時、色が変わるようにした。)

    <title>add New Radio Stream</title>
    <script type="text/javascript">
      $('#nm, #url')
        .focusin(function(f) {
          $(this).css('background-color', '#ffc');
        })
        .focusout(function(f) {
          $(this).css('background-color', '');
          ku();
        });
      function ku() {
        $('#pm').val($('#nm').val() + "|" + $('#url').val());
      }
    </script>
    <form>
      <label class="control-label">Radio Station Name</label><br/>
      <input type="text" id="nm" onkeyup="ku();" /><br/>
      <label class="control-label">stream URL </label><br/>
      <input type="text" id="url" onkeyup="ku();" size="40" /><br/>
      <input type="hidden" id="pm" name="param" />
    </form>
    

    add_radio.sh

    #!/bin/bash
    
    title=`echo $1 | cut -d '|' -f 1`
    url=`echo $1 | cut -d '|' -f 2`
    
    out=/var/lib/mpd/music/RADIO/"${title}".pls
    
    if [ -n "$title" ] && [ -n "$url" ]; then
      if [ -e "${out}" ]; then
        exit 1
      fi
    
      echo "[playlist]" > "${out}"
      echo "NumberOfEntries=1" >> "${out}"
      echo "File1=${url}" >> "${out}"
      echo "Title1=${title}" >> "${out}"
      echo "Length1=-1" >> "${out}"
      echo "Version=2" >> "${out}"
    
      chown pi.pi "${out}"
      mpc update RADIO
    fi
    
    exit 0
    
    • /home/pi/plugin/.plugin.jsonに以下の項目を追記
      {
        "menu"   :"ADD RADIO STREAM",
        "author" :"sunatomo",
        "active" :"yes",
        "icon"   :"import",
        "form"   :"/plugins/add_radio/add_radio.html",
        "command":"/home/pi/plugins/add_radio/add_radio.sh",
        "output" :"",
        "success":"Success!",
        "error"  :"error!"
      }
    

    このやり方で複数のフォームパラメータをシェルスクリプトに渡すことが可能になりました(sampling_rate_Setting内のos_setting.htmlが参考になりました。
    ただし、ラジオボタンと異なり、inputによるテキスト入力の場合はonChangeでJavaScriptを走らせるのはあまりよくないかもしれません。)
    また、symphonic-mpdのプラグインではシェルスクリプトにスペース混じりで文字を送っても正常にパラメータとして認識することが分かりました。

    後は今回の入力されたテキストの判定部を入れて完成まで持っていきます。

    使い方:
    プラグインの「ADD RADIO STREAM」を選択します。
    ダイアログで2つの文字列入力部が表示されますので、はじめにラジオ局名、次にそのラジオ局のURLを入れて下さい。
    両方の文字入力を済ませ「OK」ボタンを押すと、入力されたパラメータでsymphonic-mpdのラジオプリセットに追加登録されます。

  • Spotifydの設定プラグイン
    @ジャイアン 様のところでやっているインストール方法のPDF化の内容を見ていて思い当たったのですが、
    NASの設定はWebで行うことが出来るのに、Spotifydの設定はエディタで編集が必要というところがちょっと不便かなぁと思いまして、
    プラグインを作ってみましたので提供します。

    提供するもの:
    /home/pi/plugin/.plugin.json (向けの設定)

      {
        "menu"   :"Spotifyd SETTINGS",
        "active" :"yes",
        "icon"   :"cog",
        "form"   :"/plugins/demo/spotify_form.html",
        "command":"/home/pi/plugins/demo/edit_spotify.sh",
        "output" :"",
        "success":"success!",
        "error"  :"error!"
      } ,
    

    /home/pi/plugins/demo/spotify_form.html
    (プラグインのフォーム用HTMLファイル)

    <title>set Spotifyd user and password</title>
    <script type="text/javascript">
      $.getJSON( './.spotify.json', function(d) {
        $('#us').val(d.username);
        $('#pw').val(d.password);
        $('#pm').val(d.username + "|" + d.password);
      });
    
      $('#us, #pw')
        .focusin(function(f) {
          $(this).css('background-color', '#ffc');
        })
        .focusout(function(f) {
          $(this).css('background-color', '');
          ku();
        });
    
      function ku() {
        $('#pm').val($('#us').val() + "|" + $('#pw').val());
      }
    </script>
    Set Sptifyd user and password
    <form>
      <label class="control-label">username</label><br/>
      <input type="text" id="us" onkeyup="ku();"/><br/>
      <label class="control-label">password</label><br/>
      <input type="text" id="pw" onkeyup="ku();"/><br/>
      <input type="hidden" id="pm" name="param"/>
    </form>
    

    /home/pi/plugins/demo/edit_spotify.sh
    (/etc/spotifyd.conf書換シェルスクリプト)

    #!/bin/bash
    
    us=`echo $1 | cut -d '|' -f 1`
    pw=`echo $1 | cut -d '|' -f 2`
    
    out=/etc/spotifyd.conf
    
    if [ -n "${us}" ] && [ -n "${pw}" ]; then
      #/usr/local/sbin/rmtrw.sh 2
    
      sed -i "/^username/c\username = ${us}" ${out}
      sed -i "/^password/c\password = ${pw}" ${out}
      sync
    
      systemctl restart spotifyd.service
    
      #/usr/local/sbin/rmtro.sh 2
    
      exit 0
    else
      exit 1
    fi
    

    /home/pi/configs/spotify_pre.sh
    (spotifyd.serviceの起動前に実行するシェルスクリプト。
    フォーム文で現在の設定からusernameとpasswordを取得するために/var/lib/mpd/musicに.spotify.jsonというファイルを生成します。)

    #!/bin/sh
    
    out=/var/lib/mpd/music/.spotify.json
    
    us=`cat /etc/spotifyd.conf |grep username|tr -d ' '|cut -d '=' -f 2`
    pw=`cat /etc/spotifyd.conf |grep password|tr -d ' '|cut -d '=' -f 2`
    
    if [ -n "$us" ] && [ -n "$pw" ]; then
      #/usr/local/sbin/rmtrw.sh 2
      echo "{\"username\":\"${us}\",\"password\":\"${pw}\"}" > $out
      sync
      #/usr/local/sbin/rmtro.sh 2
      exit 0
    else
      exit 1
    fi
    

    /etc/systemd/system/spotifyd.service
    (spotifydのsystemdでのサービス設定ファイル。spotify_pre.shを起動する設定を追加しています。
    具体的には[Service]項のExecStart(これが実際にSpotifydを起動する命令が記載されている。
    の前にExecStartPreから始まる1行を追加しただけです。)

    [Unit]
    Description=spotify-connect daemon
    Wants=sound.target
    After=sound.target
    Requires=avahi-daemon.service
    After=avahi-daemon.service
    Wants=network-online.target
    After=network.target network-online.target rc-local.service
    
    [Service]
    EnvironmentFile=/etc/environment
    ExecStartPre=/home/pi/configs/spotify_pre.sh >/dev/null 2>&1
    ExecStart=/usr/local/bin/spotifyd -c /etc/spotifyd.conf --no-daemon
    
    LimitRTPRIO=99
    LimitMEMLOCK=infinity
    CPUSchedulingPolicy=fifo
    CPUSchedulingPriority=99
    CPUAffinity=2
    
    # none, realtime, best-effort, idle
    IOSchedulingClass=realtime
    
    # 0(highest) - 7(lowest)
    IOSchedulingPriority=0
    
    Restart=no
    
    [Install]
    WantedBy=default.target
    

    インストール方法:
    .plugin.json向けの設定はいつもの通り書換をお願いします。
    (個人的にはuser.jsの直後がお薦め)
    シェルスクリプトは実行権限を与えるのをお忘れなく。
    インストール後に以下のコマンドで一度spotifydを再起動して下さい。

    sudo systemctl restart spotifyd.service
    

    注意:
    /etc/spotfyd.confのusername・passwordをエディタで直接編集した場合、その後にプラグインのフォームで表示されるusernameとpasswordは実際の設定ファイルと異なるものになります(spotifydが再起動すれば追従します)。
    また、SpotifyやApplePlayで再生中はMPD・ympdは停止しますので、一旦再生を停止してympdが起動してからusername・passwordの書換を行って下さい。

  • @sunatomo さん

    spotifydの設定は、UIが欲しいなと思っていました。

    このプラグインもSDイメージに同梱させていただけると幸いです。


    プラグインで設定ファイルを読み込むのがとても大変ですよね。

    事前にjsonに書き出しておくなどの工夫が必要で、書き出しタイミングの検討など難しいポイントもあります。

    sunatomoさんの書き込みを眺めながら思ったのですが、設定ファイルの読み込み・書き込みを受け付けるAPIをympdに設けてしまえば、プラグインの実装が格段に楽になりそうですよね。
    ちょっと考えてみたいと思います。:relaxed:

  • すいません。勝手ながらプラグイン関連のため2つほどメッセージをコチラのスレッドに移動しました。
    @パパリウス さま
    私の知っている限りではJavascriptでテキストファイルを読み込んで解析できる方法としてはJSONファイルしか無いので、
    本来の設定ファイル以外に中間JSONを置いて対応させました。
    おっしゃるとおり書出しタイミングや本当の設定ファイルを手動編集した場合の中間JSONファイルの追従性など難しいところはあると思いますのでAPIで対応頂けると非常に助かります。

  • @sunatomo さん

    次のバージョンに同梱予定のympdをアップします。

    ympd_v093b.tar.gz

    以下を差し替えてください。
    /usr/local/bin/ympd
    /home/pi/misc/ympd_event.sh

    デモ用のプラグインを2種用意しています。
    spotifyd.html
    config.txt.html
    を/home/pi/configs/demo/にコピーしてください。

    プラグイン定義も同梱しています。

    
     {
        "menu"   :"I2S DAC",
        "active" :"yes",
        "icon"   :"edit",
        "form"   :"/plugins/demo/config.txt.html",
        "success":"",
        "error"  :""    
      },
      {
        "menu"   :"Spotify",
        "author" :"sunatomo",
        "active" :"yes",
        "icon"   :"edit",
        "form"   :"/plugins/demo/spotifyd.html",
        "success":"",
        "error"  :""    
      },
    

    デモ)config.txt.html

    <form>
      <label class="control-label">dtoverlay</label><br/>
      <input class="config" type="text" uri="/boot/config.txt" key="dtoverlay" style="width:100%;" /><br/>
    </form>
    

    フォームのhtmlを作成するポイントは、<input>に

    • class="config" を指定すること
    • uriに設定ファイルのパスを指定すること
    • keyにパラメータ名を指定すること

    の3点です。

    このような指定がされた<input>があれば、Web UIで当該プラグインを開いたときに自動で設定値を読み取りにいきます。

    また、OKボタンを押したら自動で設定値を更新しにいきます。

    設定ファイルの単純な読み書きだけであれば、javascriptを用意する必要はありません。


    注意事項としては、config.txt内のdtoverlayのように1ファイル中に同じパラメータが複数回出現するものがあります。

    この場合、最初の1つだけを読み書きする仕様にしています。


    ここからは混み入ったプラグインを作成する場合の手引きです

    読み書きを自分で制御したい場合は、class="config" を付けないでください。

    ympdの改修内容ですが、
    http://smpd.local/r/boot/config.txt?dtoverlay
    にアクセスすると、/boot/config.txtのdtverlayを読み取ってブラウザに返すようにしました。

    先頭のrはreadモードです。

    jsonではなくテキストで返す仕様ですので、getJSONではなくjqueryのgetメソッドを使って、第4引数に"html"を指定すると扱いやすいです。


    書き込みについては、
    http://smpd.local/w/boot/config.txt?dtoverlay=rpi-dac
    という風に、パラメータ名に続けて=設定値を指定してやると、設定値の書き込みをします。

    先頭のwはwriteモードです。


    javascriptでの書き込み例

    $.get('/w/boot/config.txt'), {overlay : $('#i2s').val()});
    

    javascriptでの読み込み例

    $.get('/w/boot/config.txt'), {overlay=''},
      function(data){$('#i2s').val(data);}, "html");
    

    読み込みにもwモードが使えます。クエリーストリングにキー名だけ指定し、値を空にしておけば読み取り動作になります。

  • @パパリウス さま
    早速のympdでの対応、本当にありがとうございます。
    実際に使ってみました。

    ympd_event.shの値を読み込むsedの正規表現、コチラのほうが良いと思います。
    (というか、私のユーザ名だと頭1文字かけるのがわかったので)

    cat "$2" | sed -n "s/^[ \f\n\r\t]*$3[ \f\n\r\t]*[=][ \f\n\r\t]*//p" | head -n1 | sed -e "s/\"//g"
    

    オリジナルでは空白検出を[ \s]と記載していましたが[ \f\n\r\t]に変更しました(\f\n\rは要らないかもしれませんが)。

    また、config.txt.htmlを色気を出して手入力+リストに対応させようと思いましたが、今の所うまく動いていません。
    一応参考に現状のHTML貼り付けします。

    <script>
      //$(funtion() {
      //  $('.config').attr('list', 'keyword');
      //});
    </script>
    <form>
      <label class="control-label">dtoverlay</label><br/>
      <input class="config" type="text" list="scard" uri="/boot/config.txt" key="dtoverlay" style="width:100%;" autocomplete="off" /><br/>
      <datalist id="scard">
        <option value="sabreberry32"></option>
        <option value="i-sabre-k2m"></option>
        <option value="allo-boss-dac-pcm512x-audio"></option>
        <option value="allo-digione"></option>
        <option value="allo-piano-dac-plus-pcm512x-audio"></option>
        <option value="allo-piano-dac-pcm512x-audio"></option>
        <option value="rpi-dac"></option>
        <option value="dionaudio-loco"></option>
        <option value="hifiberry-dac"></option>
        <option value="hifiberry-dacplus"></option>
        <option value="hifiberry-digi"></option>
        <option value="hifiberry-digi-pro"></option>
        <option value="hifiberry-amp"></option>
        <option value="iqaudio-dac"></option>
        <option value="iqaudio-dacplus"></option>
        <option value="iqaudio-digi-wm8804-audio"></option>
        <option value="justboom-dac"></option>
        <option value="justboom-digi"></option>
        <option value="rra-digidac1-wm8741-audio"></option>
      </datalist>
    </form>
    

    実現したい機能としては
    「現状の設定をテキストボックスに表示、
    datalistにデフォルトのサウンドカードドライバ名があるのでこれを選択してテキストボックスに反映可能、
    リストにない場合はテキストボックスに直接入力可能」
    ということです。

    現状ではconfig.txtの結果は表示されていますがリストは空になってしまいます。
    コメントアウトしているJavascriptを有効化するとせっかく調べたconfig.txtの結果がテキストボックスから消えてしまう。
    自分でも調査しますが、もしお分かりの方おりましたらお知恵をお貸し下さい。

  • @sunatomo さん

    抽出ロジックの改善案をいただきどうもありがとうございます。:smile:

    mpd.confのように、スペース区切りでダブルクォーテーションで括られている場合にうまく抽出できませんでした。
    (例えば、 direct_io "yes" が抽出できない)

    そちらで問題が発生したのはどのようなパラメータ・値でしょうか?
    こちらのテストケースに追加して検証したいと思います。

    リストでの選択について、こちらでも考えてみます。


    リスト選択の件ですが、
    最初はlistを指定せずに後から<script>で設定すると意図通りに動きました。(理由はよく分かりませんが、なにかタイミングの問題かと思います。)

    <input id="i2s" class="config" type="text" uri="/boot/config.txt" key="dtoverlay" style="width:100%;" autocomplete="off" /><br/>
    
    <script>
      $('#i2s').attr('list', 'scard');
    </script>
    
  • @パパリウス さま
    大変申し訳ありません。[=]後ろの*、検証の際に消していました。
    (/boot/config.txtと/etc/spotify.confばかり見て、=で繋いでいない設定ファイルがないと思いこんでいた)

    cat "$2" | sed -n "s/^[ \t]*$3[ \t]*[=]*[ \t]*//p" | head -n1 | sed -e "s/\"//g"
    

    これで、/etc/mpd.conf含めて確認済みです。

  • @sunatomo さん

    おお!完璧に動作します。ありがとうございます。:smile:

    読み取り・書き込みの両方を直したものをアップしておきます。
    ympd_event.sh


    これで「イコール区切り」「スペース区切り」「ダブルクォーテーション括り」のパターンは対応できましたね。

    config.txt
    mpd.conf
    spotifyd.conf
    や同様のフォーマットの設定ファイルなら大丈夫そうです。

    (.plugin.jsonやspotify-connect.confのように、フォーマットが大きく異なるファイルはダメですね。)

  • @パパリウス さま
    リスト選択の件、予定通りの動作を確認いたしました。
    最終版の画像とソースコードを貼り付けします。
    (サウンドカード名からドライバ名の変換まで対応したい場合は今回提供するHTMLを元にやってみて下さい。
    ただし、パパリウス様が提供した最新ビルドのympdでしか動作しません。
    恐らく次バージョンで差替されると想定されますが...)
    i2s_dialog.png

    <script>
      $('#i2s').attr('list', 'scard');
    </script>
    <form>
      <label class="control-label">dtoverlay</label><br/>
      <input id="i2s" class="config" type="text" uri="/boot/config.txt" key="dtoverlay" style="width:100%;" autocomplete="off"/><br/>
      <datalist id="scard">
        <option value="sabreberry32"></option>
        <option value="i-sabre-k2m"></option>
        <option value="allo-boss-dac-pcm512x-audio"></option>
        <option value="allo-digione"></option>
        <option value="allo-piano-dac-plus-pcm512x-audio"></option>
        <option value="allo-piano-dac-pcm512x-audio"></option>
        <option value="rpi-dac"></option>
        <option value="dionaudio-loco"></option>
        <option value="hifiberry-dac"></option>
        <option value="hifiberry-dacplus"></option>
        <option value="hifiberry-digi"></option>
        <option value="hifiberry-digi-pro"></option>
        <option value="hifiberry-amp"></option>
        <option value="iqaudio-dac"></option>
        <option value="iqaudio-dacplus"></option>
        <option value="iqaudio-digi-wm8804-audio"></option>
        <option value="justboom-dac"></option>
        <option value="justboom-digi"></option>
        <option value="rra-digidac1-wm8741-audio"></option>
      </datalist>
    </form>
    

    操作感を説明すると以下の通り。
    ・事前にconfig.txtに登録済みのドライバ名がテキストボックスに自動的に表示されます。
    ・テキストボックスのドライバ名を全消去した場合、symphonic-mpdがサポートする全ドライバを
     リストとして表示できます(画面イメージはこの状態)。
    ・テキストボックスに入力したドライバ名が一部合致したものがリストに抽出されます。
    ・ドライバ名の登録漏れや将来の追加対応時はdatalistタグ内のオプションに記述すれば対応できます。

  • @sunatomo さん

    どうもありがとうございます!
    v0.2からずっと欲しかった機能です:laughing:


    プラグインの有効/無効を切り替えるプラグインを試作中です。
    使わない機能はメニューから消しておきたいですからね:relieved:

    07B65C37-4107-4666-BCC1-09ADB051DF0B.png

  • @パパリウス さま

    プラグインの有効/無効を切り替えるプラグインを試作中です。

    これ、本当に良いですね。というか、自分で作ろうかなぁって考えていました:relaxed:
    あとはプラグインを1つのファイルにアーカイブ化して、インストール可能な仕組みがあれば
    ほぼ完成では無いでしょうか?
    (例えば、「プラグインを保存する専用フォルダを用意して、再起動時にそのフォルダにアーカイブファイルが存在すれば自動的に解凍→インストール」という方法ならばシェルスクリプトのみで対応出来ますよね。
    当然プラグインのアーカイブ時の書式は決めなければなりませんが。)

    あと、config.txtですがドライバへのオプション渡し(スレーブモード指定など)は、
    取りあえずはテキストボックスに手動で追記頂くことにしましょうか。
    (裏でinnomaker-hifi-dac-hatのスレッドを見ていて思い出しました。)

  • @sunatomo さん

    そうそう。
    私もパッケージマネージャ的な機能を盛り込めたらいいなぁと思っています:wink:


    手動で追記で問題ないと思います。
    ,slaveをつけたりするのは、実験するときだけですし:relieved:

    dtoverlayのオプションはカンマ区切りですね。
    いまの実装だとカンマがURLエンコードされて %2C で保存されちゃいますので、ympd_event.sh側で%2Cをカンマに逆変換すればいいですかね。:sweat:

  • こちらの記述を参考にして、ympd_event.shの方をもう少し変更してみました。
    ・設定ファイルから必要な設定を読み込む部分をparam関数として外出し
    ・上記のurldecode関数を実装しw指定の場合はパラメータをURLデコードした
     (私が動作確認した限りではカンマも正常に取得出来ています)
    ympd_event-.20191118.sh

  • @sunatomo さん

    ympd_event.shの修正、どうもありがとうございます。
    次のバージョンに取り込ませていただこうと思います。


    プラグイン実験室でsunatomoさんとやりとりさせていただき、久しぶりにympdのソースを見直す機会を得ました。

    むくむくとインスピレーションも湧いてきまして、この勢いでプラグイン機構の実装を全面的に見直そうと思っています。

    これまでのプラグインとの互換性は失いますが、

    • インストールやon/off切り替えはsshでの作業が不要
    • 作るのが楽
    • メンテナンスが楽
    • 配布が楽

    なものを目指したいと思います。

    ympdを弄るのはとても楽しいです:relieved:

  • 結局そこまで凝る必要は無かったのですが、やってしまいました。
    config.txt.png
    機能としては以下の通り。
    ・SupportのI2S DAC対応表を取り込みし、Javascriptの配列化しています。
     (将来的に対応カードが判明した場合は配列にリストを加えれば対応出来ます。
     また、配列をJSONファイルにすれば外部読み込み対応可能です)
    ・テキストボックスにカーネルドライバ名を直接入力もしくはリストから選択すると、
     当該ドライバ名と同ドライバで動作するデバイス名称が下のCardに表で表示されます。
     (dtoverlayにカンマ付きでオプションを指定していてもカード名で検索するので追従します。)
    あとはチップセットも対応表の配列には入っていますので、
    これまで分類して表示できればさらに良いかも(とりあえず、今回はここまでということで)。
    config.txt.20191120.html.zip

    <script>
      var i2sc=[
    {"d":"Sabreberry32","c":"ES9018Q2C","k":"sabreberry32"},
    {"d":"Audiophonics ES9018 DAC","c":"ES9018K2M","k":"i-sabre-k2m"},
    {"d":"Allo Boss DAC","c":"Burr Brown PCM5122","k":"allo-boss-dac-pcm512x-audio"},
    {"d":"Allo DigiOne","c":"Cirrus Logic WM8805","k":"allo-digione"},
    {"d":"Allo MiniBoss DAC","c":"Burr Brown PCM5122","k":"allo-boss-dac-pcm512x-audio"},
    {"d":"Allo Piano 2.1 Hi-Fi DAC","c":"Burr Brown PCM5142","k":"allo-piano-dac-plus-pcm512x-audio"},
    {"d":"Allo Piano Hi-Fi DAC","c":"Burr Brown PCM5122","k":"allo-piano-dac-pcm512x-audio"},
    {"d":"Audiophonics ES9023 DAC","c":"ESS Sabre ES9023","k":"hifiberry-dac"},
    {"d":"Audiophonics ES9023 DAC LTE","c":"ESS Sabre ES9023","k":"hifiberry-dac"},
    {"d":"Audiophonics ES9023 DAC TXCO","c":"ESS Sabre ES9023","k":"hifiberry-dac"},
    {"d":"Audiophonics ES9028 DAC","c":"ESS Sabre ES9028Q2M","k":"rpi-dac"},
    {"d":"Audiophonics PCM5102 DAC","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"Audiophonics PCM5122 DAC","c":"Burr Brown PCM5122","k":"hifiberry-dacplus"},
    {"d":"Audiophonics TDA1387 DAC","c":"Philips TDA1387","k":"hifiberry-dac"},
    {"d":"Buffalo I","c":"ESS Sabre ES9008","k":"rpi-dac"},
    {"d":"Buffalo II/IIIse","c":"ESS Sabre ES9018","k":"rpi-dac"},
    {"d":"DDDAC1794 NOS","c":"Burr Brown PCM1794","k":"rpi-dac"},
    {"d":"DIAL-DAC","c":"Burr Brown PCM1793","k":"rpi-dac"},
    {"d":"DIYINHK ES9023 DAC","c":"ESS Sabre ES9023","k":"hifiberry-dac"},
    {"d":"Denafrips Pontus R2R DAC (I2S)","c":"Altera MAX II CPLD","k":"rpi-dac"},
    {"d":"Dion Audio LOCO","c":"PCM5242 DAC","k":"dionaudio-loco"},
    {"d":"Durio Sound PRO","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"G2 Labs BerryNOS","c":"Philips TDA1543","k":"hifiberry-dac"},
    {"d":"G2 Labs BerryNOS","c":" RedPhilips TDA1543","k":"hifiberry-dac"},
    {"d":"HIFI DAC","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"HIFI DAC+","c":"Burr Brown PCM5122","k":"hifiberry-dacplus"},
    {"d":"HIFI Digi","c":"Wolfson WM8804G","k":"hifiberry-digi"},
    {"d":"HIFI Digi+","c":"Wolfson WM8804G","k":"hifiberry-digi"},
    {"d":"HiFiBerry Amp(Amp+)","c":"Burr Brown TAS5713","k":"hifiberry-amp"},
    {"d":"HiFiBerry DAC","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"HiFiBerry DAC+","c":"Burr Brown PCM5122","k":"hifiberry-dacplus"},
    {"d":"HiFiBerry DAC+ Light","c":"ESS Sabre ES9023","k":"hifiberry-dac"},
    {"d":"HiFiBerry DAC+ Pro","c":"Burr Brown PCM5122","k":"hifiberry-dacplus"},
    {"d":"HiFiBerry Digi(Digi+)","c":"Cirrus Logic WM8804","k":"hifiberry-digi"},
    {"d":"HiFiBerry Digi+ Pro","c":"Cirrus Logic WM8804","k":"hifiberry-digi-pro"},
    {"d":"Hifimediy ES9023","c":"ESS Sabre ES9023","k":"hifiberry-dac"},
    {"d":"IQaudIO Pi-AMP+","c":"Burr Brown TPA3118","k":"iqaudio-dacplus"},
    {"d":"IQaudIO Pi-DAC","c":"Burr Brown PCM5122","k":"iqaudio-dac"},
    {"d":"IQaudIO Pi-DAC PRO","c":"Burr Brown PCM5242","k":"iqaudio-dacplus"},
    {"d":"IQaudIO Pi-DAC+","c":"Burr Brown PCM5122","k":"iqaudio-dacplus"},
    {"d":"IQaudIO Pi-DACZero","c":"Burr Brown PCM5122","k":"iqaudio-dacplus"},
    {"d":"IQaudIO Pi-Digi+","c":"Wolfson WM8804","k":"iqaudio-digi-wm8804-audio"},
    {"d":"IQaudIO Pi-DigiAMP+","c":"Burr Brown TAS5756","k":"iqaudio-dacplus"},
    {"d":"IanFIFO II","c":"Altera Max II CPLD","k":"hifiberry-dac"},
    {"d":"JustBoom AMP HAT(Zero)","c":"Burr Brown TAS5756","k":"justboom-dac"},
    {"d":"JustBoom DAC HAT(Zero)","c":"Burr Brown PCM5122 (PCM5121)","k":"justboom-dac"},
    {"d":"JustBoom Digi HAT(Zero)","c":"Wolfson WM8804G","k":"justboom-digi"},
    {"d":"Lucid Labs Raspberry Pi DAC","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"Mamboberry HiFi DAC+","c":"ESS Sabre ES9032","k":"hifiberry-dac"},
    {"d":"Mamboberry LS DAC+","c":"ESS Sabre ES9023p","k":"hifiberry-dac"},
    {"d":"Pi2Design 503HTA Hybrid Tube Amp","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"Pimoroni pHAT DAC","c":"Burr Brown PCM5102A","k":"hifiberry-dac"},
    {"d":"PlainAMP","c":"Burr Brown TAS5756","k":"iqaudio-dacplus"},
    {"d":"PlainDAC","c":"Burr Brown PCM5100","k":"hifiberry-dac"},
    {"d":"PlainDAC+","c":"Burr Brown PCM5121","k":"hifiberry-dacplus"},
    {"d":"PlainDSP","c":"Burr Brown PCM5121","k":"hifiberry-dacplus"},
    {"d":"RPi-DAC","c":"Burr Brown PCM1794A","k":"rpi-dac"},
    {"d":"RaspyPlay4","c":"Burr Brown PCM5122","k":"iqaudio-dac"},
    {"d":"Red Rocks Audio DigiDAC1","c":"Wolfson WM8742 (DAC) WM8804 (S/PDIF)","k":"rra-digidac1-wm8741-audio"},
    {"d":"SB32+PRO DoP","c":"ESS Sabre ES9218P","k":"hifiberry-dacplus"},
    {"d":"Soekris DAM1021/1121 (I2S)","c":"FPGA based","k":"rpi-dac"},
    {"d":"Suptronics x400","c":"Burr Brown PCM5122","k":"iqaudio-dacplus"},
    {"d":"Terra-BerryDAC 2","c":"AK4490EQ","k":"hifiberry-dac"}
    ];
    
      var ary1 = [];
      var ary2 = [];
      for (var i = 0, lmt = i2sc.length; i < lmt; i++) {
        ary1.push(i2sc[i].k);
      }
      ary2 = removeArrayDuplicates(ary1);
    
      var scd = document.getElementById('scard');
      for (var i = 0, lmt = ary2.length; i < lmt; i++) {
        var opt = document.createElement("option");
        opt.value = ary2[i];
        scd.appendChild(opt);
        opt = null;
      }
    
      $('#i2s').attr('list', 'scard');
      change();
    
      function removeArrayDuplicates(array) {
        var exist = {}, result = [];
    
        for (var i = 0, l = array.length; i < l; i++) {
          var tmp = array[i];
        
          if (!exist[tmp]) {
            exist[tmp] = true;
            result.push(tmp);
          }
        }
    
        return result;
      }
    
      function change() {
        var flg = 0;
        $('#k').text(' ');
        $('#d').text(' ');
        var sample = $('#i2s').val().split(',');
        for(var i = 0, lmt = i2sc.length; i < lmt; i++) {
          if (sample[0] === i2sc[i].k) {
            if(flg === 0) {
              $('#k').text(i2sc[i].k);
              $('#d').text(i2sc[i].d);
            } else {
              $('#d').text($('#d').text() + ',' + i2sc[i].d);
            }
            flg++;
          }
        }
      }
    </script>
    <form>
      <label class="control-label">dtoverlay</label><br/>
      <input id="i2s" class="config" type="text" uri="/boot/config.txt" key="dtoverlay" style="width:100%;" autocomplete="off" onfocut="change();" onkeyup="change();"/><br/>
      <datalist id="scard">
      </datalist>
    </form>
    <br/>
    <table style="width:100%" border="1">
    <tr><th>Driver</th><th>Card</th></tr>
    <tr><td id="k"> </td><td id="d"> </td></tr>
    </table>
    
  • ラジオストリームをRADIOに追加するプラグイン(V.0.9.3)
    これは以前に掲載したインターネットラジオURLをRADIOフォルダに保存するためのプラグインをv.0.9.3に対応させたものです。
    保存先は/home/pi/plugins/14-add_radioを想定しています。
    SAVE_RADIO.png

    app.json

    {
    	"menu": "SAVE RADIO",
    	"icon": "settings_input_antenna",
    	"note": "add new radio station to RADIO folder"
    }
    

    form.html

    <script type="text/javascript">
      $('#nm')
        .focusout(function(f) {
          $(this).val(ku($(this).val()));
        });
      function ku(v) {
        return  v.replace(/ /g, '_');
      }
    </script>
    <div style="padding:20px;">
      <p>Save Radio Stram URL to RADIO Folder</p>
      <label class="control-label">Radio Station Name</label><br/>
      <input type="text" id="nm" class="run" /><br/>
      <label class="control-label">stream URL</label><br/>
      <input type="text" id="url" class="run" />
    *white space (" ") in "Radio Station Name" string has been replaced to "_"
    </div>
    
    

    run.sh

    #!/bin/bash
    
    ttl=$1
    url=$2
    
    out=/var/lib/mpd/music/RADIO/"${ttl}".pls
    
    /usr/local/sbin/rmtrw.sh 2
    
    if [ -n "$ttl" ] && [ -n "$url" ]; then
      if [ -e "${out}" ]; then
        exit 1
      fi
    
      echo "[playlist]" > "${out}"
      echo "NumberOfEntries=1" >> "${out}"
      echo "File1=${url}" >> "${out}"
      echo "Title1=${ttl}" >> "${out}"
      echo "Length1=-1" >> "${out}"
      echo "Version=2" >> "${out}"
    
      chown pi.pi "${out}"
      mpc -q update RADIO
      sync
    fi
    
    /usr/local/sbin/rmtro.sh 2
    
    exit $retval
    

    インストール方法
    1./home/pi/pluginsに14-add_radioフォルダを作って下さい。
    2.app.json・form.html・run.shをソースコードから複写して下さい。
     (SSHのシェル上でnanoエディタで各ファイルを新規作成で開き、そのままコピペするだけでOK)
    3./home/pi/plugins/attachフォルダにてln -s ../14-add_radio .と入力して下さい。

    使い方
    プラグインの使い方は簡単
    RadioStationNameに保存したいラジオ局の名称を、stream URLにはそのラジオ局のURLを入れてOKを押せば、当該ラジオ局のplsファイルが/var/lib/mpd/music/RADIOに作られるという仕組みです。
    stream URLが正しいものかは確認していませんので事前にADD STREAMで確認して下さい。
    (ADD STREAMは入力したURLをキューに追加します。これで再生出来ればOK)

    ちょっと解説(新しいrun.shへパラメータを渡す際の注意事項)
    v.0.9.3以降で対応するform.htmlですが、class="run"でinput要素を渡す際は
    必ず半角スペースを他のキャラクターで置き換えて下さい
    (ファイル中のJavaScriptは「Radio Station Name」に入力された文字列内の" "を"_"に置き換えするものです)。
    これは現状のWebインターフェース(ympd)ではブラウザのフォーム値をラズパイにパラメータとして渡す際の各パラメータ区切りとして半角スペースを使用しているためです。
    (パラメータ内部に半角スペースが存在するとrun.shが誤解してしまうため)
    どうしても半角スペースを含むパラメータをrun.shに渡したい場合は以下の2つの方法で実現出来ます。
     ①半角スペースを他のキャラクターに置き換えし、run.shの内部処理でそれを戻す
     ②各パラメータ間を別なキャラクターで予め接続した1つの文字列として渡し、run.shの
      内部処理でパラメータを分割する

  • @sunatomo さん

    プラグインの投稿、どうもありがとうございます。

    半角スペースの件、ご指摘ありがとうございます。
    個々のプラグインで対策していただくのは不便ですので、ympd本体側を修正したいと思います。

    v0.9.3からプラグイン作成ルールを刷新しましたが、作りやすさ・メンテナンスのしやすさなど、気付いた点があればおっしゃってください。