$$ \def\v{\boldsymbol} \def\m{\boldsymbol} \def\trans{^\mathsf{T}} \def\inv{^{-1}} \def\bmat{\begin{pmatrix}} \def\emat{\end{pmatrix}} \def\diag{\operatorname{diag}} \def\tr{\operatorname{tr}} \def\ad{\operatorname{ad}} \def\Ad{\operatorname{Ad}} \def\E{\operatorname{E}} \def\det#1{| #1 |} \def\her{^\mathsf{H}} \def\wed{\wedge} \def\given{\mid} \def\defeq{\triangleq} \def\Ys{{\cal Y}} \def\argmin{\mathop{\mathrm{argmin}}} \def\argmax{\mathop{\mathrm{argmax}}} \def\blockdiag{\mathop{\mathrm{blockdiag}}} \def\inner#1{\langle #1 \rangle} $$

Raspberry Pi Zero をエンドレス動画プレイヤーとして使う

学会やら展示会やらで動画をエンドレスで再生したい場合,Raspberry Pi Zero を使うことにすると,荷物の量とか盗難時のダメージとかを低減できて便利である.

一方,会場での設置・操作・撤収をできるだけ簡単にしようと思うと,ちょっと準備をしておく必要がある.つまり,キーボードをつないだりリモートログインしたりすることなく勝手に再生が始まってほしいし,頭出しや停止,シャットダウンなども手軽にできるようにしたい.

というわけで,いろいろ試行錯誤してたどりついた現状のベストプラクティスをまとめておくことにする.

目次:

OMXPlayer のキー操作は自動再生と相性が悪い

Raspberry Pi で動画を再生するなら OMXPlayer というプレイヤーが優秀で,ハードウェアアクセラレータを十二分に活用してくれているようで,Raspberry Pi Zero のような非力なマシンでもたいていの動画をストレス無く再生できる.

出力映像はフレームバッファに直接書き込まれるので,文字端末環境だろうが GUI デスクトップ環境だろうが,はたまた ssh でリモート接続したシェルからの実行だろうがお構いなしに,映像はディスプレイ上にフルスクリーン表示される.この豪快さもわかりやすくてよい.

映像展示の再生デバイスとしてRaspberry Piを使うと最高(Raspbian Stretch版) - nomolkのブログ

上の記事のように OS の起動時やデスクトップ環境の起動時に自動で再生を開始するように設定すれば目的は達せられるのだが,「未解決の問題」として指摘されているように,その場合はプレイヤーの操作が効かなくなるという問題がある.

OMXPlayer 自体はキーボード入力による操作 (例えば q キーで終了したり,スペースキーで一時停止したり,カーソルキーで 30 秒進めたり戻したり) が 可能なのだが,cron などで自動開始した場合は,実行中の OMXPlayer にキー入力が渡らないので操作が効かない.

というか,そもそもこれだけの用途で外付けキーボードを持ち歩きたくない.

OMXPlayer を外部 I/O から操作できるようにする

試行錯誤した結果たどりついたのは,ジャンパケーブルだけ持ち歩いておいて,I/O ピンの接続によって操作するという方針である.「それは『簡単に操作できる』と言えるのか?」という疑問が湧かないわけでもないが,最小限の荷物で必要最低限のことはできる.

とりあえず,動画再生の中断・再開とシャットダウンの機能だけを実装してみた.

14ピンにジャンパケーブルを挿した Raspberry Pi Zero W.どのピンがどの機能だったかすぐ忘れるのでケースにラベルを貼ってある.ケース内の茶色い線は予備のジャンパケーブル.


起動時は,HDMI 出力をディスプレイにつなぎ,USB に電源を供給するだけでよい.OS が起動したら自動で再生が始まる.

動画の再生を中断して Linux のコンソールを表示したくなったら 16 ピン (BCM23) と 14 ピン (グラウンド) をジャンパでつなぐ.16 ピンを開放すると次の動画の頭から再生が始まる (簡易な頭出しとしても使用できる).

撤収時は,18 ピン (BCM24) と 14 ピンをジャンパでつなぐ.シャットダウンが完了したら片付ける.

インストール手順

ハードウェアは Raspberry Pi Zero W,OS は 2018-06-27-raspbian-stretch-lite で動作テストした.

インストールと設定の手順は基本的にはここの README に書いた通り.

GitHub - shingo-kagami/raspi_videoplayer: A Raspberry Pi Endless Video Player

HDMI のホットプラグを有効にする

/boot/config.txt に hdmi_force_hotplug=1 という行があるので,先頭の # を削除して有効化する.

これで HDMI へのディスプレイの接続を OS 起動後にしても大丈夫になる.ディスプレイとのつなぐ方が必ず先だという自信がある場合は,スキップしてよい.

一定のアイドル時間でコンソール画面がブランクになるよう設定する

/boot/cmdline.txt の末尾に consoleblank=600 を追加する.これで 600 秒のアイドル時間で画面が暗転するようになる.

これが必要な理由は後述.600 のところは好きな値にしてよいが,0 はダメ.

コンソール自動ログインに設定する
$ sudo raspi-config

として,Boot Options → Desktop / CLI → Console Autologin を選んでリブート.
以降は OS 起動後は ユーザ pi が自動ログインすることになる.

OMXPlayer と Python3-RPi.GPIO をインストール
$ sudo apt-get update
$ sudo apt-get install omxplayer
$ sudo apt-get install python3-rpi.gpio
videoplayer.py スクリプトを配置する

適当な場所に videopalyer.py を置く.

以下では /home/pi/script/videoplayer.py に置いたとする.実行権を忘れずに与えておく.

$ chmod +x ~/script/videoplayer.py
cron で videoplayer.py の自動実行を設定
$ crontab -e

を実行し,立ち上がったエディタで以下の 1 行を書いて保存する.

@reboot	/home/pi/script/videoplayer.py > /dev/null 2>&1 &
/home/pi/Videos に動画ファイルを置く

ここに置いた動画ファイルが,ファイル名の辞書順で繰り返し再生される.

ただし,ここに (あるいは python のパスが通ったどこかに) 以下のようにリスト変数 vids を定義した playlist.py というファイルを置いておくと,記載された動画がリスト順に再生される.

vids = [
  '/home/pi/Videos/aaa.mp4',
  '/home/pi/Videos/bbb.mp4',
]

実装ノート

videoplayer.py の内容は至って簡単で,OMXPlayer をサブプロセスとして順次実行しながら,RPi.GPIO からのコールバックで I/O ピンによる操作を受け付ける.OMXPlayer への「キー操作」は,標準入力に文字を送ることで実現する.

今の実装では「キー操作」は "q" (終了) しか使っていないが,同じ仕組みで他の「キー操作」に対応するよう拡張するのは容易なはずである.(ただしジャンパケーブルでやってると何が何だかわからなくなると思うので,適当なスイッチなりキーパッド的な何かなりを外付けする方がよいと思うが)


基本はそれだけなのだが,いくつか考慮するべき点がある.

まず,この方法では動画の切り替え時に OMXPlayer をいったん終了して再び実行するので,その間コンソール画面が一瞬見えてしまう.見苦しいのでコンソール画面をブラックアウトしておきたい.

それには,(videoplayer.py から見てコンソール画面は別端末であることに注意して)

TERM=linux sudo setterm -blank force < /dev/tty1

を実行すればよい.逆に,ブラックアウトを解除するには

TERM=linux sudo setterm -blank poke < /dev/tty1

とする.

ここで落とし穴になるのは,/boot/cmdline.txt に consoleblank=... として自動ブラックアウト時間を設定しておかないと setterm -blank は効かない点である.consoleblank=0 でもダメだったので,何か適当な長い時間を設定しておかないといけない.600 なら 10 分間.お好みで適当な数字にしておくとよい.

もう一つの落とし穴は,OS 起動時に setterm -blank force < /dev/tty1 しようとすると,Permission Denied でエラーになりがちな点である.おそらく,コンソール画面側の準備ができていないうちに実行されてしまうのだろう.失敗を検出してリトライする仕組みを入れておくことにした.

これと同様に,RPi.GPIO の初期化も OS 起動後すぐだと失敗することがある.こちらもリトライを入れることにした.


次のエントリでは,これと一緒に持ち歩く HDMI ディスプレイの話をする.