Chienomi

Local Web Media PlayerとDLsite Voice Utilsを組み合わる

開発::util

先日公開したLocal Web Media Playerはリリース後毎日改修を行い、私にとって非常に使いやすいソフトウェアになった。

音楽は私はほとんどプレイリストで聴き、ときどきアルバム単位で聴く感じなので、m3uプレイリストをサポートしたことで普通に使えるようになった。

そしてもうひとつの大きな目的だったのが、音声作品の再生だ。

DLsite Voice Utilsは2023年5月にリリースして以来、しっかりと実用しつつ改善を続けているソフトウェアだ。 このソフトウェアはアップデートによりカスタムURLスキーマハンドラによってフォルダを開くという方式を取るようになり、DLsite Voice Utilsを使って検索し、そこからNemoを開いてmpvで再生するという流れではあるのだが、これはその方式上(DLsite Voice Utilsが静的なHTMLファイルであるというのも含めて)、ライブラリを置くホストと再生するホストが同一である必要がある。

私はUSBエンクロージャに入れたSSDにコレクションを収録しているので、他のPCでも再生しようと思えばできるのだが、ファイルパスの対応関係が異なると駄目なのでそんなにやりやすいわけでもない。

何より問題は音楽再生同様、布団でチルしながら聴きたい問題だ。 ラップトップを起動してBluetoothイヤフォンで、とかすることもあるのだけど、だいぶ面倒。

だがブラウジングと再生パートをLWMPでできればそのあたりが解決する。 もちろん、LWMP単体でも_VoiceByActressディレクトリを共有すれば(lighttpdはシンボリックリンクを解決するので)だいたいいい感じに使えるのだけど、目的の作品を探すのは結構大変なので、やはりDLsite Voice Utilsを使いたい。

DLsite Voice Utilsは静的なHTMLファイルで機能することを前提にしており、またこの機能を失いたくないのでコンセプトに齟齬があるが、機能的にはしっかりと補完関係にある。

そこでDLsite Voice Utilsを少し改修してLWMPと連携することを目標とする。

障害はなにか

まずデータベースにはローカルシステム上のファイルパスが保存されており、ベースとなるHTMLは静的に(file://プロトコルで)開かれ、画像も同様にfile://プロトコルでアクセスし、作品はdvlfol://カスタムURLによって開くようになっている。

これは単にプロトコルを変換するだけでなく、パス自体もHTTPサーバーのドキュメントルート起点に変更する必要がある。 そして、作品ディレクトリに関しては、LWMPで配信されているサーバーアドレスにする必要がある。

また、HTMLファイルはローカルで開くのとサーバーが配信するので少し違いがあるので、サーバーで配信するための対応も必要になる。 サーバーアドレスは不定なので、これも設定可能にしなくてはいけない。

また、現在のDLsite Voice Utilsはスマートフォンからのアクセスをかんがえておらず、かなり巨大な表を表示する方式なので、ここもなんとかする必要がある。

プロトコルとサーバーアドレスの変換

location.hrefからスキーマを含むアドレスが得られるため、

location.href.slice(0,4).toLowerCase() === "http"

で判定できる。

どのみちLWMPのサーバーアドレスは任意に設定できるために、エンドポイントを設定するための箇所が必要になる。

config.js

var voice_library_dir, lwmp_server
if (location.href.slice(0, 4).toLowerCase() === "http") {
  voice_library_dir = "/path/to/dlsite/_Voice"
  lwmp_server = "http://foohost.local:8800/"
}

となっており、index.htmlがHTTPで配信されているときだけ設定を適用できる。

app.js側ではlwmp_serverが定義されてるかどうかで動作を変えれば良い。 このために、今までinnerHTMLでサボっていた部分をちゃんとDOMを使う形に変更した。

表をたたむ

もともと表の列にはcolgroupが設定されていたけれど、colに対してdisplay: none;をあててもcol要素が消えるだけでううまく機能しない。

colに対してvisibility: collapse;が当たるようにすると機能する。

が、注意点として、Firefox Androidはこれがあまりうまくいかない。

vasibility: collapse;についてMDNでは

<table> の行、列、列グループ、行グループでは、行や列が不可視になり、 (表の列や行に display: none が適用された場合のように) 占めていた領域も除去されます。しかし、他の行や列の寸法は、不可視になった行や列のセルが存在するときのように計算されます。この値は表全体の幅や高さを強制的に再計算することなく、すばやく行や列を不可視にすることができます。

となっている。 この文章から列がcollapseになったときに表全体の寸法がどうなるのかは不明瞭であるように見える。

これは、Google Chromeでは表の幅から取り除かれるが、Firefox for Androidの場合は表自体からは取り除かれるものの、表の空間としては残る。 つまり、表の右側に何もない空間が発生する。 表の幅を制限した場合は、表示されている分だけが適用される。

PC版のFirefoxだと空間も消えるので、バグだと思うのだが。

組み合わせる

実際に組み合わせて使ってみた。

そのホスト自体で聴いているときに関しては、Nemo Actionsを使って任意のカバー画像を表示しつつ聴けることと、Nemo Actionsを使ってのデータベース編集があることから、基本的に普通にファイルで開いたほうが良い。

一方、LWMPで再生することは基本的に支障がない。 Firefoxだと音声がブチブチになってしまうことがあり、Vivaldiだとバックグラウンド再生を有効にしていても再生が止まってしまう問題があるため、いささかうまくいかないが、これはウェブブラウザ側の問題だと言える。

カバー画像はそのディレクトリにcover.jpgを配置していれば見られる(Lighttpdだからシンボリックリンクでも良い)が、正直スマホで聴きたいときは基本的に寝落ちモードだから画面を見ていないので気にならない。

mDNSの解決が遅いシステムだとかなりもっさり動作になる。 これは基本的にPCの話なので、/etc/hostsに書いておくことで改善する。もしくは、Zeroconf名を使わずアドレスで打っても良い。 ちなみに、Android14だとmDNSは使えるものの、Android6では使えない。 いつから使えるようになったのかは不明。

割と最小の改修で満足できる結果を得られたと思う。