有馬総一郎のブログ

(彼氏の事情)

2021年01月24日 01:23:48 JST - 7 minute read - Subsonic

Jpsonicがスキャンしないファイルがある…

Jpsonic、 Free media server for Japanese (Airsonic clone).が2021年から既に更新されいるので、Java 11にして v109.4.0 にしてみた。

Jpsonic v109.4.0

初め、ちゃんと表示されなくて、あれFirefoxだからと、疑ってしまったが…

Jpsonic
Ctrl+F5しろ

The CSS has changed significantly. If the display is incorrect, press Ctrl + F5 to refresh your browser.

私が愚かなだけだった。ガラっと見た目がカッコ良くなった。ログも見易くなった。

Jpsonic
Jpsonic

しかし、曲時間のシークバーのところがやはりおかしい気がする。Chromeだとちゃんと表示される。でも大した問題ではない。

Jpsonic

なのだが…前回 v109.2.0 を試したとおり、全スキャン完了後のファイル数が少ない。内部詳細見てもオールグリーン。一応、ログを見ると

org.jaudiotagger.audio.exceptions.CannotReadException: /mnt/hdd1/Public/Public_Music/VisualArt's - Key Sounds Label/TVアニメーション『Angel Beats!』OP&ED My Soul, Your Beats! - Brave Song/03_My Soul, Your Beats!

とエラーを出しているが、それらはちゃんと読み込まれているし、再生も出来る1

Airsonic

試しに元となった Airsonic v10.6.2 をインストールしてみた。手順はSubsonic, Jpsonicと全く同じ。


追記 2021-01-25
正確には v109.4.0 には表記が無い(抜けてる?)が、 v109.3.0 には Based on airsonic 11.0.0-SNAPSHOT 5c71659 とある。良くよく調べると Releases · airsonic-advanced/airsonic-advanced · GitHubというAirsonicの最新実装版があり、ここをベースにしてるのかな?ただ、 5c71659 のタグを見つけられなかった。

そもそも、 バージョン仕様とアップデート方法 | tesshu.comによると

Jpsonicのクローン元となっているAirsonicのストリームバージョンに対応。偶数がRELEASE、奇数がSNAPSHOT

とあるので安定版を使いたければ、Jpsonicも v108.0.0を使えって話だと思う。ただ、未だに理解しきれないのが、バージョニング規則。

Subsonicフォークポイントまとめ | tesshu.comには、

そのためバージョン10番台がAirsonic、100番台がJpsonicという区分けになります。

とあるし、バージョン規則の例としてもJpsonic105.1.0-RELEASE(based on Airsonic10.5.0-SNAPSHOT eb4c5a0)とある。であれば。v109.3.0もベースにしたAirsonicに合わせてv110.3.0とかに、なるんじゃないの?とか思った。でも、使う側にしてみれば、どうでもいい話だが…

追記ここまで


$ wget https://github.com/airsonic/airsonic/releases/download/v10.6.2/airsonic.war
$ sudo mv ~/airsonic.war /var/lib/tomcat8/webapps/airsonic.war
$ sudo rm -r /var/airsonic/
$ sudo rm -r /var/lib/tomcat8/webapps/airsonic
$ sudo mkdir /var/airsonic
$ sudo mkdir /var/airsonic/playlists
$ sudo mkdir /var/airsonic/transcode
$ sudo ln -s /usr/bin/ffmpeg /var/airsonic/transcode/ffmpeg
$ sudo ln -s /usr/bin/lame /var/airsonic/transcode/lame
$ sudo chown -R tomcat8:tomcat8 /var/airsonic
$ sudo chown -R tomcat8:tomcat8 /var/lib/tomcat8/webapps/airsonic.war
$ sudo vi /etc/apache2/sites-available/airsonic.conf

/etc/apache2/sites-available/airsonic.conf

<Location /airsonic/>
SSLRequireSSL
ProxyPass ajp://localhost:8009/airsonic/
</Location>
$ sudo a2ensite airsonic
$ sudo service tomcat8 start

で試すとちゃんと読み込まれる…なんでだ…

Airsonic

さすがにソースを見比べる気にはならなかったが、ぱっと見ると HSQLDBのバージョンが異なる。Airsonicは 1.8.0 、Jpsonicは 2.5.0 となっている。とはいえ、HSQLDBが2.5にバージョンアップされるのは予定されていたことなので、遅かれ早かれ、将来的に 2.5 にはなるだろう。

Database Version Notes
HyperSQL 1.8 Default for Airsonic 10.x
HyperSQL 2.5 Planned for Airsonic 11.0

Jpsonic
Airsonic

HSQLDBをダウングレードして試す方法が分からなかったので、 Setting up an external database - Airsonicにあるとおり外部DBに接続してみる。

MySQL

Jpsonic用のDBを作る。特にドキュメントに書いてないがNextcloudと同じで良いだろう。

mysql> CREATE USER 'jpsonic_user'@'localhost' IDENTIFIED BY 'password';
mysql> CREATE DATABASE IF NOT EXISTS airsonic;
mysql> -- GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON airsonic.* TO 'jpsonic_user'@'localhost' IDENTIFIED BY 'password';
mysql> GRANT ALL ON airsonic.* TO 'jpsonic_user'@'localhost' WITH GRANT OPTION;
mysql> FLUSH privileges;

GRANT SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, INDEX, ALTER, CREATE TEMPORARY TABLES ON airsonic.* TO 'jpsonic_user'@'localhost' IDENTIFIED BY 'password';で一気にユーザーと権限設定をするやりかたは 8から駄目になったようで以下のようにエラーとなる。

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'identified by 'password'' at line 1

MySQL8.0ではGRANT構文でユーザを作成できない – guro_chanの手帳

そしてJpsonic設定ファイル編集。

var/jpsonic/jpsonic.properties

DatabaseConfigType=embed
DatabaseConfigEmbedDriver=com.mysql.jdbc.Driver
DatabaseConfigEmbedUrl=jdbc:mysql://localhost:3306/airsonic
DatabaseConfigEmbedUsername=airsonic
DatabaseConfigEmbedPassword=password

を追記。

ただ、よくみると Jpsonic を外部DBで使ってみよう (v105.2.1) | tesshu.comにあるとおり、Jpsonicの画面から設定できるんだね。

再起動すると自動で移行が行われるみたいだが…

liquibase.exception.MigrationFailedException: Migration failed for change set classpath:liquibase/legacy/schema29.xml::schema29_002::muff1nman:
     Reason: liquibase.exception.DatabaseException: Specified key was too long; max key length is 3072 bytes [Failed SQL: (1071) ALTER TABLE airsonic.user_rating ADD PRIMARY KEY (username, `path`)]

とエラーが出て終了。

第32回 InnoDBインデックスの最大キー長について:MySQL道普請便り|gihyo.jp … 技術評論社

キーとするには長すぎるらしい。日本語だと、長いアルバム名ありそうだもんなぁ。対応できなくはないんだろうけど、シンドそうなのでMySQLは諦めた。


追記 2021-01-24
なんてその時はスルーしたが、3072バイトって仮に1文字4バイト( utf8mb4)だとしても768文字だぞ。自環境みたらそんな長いタグ見付からなかったぞ…結合してるのか?

曲名の最大文字数 119
B-4 ストリングス・ピアノ [Those women longed for the touch of others' lips, and thus invited their kisses.(B-4ストリングス・ピアノ)/TV-III]
アルバム名の最大文字数 121
25th Anniversary TOUR GREATEST ANTHOLOGY -NAKED- OFFICIAL PIRATES MIX Live at TOKYO INTERNATIONAL FORUM HALL-A 2014.06.04
アーティスト名の最大文字数 150
R.E.V.O.; 市川裕之; 井上花菜; Eλευσευς; 上出匡高; 花れん; 栗林みな実; 駒形友梨; 沢城みゆき; Jimang; Joelle; Shin; 南里侑香; Noël from VANISHING STARLIGHT; 深見梨加; Fuki; 藤田咲; 結良まり; RIKKI

追記ここまで


PostgreSQL

じゃあ、オープンソースと相性の良さそうな? PostgreSQLということで、インストールからDB作成まで。

$ sudo apt -y install postgresql postgresql-contrib

たまたまインストールとDB作成で参考にした RaspberryPi4でPostgresSQL+Nginx+NextCloud18構築 - Qiitapostgresql-contribもインストールしてたから、調べたら、 PostgreSQL Deep Dive: contribモジュールを使ってみようのようだ。

sudo -u postgres psqlで接続。

postgres=# ALTER USER postgres with encrypted password 'password';
postgres=# 
postgres=# CREATE ROLE airsonic;  // airsonicというロールを作成
postgres=# \password airsonic  // ロールのパスワード設定
postgres=# パスワード入力
postgres=# 
postgres=# ALTER ROLE airsonic WITH LOGIN;  // ロールにログイン権限を付与
postgres=# CREATE DATABASE airsonicdb WITH OWNER airsonic;
postgres=# // airsonicdbというデータベースを作成しairsonicに所有権を与える
postgres=# \q

何か最後のexit;だけERROR: syntax error at or near "exit"なってできなかった。古い記憶から\qを思い出した。

どうもPostgreSQLってのは認証方式にトラップ?があるようで PostgreSQLのPeer認証と他の認証方法への変更 | Web Memorandumとあるので

/etc/postgresql/10/main/pg_hba.conf

# Database administrative login by Unix domain socket
#local   all             postgres                                peer
local   all             postgres                                md5

# TYPE  DATABASE        USER            ADDRESS                 METHOD

# "local" is for Unix domain socket connections only
#local   all             all                                     peer
local   all             all                                     md5

peerとなっている箇所をmd5に。しかし、md5って本当に MD5 - Wikipediaなんだろうか?ハッシュの衝突耐性が強くないことから、ファイルサイズの確認ならまだしも、認証に使うのは良くなさそうな…まあ、ここでは気にしない。

例によってJpsonic設定ファイル編集。

var/jpsonic/jpsonic.properties

DatabaseConfigType=embed
DatabaseConfigEmbedDriver=org.postgresql.Driver
DatabaseConfigEmbedUrl=jdbc:postgresql://localhost:5432/airsonicdb?stringtype=unspecified
DatabaseConfigEmbedUsername=airsonic
DatabaseConfigEmbedPassword=password
DatabaseUsertableQuote="

すると、前回移行で失敗したからか?データベースが空です、みたいなメッセージが出て、管理者ログインもadmin/adminに戻っていた。ともあれ、設定しなおして、スキャンすると、今度は直ぐエラーにならない。

しかし、遅い!

Jpsonic
Jpsonic

既知の問題らしいが、

猛烈に遅い。

Scan time is ~30x greater in PostgreSQL 12.1 than in HSQLDB 1.8.

~30s for 1000 scanned items in both cases in my test, with a local PostgreSQL server in Docker.

HSQLDBの30倍かかる、1000個で30秒ってのは本当だ。風呂でも入って待つか…と思って、上がると…

Jpsonic
    org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT media_file.id, media_file.path, media_file.folder, media_file.type, media_file.format, media_file.title, media_file.album, media_file.artist, media_file.album_artist, media_file.disc_number, media_file.track_number, media_file.year, media_file.genre, media_file.bit_rate, media_file.variable_bit_rate, media_file.duration_seconds, media_file.file_size, media_file.width, media_file.height, media_file.cover_art_path, media_file.parent_path, media_file.play_count, media_file.last_played, media_file.comment, media_file.created, media_file.changed, media_file.last_scanned, media_file.children_last_updated, media_file.present, media_file.version, media_file.mb_release_id, media_file.mb_recording_id, media_file.composer, media_file.artist_sort, media_file.album_sort, media_file.title_sort, media_file.album_artist_sort, media_file.composer_sort, media_file.artist_reading, media_file.album_reading, media_file.album_artist_reading, media_file.artist_sort_raw, media_file.album_sort_raw, media_file.album_artist_sort_raw, media_file.composer_sort_raw, media_file.media_file_order FROM media_file WHERE media_file.path != media_file.folder AND media_file.path NOT LIKE concat(media_file.folder, concat(?, '%')) ORDER BY media_file.id LIMIT ?]; nested exception is org.postgresql.util.PSQLException: ERROR: could not determine data type of parameter $1
	at org.springframework.jdbc.support.SQLStateSQLExceptionTranslator.doTranslate(SQLStateSQLExceptionTranslator.java:101)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
	at org.springframework.jdbc.core.JdbcTemplate.translateException(JdbcTemplate.java:1443)
	at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633)
	at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:669)

エラーを吐いてスキャンが終わっていた。何か結果見るとHSQLDBの時とスキャンできてるファイル数が同じくらいだな(全く同じではない)…スキャンできないファイルがあるのは、HSQLDBのバージョンのせいではなさそう…

とりあえず、調査は終わり。JpsonicはJava 11でも動くし、/var/lib/tomcat8/webapps/airsonic.war/var/airsonic/はバックアップ取ってあったので v109.0.0 に戻した。


  1. Airsonicでも同様のエラーは出てたので、スキャンの問題とは無関係。 ↩︎