Raspberry Pi 4B + Screenly で日本語対応

Page content

余談

以前からずっと気になっていた Raspberry Pi 4B (略称:ラズパイ) を買った。本体は7000円台で、CPU は最近流行のARM。処理能力はそこそこだけど、簡単なデジタル制御実験から、小型サーバ、小型PCからなんでもできる。大量に生産されているおかげでいつでも手に入るし、例え壊れても買い換えが効く。

普及しているおかげでいろんな応用製品・拡張機器、オプションが出ていて、一からすべてを作る必要がない。処理能力はそこそことはいうものの、HDMI出力x2、USBx4端子、GigabitLAN端子、802.11ac対応Wi-Fi、Bluetooth 5.0完備。H.264(1080p60)のハードウェアエンコーダや H.265(4Kp60)のデコーダまで付いてるので動画再生や中継にも使えそう。

電子工作好きなら LED やら液晶パネルを付けたりアナログ制御してみたりと、実にいろいろ遊べそうなのだけど、インフラ屋さんの仕事をしているので、極力追加回路や半田付けをしないでできることから試したい。仕事のツールとかに応用できればなお良い。

方針

  • デジタルサイネージ (コンテンツをスケジュールで切り替えて表示する装置) を作る
  • Web サイトを定期的に切り替えたい
  • 機器監視Webサイトや、グラフ表示のサイトを見せたい
  • 管理はWebでやりたい

機器仕様・構成

  • 本体: Raspberry Pi 4 Type B (RAM 4GB仕様)
  • 出力: HDMI (要 MicroHDMI - HDMI変換)
  • 電源: USB-C 端子 (5V/3A)
  • ケース: セットトップボックス的に使うなら、放熱の良い金属筐体でファンレスがお勧め
  • ストレージ: microSD Card 32GB
  • OS: Raspberry Pi OS Lite 10 (buster) 32bit
  • ネットワーク: 内蔵Gigabit Ethernet (Wi-Fi でも可)
  • サイネージ用アプリケーション: Screenly Open Source Edition(OSE)
  • モニタ: HDMI対応、もしくは HDMIから変換できるケーブルとセットで
  • その他: USBキーボードとUSBマウス。初期セットアップのみ必要

基本準備

以下はわかりやすい解説サイトがたくさんあるので、そちらを参考に済ませる。以下はざっくり手順。

  1. Raspberry Pi Imager で microSD カードに Raspberry pi OS Lite を焼く。デスクトップ環境は使わないので最小構成の方で。
  2. MicroSD をラズパイに挿して起動
  3. 初期セットアップ。
    1. パスワード変更
    2. ホスト名変更(お好みで)
    3. 固定IP (お好みで)
    4. ロケールを日本に
    5. タイムゾーンは Asia/Tokyo
    6. 日本語キーボード
    7. オーバースキャン有効 (画面の縁にブラックバーが出ないように)
    8. SSH サーバ有効化
    9. SSH 初回ログイン後、公開鍵登録(お好みで)
    10. OS アップデート ここまで終わったら後は SSH ターミナルからリモートで作業する。

Screenly の設定

Screenly インストール

公式手順 に基づいて、SSH ターミナルから実行

bash <(curl -sL https://www.screenly.io/install-ose.sh)

必要なパッケージをダウンロードして、セットアップが自動で進む。数分かかるので待つ。 完了して再起動すると、Screenly が自動で起動するシステムが出来上がり。

Screenly の Web View の日本語・中国語・韓国語(CJK)対応

デフォルトの Screenly は、欧文フォントしか含まれていないため、日本語の Web サイトを Asset に追加すると全て□ (豆腐) に文字化けする。これを解消する。

Docker コンテナの特定

この記事を書いた時点での Screenly OSE は、下記の Docker コンテナから構成されていた。

イメージ名機能
srly-ose-nginxWebサーバ
srly-ose-celeryジョブ管理
srly-ose-viewerQT ベースブラウザ
srly-ose-websocket用途不明
srly-ose-redisインメモリデータベース
srly-ose-server用途不明

Webブラウザの機能は srly-ose-viewer に含まれる Qt5 で実装されていることがわかった。フォントは Docker コンテナの内部に配置する必要がある。

コンテナへ CJK フォントを入れる

まず、親 OS に Noto フォントをインストールする。CJK以外にも非英語圏の文字もすべてインストールされるが、いつか使うかもしれないので入れておく。

sudo apt-get install fonts-noto

docker コンテナ一覧から srly-ose-viewer を探す

sudo docker ps | grep srly-ose-viewer
7d25f41def57        screenly/srly-ose-viewer:latest-pi4   "/usr/bin/entry.sh b…"   29 hours ago        Up 10 minutes                            screenly_srly-ose-viewer_1

↑の例だとコンテナ ID が 7d25f41def57 になる

親OSにインストールした noto フォントと fontconfig設定を、コンテナの中にコピーする

sudo docker cp -a /usr/share/fonts/truetype/noto 7d25f41def57:/usr/share/fonts/truetype/
sudo docker cp -a /usr/share/fonts/opentype/noto 7d25f41def57:/usr/share/fonts/opentype/
sudo docker cp -a /usr/share/fontconfig/conf.avail/70-fonts-noto-cjk.conf 7d25f41def57:/usr/share/fontconfig/conf.avail/

正しくコピーできたかどうか確認する。まずコンテナのシェルに入る。

sudo docker exec -i -t 7d25f41def57 bash

コンテナ内の shell で、インストールされているフォントに Noto フォント系が含まれていることを確認

fc-list | grep -i noto

確認が終わったら exit でコンテナから抜けておく。

Docker コンテナのデフォルト値の変更

Docker は、デフォルトで 172.17.0.0/16 の IP 空間を内部で使用するため、既存環境と衝突すると起動しなくなる。ラズパイとも Screenly とも直接は関係ないが、実際この影響でかなりハマったので、メモしておく。

現在使用中の IP 空間の確認

$ sudo docker network inspect bridge
$ sudo ip addr show dev docker0

Docker に割り当てたい IP 空間を下記の要領で設定ファイルとして配置する。

$ sudo su -
$ cat <<'__EOL__' >/etc/docker/daemon.json
{
    "bip": "172.20.254.1/24"
}
__EOL__

docker を全て再起動

$ sudo systemctl restart docker

再起動後、先ほどのコマンドで IP 空間が変わっているか確認する。

Screenly の利用

PC のブラウザから

http://(ラズパイのIP)/

で管理画面が出る。まずは Settings 周りを適当に調整する。

Settings

Schedule Overview の画面に行き、Add Asset で静的コンテンツ (.mp4 や画像) をアップロードするか、表示させたい URL を入れて Save すると Asset に追加される。

Add Asset

追加直後は Inactive assets に入る。鉛筆アイコンで Duration (切替時間) 等を調整してから、Activity スイッチを ON にすると、Active assets に移動する。

Schedule Overview

「再生」や「停止」のボタンはなく、 Next Asset → のボタンを押すと、Inactive asset に並んでいる通りに順に再生される。動画コンテンツは無指定では動画が終わるまで、静止コンテンツ (画像や URL)は Duration の秒数が経過すると、次のコンテンツに切り替わる。

なお、残念ながら PowerPoint や PDF をスライドショー的に表示する機能はない。PowerPoint 側で動画に Export する機能で MP4 に変換できるので、これで代用はできる。

参考