Ubuntu日和

【第60回】埃を被っているRaspberry Pi 4やミニPCをメディアサーバーとして活用する

今回は引き出しに眠っていたこのRaspberry Piをなんとか活用してみる

 Rasbperry PiやミニPCを活用していますか?買っただけで満足しちゃって放置していませんか?まさか電源すら入れていないってことはないですよね?

 さて、今回はUbntuの記事とイベント用に購入し、その後ずっと放置されていた「 Raspberry Pi 4 」さんの供養を行なう。具体的にはJellyfinをインストールし、省電力メディアサーバーにしてしまおう。

なんでRaspberry Piなの?今ならミニPCでも良くない?

 一昔前までは「安く、低消費電力で、コンパクトなPC」と言えば、Raspberry Piを初めとするシングルボードコンピューター(SBC)がもてはやされていた。しかしながらそのRaspberry Piも性能があがるにつれて、価格も向上し、発熱も強くなり、電源周りもいろいろと気をつける必要が出てきている。

 さらにここ数年はさまざまなミニPCが登場し、小型PCとしてのRaspberry Piは「選択肢の1つ」でしかなくなった。特にWindowsを動かしたい層や、Steamを初めとしたゲームのうち、そこまで3D性能がいらないものが動いて欲しい層にとっては、ミニPCが有力な選択肢になりがちだ。

 もちろんRaspberry Pi自体に価値がなくなったわけではなく、少し高めの性能が欲しい組み込み機器のDIY、電子工作などのプロトタイピング、それらのための教育/学習など、本来の用途では十分に活躍している。そもそもRaspberry Piには豊富なGPIOピンやカメラコネクタなどが搭載されており、各種センサーやサーボなどの周辺デバイスを繋いでこそ真価を発揮するという考え方もある。

 だからと言って、Raspberry PiをミニPCっぽく使ってはいけないという理由もない。実際ケースの種類は豊富だし、サイズもコンパクトに収まる。依然として消費電力は小さいので常時動いてちょっとしたことを行なうサーバーに向いている。うまく設定してやればほぼファンレスな運用も可能だ。

 そしてなんといっても、ほとんどのミニPCに比較すると、ACアダプタは圧倒的に小さくできる。Ubuntuのリポジトリにあるパッケージのほぼすべてが、Raspberry Pi上でも動く。つまりRaspberry Piはご家庭内のLinuxサーバーには向いているのだ。

 と、いろいろ御託を並べたが、今回Raspberry Pi 4を元に説明するのは、手元で持て余していたからという理由だけだ。本記事で紹介する手順はRaspberry Pi 4ベースではあるが、メディアサーバーである「Jellyfin」そのものや、そのUbuntuへのインストール方法は、そのままミニPCでも適用できる。もちろんRaspberry Pi 5でも構わないし、その他のSBCでも動く可能性は高い。よって余っているマシンがあればRaspberry PiやミニPCに問わず試してみてほしい。

メディアブラウザ「Jellyfin」

  Jellyfin はマルチプラットフォームに対応したメディアサーバーだ。手持ちの動画や音楽、写真の配信は元より、サービスが対応していればTVのライブ視聴なども行なえる。Jellyfinそのものはサーバーとして開発されており、プレーヤー側としてはWebブラウザや専用クライアント、Android/iOSのアプリ、ChromecastやスマートTVなどほとんどのデバイス向けのクライアントが用意されている。

 再生速度の変更/全画面再生/PinP/プレイリスト/ハードウェアトランスコーディングなどなど、再生時に欲しい機能は一通りサポートしているし、マルチユーザーでのアカウント管理も可能だ。複数クライアント間で同時視聴できるSyncPlayなんて機能も存在する。

 元々は「VideoBrowser」という名前のWindows向けソフトウェアとして開発が始まり、その後「MediaBrowser」、「Emby」と名前を変えて開発が続いているソフトウェアが元になっている。EmbyはもともとGPL 2.0で提供されていたが、2018年になって次のリリースから本格的にクローズドソースになるとアナウンスされたことなどを受けて、GPL版のEmbyをフォークして作られたのがJellyfinだ

 言語はC#を採用しているが、フレームワークとしては「.NET」を使っており、Ubuntu上はもちろんRaspberry PiのようなArm上のデバイスでも動作する。前述の通り豊富なクライアントソフトウェアが用意されているため、一般的なデバイスであれば再生環境に困ることはないだろう。

 ちなみにJellyfinは、 Raspberry PiなどのSBCへのインストールは推奨していない 。理由は単純で「性能が低い」からだ。特にハードウェアアクセラレーションについては、IntelなどのCPUに組み込まれているiGPUのそれに比較すると使える機能が少なかったり、インターフェイスが不明だったりすることも多いため、動画などをさまざまな解像度で描画するには向かないと考えておいたほうがいいだろう。ただし、今回はトランスコードが不要な音楽の配信を目的としている。利用する機能を限定する前提なら、Raspberry Piでも十分に動作する。

Raspberry Pi 4にUbuntuをインストール

 まずはRaspberry Pi 4にUbuntuをインストールしよう。と言ってもデスクトップ版UbuntuのRaspberry Pi 5へのインストール方法はすでに第52回で紹介した。デスクトップ版のインストール方法については、Rasbperry Pi 4でもほぼ同じなのでそちらを参照して欲しい。

 今回はメディアサーバーということでサーバー版をインストールしよう。また、Raspberry Pi 4にはM.2コネクターはないため、インストール先もUSBかSDカードかのどちらかになる。なお第41回でも説明した「UASプロトコル(USB Attached SCSI Protocol)」については、Raspberry Pi 4だといくつか懸念点があるようだ。まったく動かないというわけではないが、相性によっては性能が低下する可能性がある点にも注意しておこう。相性問題が発生した場合は、Ubuntu側でそのUSBストレージに対してUASプロトコルを無効化することになる。

 またメディアサーバーで配信するデータは、Ubuntuとは別のストレージにしておいたほうが何かあったときの取り回しはしやすい。こちらは容量が必要になるのでUSB接続のストレージになるだろう。

 ここまでの話を踏まえると、Ubuntuのインストールと起動方法として次のような選択肢が出てくる。

  • USBストレージを2台接続し、片方をUbuntuにする
  • USBストレージを1台接続し、UbuntuはmicroSDカードから起動する
  • USBストレージを1台接続し、Ubuntuはネットワークブートする

 ただしRaspberry Pi 4のUSBには次の制約が存在する

  • 4ポート合わせて1,200mAまで
  • 4ポートで通信帯域も共有する
  • USB-SSD/UASには相性問題がある

 一般的なmicroSDカードは遅いし壊れやすい。よってRaspberry Pi 4でOSを起動するならUSBストレージがよく使われる。実際デスクトップを動かすなら速度が出るUSBストレージを使いたくなるだろう。しかしながら今回はサーバー版であるため、そこまで大きなサイズのファイルを頻繁にアクセスすることはない。特に起動するプログラム自体は一度メモリにロードされてしまえば、microSDカードの遅さは気にならなくなる。そうなるとUSBの帯域はメディアサーバーのストレージアクセスに使いたいところだ。

 そのような事情もありRaspberry Pi 4の場合、UbuntuサーバーそのものはmicroSDカードにインストールしてしまうことも十分に意味がある。今回はmicroSDカードにUbuntuをインストールして、USBポートはJellyfinで配信するデータ専用のストレージにしてしまおう。

 Ubuntuのインストール方法は第52回と同じく「 Raspberry Pi Imager 」を使う。

デバイスは「Raspberry Pi 4」をOSは「Other general-purpose OS」から「Ubuntu」の「Ubuntu Server 24.04」で始まるものを選ぼう

 一般的にサーバー運用する場合、なるべく「 余計なソフトウェアはインストールしない 」ことが鉄則だ。インストールされているソフトウェアが多いほどメンテナンスは煩雑になるし、対応しなければならない脆弱性も増える。NATの内側で運用するのであればある程度の緩さは許容されるものの、それでも手間がかからないにこしたことはない。よってデスクトップ版を使うよりはサーバー版を使うことを強くおすすめする。

「次へ」を押した後に「設定を編集する」を選び、ホスト名・ユーザー名・パスワードなどを設定しておく

 Raspberry Pi Imagerは「cloud-init」と呼ばれる初期設定システムをサポートしている。この設定画面でホスト名やユーザー名を入れておけば、起動直後に設定スクリプトが動作し、必要な設定を行ってくれるというわけだ。そうすることでディスプレイ/キーボードを用意しなくても、起動すればすぐに使えるようになる。

 さらに上記設定で「ホスト名.local」を設定しておくと、初回起動後に「avahi-daemon」パッケージをインストールしてくれる。これはLinuxで動くmDNS(Multicast DNS)機能で、いわゆるDNSがなくてもLAN内であれば「ホスト名.local」で名前解決できる仕組みだ。逐一サーバーのIPアドレスを把握しなくても良いので、ご家庭内のネットワークでカジュアルに提供するサービスにはおすすめの仕組みとなる。Wi-Fiの認証にも対応しているので、LANケーブルすら不要にもできる。

 あとはmicroSDカードに書き込んで、Raspberry Pi 4に接続し、電源を入れるだけで良い。今回は初期設定時にavahi-daemonをインストールするために、あらかじめLANケーブルも接続しておく。

ACアダプタとストレージ込みでもこのサイズ。USB-SSDが出っ張っているのはご愛嬌。ちなみにケースファンだけでなく、デバッグ用にシリアルコンソールケーブルも繋いでいる。

 電源を入れたあとは自動的な初期設定が動く。しばらく待ってから、SSHログインを試みてみよう。次のような方法でavahi-daemonが立ち上がるのを待っても良いかもしれない。

pingが成功したら準備完了ということで成功するまで待ち続ける。Ctrl-Cで中断できる
$ while true; do if ping -q -c 1 ホスト名.local; then break; fi; sleep 1; done

 microSDを使っている場合、Ubuntuサーバーだと起動完了に1分から2分ぐらいかかる。さらに初回起動時はいろいろな初期化処理が動くので、だいたい10分経ってもpingに応答がなければ何か問題があると考えれば良いだろう。その場合は、HDMIとキーボードを接続するかシリアルコンソールを接続することになる。

 ちなみにログインしたあとに次のコマンドを実行すると、cloud-initが正常に終了しているかを確認できる。

「SUCCESS」と表示されていたら基本的に成功。初回起動時の処理に6分ぐらいかかっていることが分かる
$ tail -n 3 /var/log/cloud-init.log
2024-08-31 10:14:56,419 - util.py[DEBUG]: Read 14 bytes from /proc/uptime
2024-08-31 10:14:56,419 - util.py[DEBUG]: cloud-init mode 'modules' took 358.360 seconds (358.36)
2024-08-31 10:14:56,419 - handlers.py[DEBUG]: finish: modules-final: SUCCESS: running modules for final

 インストールが完了し、ログインできたらシステムを更新しておこう。

Ubuntu 24.04 LTSでは「-U」オプションを付けると事前にapt updateをやってくれる
$ sudo apt -U -y full-upgrade

 さらにEEPROMも更新しておくことをおすすめする。

あまりに古いEEPROMだとUSBブートなどもうまく動かないので注意が必要だ
$ sudo rpi-eeprom-update -a
*** PREPARING EEPROM UPDATES ***

BOOTLOADER: update available
   CURRENT: Tue Jan 25 14:30:41 UTC 2022 (1643121041)
    LATEST: Wed Jan 11 17:40:52 UTC 2023 (1673458852)
   RELEASE: default (/lib/firmware/raspberrypi/bootloader-2711/default)
            Use raspi-config to change the release.

  VL805_FW: Using bootloader EEPROM
     VL805: up to date
   CURRENT: 000138a1
    LATEST: 000138a1
   CURRENT: Tue Jan 25 14:30:41 UTC 2022 (1643121041)
    UPDATE: Wed Jan 11 17:40:52 UTC 2023 (1673458852)
    BOOTFS: /boot/firmware
'/tmp/tmp.EU69Yi2DSx' -> '/boot/firmware/pieeprom.upd'
Copying recovery.bin to /boot/firmware for EEPROM update

EEPROM updates pending. Please reboot to apply the update.
To cancel a pending update run "sudo rpi-eeprom-update -r".

 ちなみにRaspberry Piの温度は次の方法で確認できる。ファンありのケースだとかなり温度は抑えめだ。

パッケージ更新処理直後にこれぐらいなら高温時以外はファンをオフにする仕組みを実装してもいいかもしれない
$ vcgencmd measure_temp
temp=33.6'C

 あとはシステムを再起動して、Raspberry Piの準備は完了となる。

Jellyfinをインストール

 ようやくJellyfinをインストールする準備が整ったので、インストールしていこう。Jellyfinにはさまざまなインストール方法が存在するが、Ubuntuの場合はインストールスクリプトを使うのが一番楽だろう。これはJellyfinが提供するパッケージリポジトリを追加するため、ソフトウェアのアップデートもaptコマンドで実行できる。

 まずインストールスクリプト(install-debuntu.sh)をダウンロードして、ハッシュ値が合っているか比較しよう。

特に何も表示されなければ問題ないことになる
$ diff <( curl -s https://repo.jellyfin.org/install-debuntu.sh -o install-debuntu.sh; sha256sum install-debuntu.sh ) <( curl -s https://repo.jellyfin.org/install-debuntu.sh.sha256sum )
$ (この手前でエラーなどが表示されなければOK)

 ダウンロードしたinstll-debuntu.shを実行する前に、それが何をするかは確認しておこう。アーキテクチャやOSに依存するものの、基本的にはJellyfinのリポジトリを追加し、Jellyfinとそれが依存するパッケージをインストールしている。Jellyfinパッケージがインストールされたら、自動的にサービスが立ち上がるので、そのアクセス手順も表示するスクリプトだ。

インストールスクリプトを実行して、Jellyfinパッケージをインストールする
$ sudo bash install-debuntu.sh
> Determining optimal repository settings.

Found the following details from '/etc/os-release':
  Real OS:            ubuntu
  Repository OS:      ubuntu
  Repository Release: noble
  CPU Architecture:   arm64
If this looks correct, press <Enter> now to continue installing Jellyfin.
(中略)
> Installing Jellyfin repository into APT.
Types: deb
URIs: https://repo.jellyfin.org/ubuntu
Suites: noble
Components: main
Architectures: arm64
Signed-By: /etc/apt/keyrings/jellyfin.gpg
(中略)
> Waiting 15 seconds for Jellyfin to fully start up.

-------------------------------------------------------------------------------
 ● jellyfin.service - Jellyfin Media Server
     Loaded: loaded (/usr/lib/systemd/system/jellyfin.service; enabled; preset: enabled)
    Drop-In: /etc/systemd/system/jellyfin.service.d
             └─jellyfin.service.conf
     Active: active (running) since Sun 2024-08-18 17:30:02 JST; 27s ago
(中略)
You should see the service as 'active (running)' above. If not, use https://jellyfin.org/contact to find us for troubleshooting.

You can access your new instance now at http://192.168.10.11:8096 in your web browser to finish setting up Jellyfin.

Thank you for installing Jellyfin, and happy watching!

 最後の方で「Active: (active (running)」になっていたら問題ない。その後、最後のほうにある「http://IPアドレス:8096」もしくは「http://ホスト名.local:8096」にWebブラウザからアクセスしよう。あとは次のように初期設定を行なうことになる。

最初にアクセスした人が管理アカウントも作れる点に注意しよう。表示言語は英語でも日本語でも好みの言語を選べば良い
管理者アカウントを設定する
この時点でメディアライブラリ(再生するデータなどの場所)を設定できるが、あとからでも追加できるのでここでは何も追加せずに「次へ」を選ぶ
優先するメタデータ言語も好きな言語を選ぶと良い
リモートアクセスの許可は、ブラウザやクライアントからアクセスするために必要だ

 「自動ポートマッピングを有効」すると、自宅のJellyfinに外出先からアクセスできるようになる。ただしもちろんIPアドレスなどを何らかの方法で知らなくてはならないし、そのコンテンツが本当にインターネット経由で再生できるかどうかも、コンテンツに依存する。まずはローカルで使ってみる前提で、「自動ポートマッピングを有効」はオフにしておこう。

設定が完了した
先ほど設定したアカウントでログインする
ライブラリを設定していないため、何も表示されない

 本来は、ここで次のステップとしてメディアライブラリを追加することになる。ただし今回は前述したように、「Raspberry Piに接続したUSBストレージ」をメディアライブラリとして使用したい。そこでまずはUSBストレージを追加する方法を紹介しよう。

外部ストレージの設定

 それではメディアデータを保存するためのUSBストレージを設定しよう。

 ちなみにUSBストレージである必要性はない。同じネットワーク上にいるNASのストレージをNFSやSambaでマウントして参照しても良いし、Raspberry Pi自体をNASとして運用することも可能だ。NextcloudやGoogle Driveのようなオンラインストレージをローカルにマウントして同期をとってもかまわない。Jellyfinからはローカルファイルとしてメディアデータが見えれば良いので、環境に応じてさまざまな組み合わせが考えられる。

 その中でもっともシンプルなのが、「USBストレージ上のメディアを再生する」というわけだ。USBストレージをUbuntu上で使うにはまず最初にファイルシステムについて検討する。

  • FATやNTFSを使う
  • ext4などでフォーマットする

 USBストレージは購入時点で大抵はFATやNTFSなど、Windowsからすぐにアクセスできるファイルシステムでフォーマットされているはずだ。それをそのままUbuntuで使っても良い。その場合は後述のフォーマットはスキップできる。ただ1個あたりのファイルサイズが大きかったり、ファイルの数が増えてくるなら、Ubuntu上でよく使われているext4などのファイルシステムを使ったほうが安定するし、高速できもある。せっかくなのでUSBストレージを、ext4でフォーマットする方法も紹介しておこう。

 Ubuntuデスクトップがあるなら、そちらでGUIからフォーマットしても良いが、CLIなら次の手順となる。まずUSBストレージをRasyberry Piに接続する。するとdmesgに次のようなログが現れる。

dmesgはカーネルのログメッセージを表示するコマンドだ
$ sudo dmesg | tail
[ 8913.851032] sd 1:0:0:0: Attached scsi generic sg1 type 0
[ 8914.354926] sd 1:0:0:0: [sdb] 976773168 512-byte logical blocks: (500 GB/466 GiB)
[ 8914.354962] sd 1:0:0:0: [sdb] 4096-byte physical blocks
[ 8914.355155] sd 1:0:0:0: [sdb] Write Protect is off
[ 8914.355177] sd 1:0:0:0: [sdb] Mode Sense: 5f 00 00 08
[ 8914.355583] sd 1:0:0:0: [sdb] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 8914.356078] sd 1:0:0:0: [sdb] Preferred minimum I/O size 4096 bytes
[ 8914.356103] sd 1:0:0:0: [sdb] Optimal transfer size 33553920 bytes not a multiple of preferred minimum block size (4096 bytes)
[ 8914.361677]  sdb: sdb1 sdb2 sdb3
[ 8914.363698] sd 1:0:0:0: [sdb] Attached SCSI disk

 上記の例だと「sdb」が接続されたストレージだということが分かる。環境によって「sda」だったり「sdc」だったり「mmcblk0」だったり「nvme0n1」だったりするので注意が必要だ。今回は比較的シンプルな手順を説明したが、ログを読める知識が必要という難点もある。もう少しカジュアルにやるなら、ストレージ接続前にlsblkコマンドを実行し、接続後にもう一度実行して、その差を確認するとかだろうか。これはこれで泥臭い気もする。

 さて「sdb」がストレージだと分かったので、あとはフォーマットしていこう。まずはGPTパーティションテーブルに変更して、ストレージすべてをひとつのパーティションにする。

「/dev/sdb」は環境に応じて変更する必要がある。間違えると大事なデータが消えて大惨事になるので注意して操作して欲しい
$ sudo parted /dev/sdb
GNU Parted 3.6
Using /dev/sdb
Welcome to GNU Parted! Type 'help' to view a list of commands.

GPTに変更する:
(parted) mklabel gpt
Warning: The existing disk label on /dev/sdb will be destroyed and all data on this disk will be lost. Do you want to continue?
Yes/No? y
Error: Partition(s) 3 on /dev/sdb have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use.  As a result, the old partition(s) will remain in use.
You should reboot now before making further changes.
Ignore/Cancel? i

第一パーティションにすべての領域を使う:
(parted) mkpart primary ext4 0% 100%
Error: Partition(s) 1, 3 on /dev/sdb have been written, but we have been unable to inform the kernel of the change, probably because it/they are in use.  As a result, the old partition(s) will remain in use.
You should reboot now before making further changes.
Ignore/Cancel? i

変更結果を表示する:
(parted) print
Model: I-O DATA SSPS-US (scsi)
Disk /dev/sdb: 500GB
Sector size (logical/physical): 512B/4096B
Partition Table: gpt
Disk Flags:

Number  Start   End    Size   File system  Name     Flags
 1      1049kB  500GB  500GB  ext4         primary

(parted) quit
Information: You may need to update /etc/fstab.

 個別にいろいろメッセージが出たり、確認事項が出てくるがすべてYesかIgnoreで問題ない。特に「Ignore/Cancel」についてはパーティションテーブルが変更されたことで、カーネル側の情報を更新する必要がある旨の警告であり、今回はこの時点では無視して良い。ただし「quit」したあとに次のコマンドで情報を更新しておこう。

パーティションテーブルの最新情報をカーネルに反映する
$ sudo partprobe /dev/sdb

 ちなみにここではインタラクティブに設定したが、次のようなコマンドで一気にやってしまうという手もある。

あらかじめ設定したい内容が決まっているならコマンドのオプションに設定してあげれば良い
$ sudo parted -s /dev/sdb mklabel gpt
$ sudo parted -s /dev/sdb -- mkpart primary 0% 100%

 次はファイルシステムのフォーマットだ。

ext4ファイルシステムとしてフォーマットする
$ sudo mkfs -t ext4 /dev/sdb1
mke2fs 1.47.0 (5-Feb-2023)
/dev/sdb1 contains a vfat file system
Proceed anyway? (y,N) y
(中略)
Writing superblocks and filesystem accounting information: done

 最後にファイルシステムのUUIDを確認しておこう。

UUID=がファイルシステムのUUIDで、PARTUUIDはパーティションのUUID
$ sudo blkid /dev/sdb1
/dev/sdb1: UUID="4247cd06-3f16-419b-bdb7-aae0abfa6177" BLOCK_SIZE="4096" TYPE="ext4" PARTLABEL="primary" PARTUUID="c7ea04c3-76ec-4d38-9d67-51744a7cedb1"

 これでストレージの準備は整った。ただ、どうせならUSBストレージが接続されているときは自動的にマウントされるようにしておきたい。そこでマウント用のエントリを作成し、デバイスを認識したら自動的にマウントするように設定しよう。

 マウント用のエントリについてはいろいろな案があるが、リムーバブルメディアであれば「/media」以下にディレクトリを作ってマウントさせることが一般的だ。今回は「/media/jellyfin」というディレクトリを作っておくことにする。

マウント用のエントリの作成
$ sudo mkdir /media/jellyfin

 次に「sudo editor /etc/fstab」を実行して、fstabを編集する。これはシステムがファイルシステムをマウントする際の情報を記録しているファイルだ。ここに書いておけば、あるストレージをどこのマウント用エントリにどのようなオプションでマウントするかを管理できる。すでにルートファイルシステムなどが記載されているはずなので、末尾に新しい行を追加しよう。

末尾に次の行を追加する
UUID=(blkidで表示したUUIDの値) /media/jellyfin ext4 defaults,noauto,x-systemd.automount 0 0

 ポイントは「noauto」と「x-systemd.automount」だ。「noauto」は自動マウントしないオプションだ。たとえばこれが設定されていないと、システムは起動時にマウントしにいこうとする。リムーバブルメディアの場合、起動時に必ずしもデバイスが繋がっているとは限らないため、マウントに失敗する可能性がある。マウントに失敗するとそこで緊急モードに遷移してしまうため、ディスプレイとキーボードを繋いで復旧させなくてはならなくなるのだ。

 「x-systemd.automount」はデバイスを認識したら自動的にマウントするsystemdの機能だ。noautoと組み合わせて使うことで、起動時にデバイスがあればマウントするし、なければ何もしないといった動作にできる。今回の用途にはぴったりだろう。

 設定が終わったら最後にマウントしてメディアを保存するディレクトリを作ってしまおう。

fstabを更新した場合は、systemd daemon-reloadも実行しておこう。大抵の場合は必須ではないが、mountコマンド側の警告を抑制できる。今回はx-systemd.automountを設定しているのでやっておいたほうが良い
$ sudo systemd daemon-reload
$ sudo mount /media/jellyfin
$ sudo chown $USER: /media/jellyfin
$ mkdir /media/jellyfin/Music

 今回は手持ちの楽曲を保存したかったので「Music」というディレクトリを作っておいた。あとはここにJellyfinで再生したいファイルを置いておく。

 さて、ここまで読んで「めんどくさい!」と思ったそこのあなた。その感覚は正しい。LinuxのCLIに慣れたユーザーであれば手癖で覚えていることも多いものの、たまにしかやらない場合は「あれここはどうするのが正しい手順だっけ?」と悩むことも多い。普段CLIに慣れてない人なら、さらにめんどくさそうに思えるだろう。

 ただし、そこまで何度もやる手順ではないこと、汎用性が高いため一度慣れてしまえば他の環境でも流用可能なこと、実際に実施した操作をコマンド履歴として残せること、ころころ変わりがちなGUIの操作には依存しなくて良く、場合によっては「コピペ」ですべて完了することなどから、CLIの操作を好む人も多い。

 せっかくRaspberry Piをディスプレイとキーボードが不要なヘッドレスで運用する機会なので、これを機にCLIにも手を出してみよう。

メディアライブラリを追加する

 ストレージにメディアを用意できたら、Jellyfin側の操作に戻る。

左上のハンバーガーメニューもしくは右上のプロファイルボタンから「管理」の「ダッシュボード」を選択する
左端の「ライブラリ」を選択し、「メディアライブラリを追加」を押す
コンテンツタイプは再生したいメディアの種類に応じて設定。今回は「音楽」を選択
あとは必要に応じて設定を埋めていく。ポイントは「フォルダー」に先ほど作成したディレクトリを設定すること。それ以外は初期設定でも良い。OKボタンを押す
ホームのマイメディアに「音楽」が追加された
再生キューと再生中の様子。サブフォルダごとに階層がわかれるので、それも活用すると良い

 UIは丁寧に日本語化されているため、操作につまずくことはほぼないだろう。プレイリストなども作成/編集できるので、そちらも活用すると良い。

Jellyfin専用のクライアントを用意する

 JellyfinにはWeb UIだけでなく、専用のクライアントも用意されている。また初期設定では無効化されているが、DLNAにも対応しているためDMPを使うという手もある。

 DLNAについては「ダッシュボード」の「管理」から「DLNA」を選択し、「プラグインを取得」を選べば使えるようになる。ただし、プラグイン化されていることからも想像できるように、Jellyfin本体としてはDLNA対応にはあまり積極的でない。普通のTVにような専用クライアントを入れられないような環境向けだと考えておこう。

 さて、前述のとおりJellyfinでは各プラットフォーム向けに専用クライアントを提供している。もちろんUbuntu向けも存在する。一番簡単にインストールできるのはFlatpak版のクライアントだろう。Flatpakについては第4回で軽く紹介しているが、どのLinuxディストリビューションでも使えるパッケージフォーマットだと考えておけば良い。一応GitHub側にDebianパッケージ版も用意されているが、アップデートの追随が面倒になるのでFlatpakのほうをおすすめする。

 UbuntuにFlatpakパッケージをインストールするには、管理用ソフトウェアをインストールし、リポジトリを追加する必要がある。

Flatpakパッケージインストールのための準備
$ sudo apt install flatpak
$ flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo

 あとは追加したリポジトリからパッケージをインストールするだけだ。

Flatpakのパッケージはぱっと見、わかりにくい。本来はGUIからインストールする想定であるのも理由の1つだ
$ flatpak install flathub com.github.iwalton3.jellyfin-media-player
Looking for matches…
Required runtime for com.github.iwalton3.jellyfin-media-player/x86_64/stable (runtime/org.kde.Platform/x86_64/5.15-23.08) found in remote flathub
Do you want to install it? [Y/n]:(Enterを入力)

com.github.iwalton3.jellyfin-media-player permissions:
(使用する権限が表示される)

(中略)

 パッケージの起動はSuperキー(Windowsキー)を押して、「jellyfin」で検索すれば良い。また端末からも以下の方法で起動できる。

パッケージ名を指定して、flatpakコマンド経由で起動する
$ flatpak run com.github.iwalton3.jellyfin-media-player
Jellyfinサーバーへの接続画面

 最初はJellyfinサーバーへ接続する。ここで注意しなくてはならないのが、Flatpakパッケージ版だとAvahi/mDNSが動かないことだ。つまり「ホスト名.local」のような名前解決ができず、DNSを使うかIPアドレスを直接入力する必要がある。

ログインアカウントの設定
表示設定
メディア一覧の表示

 一度ログインしてしまえば、使い方自体はWeb版のそれとほぼ同じとなる。Webブラウザが良いか、専用クライアントが良いかは好みに合わせれば良いだろう。スマートフォン/スマートTV向けのクライアントも用意されているので、そちらもぜひ試してみて欲しい。

 ちなみにRaspberry Pi 4上で楽曲を再生しているだけなら、CPUを10%も使用しない。CPU温度もケースのファンを静音モードで回していても40℃前後を行ったり来たりする程度だ。

 今回はとりあえず「インストールして使えるようにする」までを紹介したが、実際はここからさらにカスタマイズする方法がいくつかある。たとえばどうせRaspberry Pi上に楽曲データがあるなら、USBスピーカーやBluetoothオーディオデバイスもそちらに繋げてしまって、そこから音を流してみたいと思うかもしれない。残念ながらJellyfin単体では実現できないが、JellyfinをYouTube Musicのような音楽ストリーミングサービスとして捉えて、そういうクライアントを使えばできそうだ。

 また今回はmicroSDカードにUbuntu本体をインストールしたが、microSDカードはそこまで耐久性は高くない。少しでも耐久性を上げたければ、「書き込み回数を減らす」のが一番お手軽な方法だ。よく使われるのは「overlayfs」だろう。これは複数のファイルシステムを重ねて1つのファイルシステムに見せる仕組みで、Dockerなどでも使用されている。microSDカード上のファイルシステムを下のレイヤーにし、そこにメモリ上に作成したファイルシステムをかぶせることでファイルシステムへの書き込みはすべてメモリにのみ行われる。これによりmicroSDカードへの書き込みを減らせる。

 これは再起動するとデータが消えることを意味する。よってログを別の書き込み可能で壊れても良いストレージに保存したり、いっそのことログは諦めてしまうということも考えなくてはならず、メリットばかりではないものの有力な手段と言えるだろう。これはUbuntuでも可能なので、ぜひチャレンジしてみて欲しい。