WezTerm&libsixelでSSH接続したラズパイから即興の監視カメラ的な使い方を試す


※ 当ページには【広告/PR】を含む場合があります。
2024/06/20
ffmpegでラズパイゼロからカメラ画像をUDP配信する方法
蛸壺の中の工作室|SSH接続を介したWezTerm&libsixelで即興の監視カメラ的な使い方を試す

だいぶ前の記事で、リモートのラズパイからカメラ画像を動画としてUDP配信による簡単な監視カメラ化する方法について取り上げていました。

合同会社タコスキングダム|タコツボの中の工作室
ffmpegでラズパイゼロからカメラ画像をUDP配信する方法

簡単にできる自分専用動画配信サービスをffmpegでどう実現するかを解説

その際ポイントとなったのが
「ffmpeg」「ffplayer」「v4l2」のセットアップやコマンドの使い方、ネットワークの設定だったり、少々面倒に感じるポイントがいくつかありました。

今回はもっと簡単にターミナル上に動画を表示させるためのやり方を
「libsixel」で考えていこうと思います。

なおこの記事の内容では「libsixel」のインストール方法と使用法を解説していませんので、以下の記事を参考にしてください。

参考|【シェルコマンド】WezTermとlibsixelを使ってDebian&MacOSのターミナルで画像をそのまま表示してみる


ラズベリーパイ4B 4GB 技適対応品

Raspberry Pi Zero W (ヘッダーハンダ付け済)

Raspberry Pi Zero 2 W 技適取得済

ラズベリーパイピコ

ラズベリーパイ カメラモジュールV2

ラズパイZere/Zero W用カメラFFCケーブル 2本セット(15ピン22ピン15cm)

RAVPower USB充電器 2ポート 24W 【最大出力5V,4.8A】

ラズパイマガジン 2019年12月号 カメラ&センサー工作入門

IoTの基本・仕組み・重要事項が全部わかる教科書

「FFmpeg-SIXEL」はすでに非推奨の状態

※この節の内容は主題とは直接関係ないので、興味がない場合次節からお読みください。

かつてはターミナルからCUIに直接動画を流すことのできた
「FFmpeg-SIXEL」ですが、10年弱もメンテナンスされていないため、必須の依存ライブラリのいくつかが現在のラズパイOSで利用不可能となっています。

「FFmpeg-SIXEL」のコンセプトとしては、動画フォーマットに
sixelを組み込んだffmpegであり、

            $ ffmpeg -i 'https://www.youtube.com/watch?v=LLzGBpNlX-c' -f sixel -pix_fmt rgb24 -s 480x270 -
#...ターミナルに直接動画を再生する
        
ようなニッチで面白い仕様のプログラムでした。

なお、通常版のffmpegではストリーミングを直接sixelのフォーマットに変換することができません。

結局は手元のラズパイでビルドインストールできませんでしたが、無駄に時間も取られてしまったため、どこらへんで躓いたのかを記録として残しておきます。

aptからffmpegをアンインストール

一旦、通常版のffmpegを設定ファイル+依存関係にあるパッケージもごっそり削除してみます。

            $ sudo apt --purge remove ffmpeg
        

FFmpeg-SIXELをインストール

ではsixelで動画再生できるようにされた
FFmpeg-SIXELをソースコードビルドしていきます。

参考|インストール手順

以下は公式通りにコマンドを順に叩きます。

            $ git clone https://github.com/saitoha/FFmpeg-SIXEL
$ cd FFmpeg-SIXEL
$ ./configure --enable-libquvi --enable-libsixel
$ make install
$ ffmpeg -i 'https://www.youtube.com/watch?v=ixaMZPPmVG0' -f sixel -pix_fmt rgb24 -s 480x270 -
        
するとconfigureの段階で、どうもlibquviがないらしいエラーが発生します。

            $ ./configure --enable-libquvi --enable-libsixel
ERROR: libquvi not found using pkg-config

If you think configure made a mistake, make sure you are using the latest
version from Git.  If the latest version fails, report the problem to the
ffmpeg-user@ffmpeg.org mailing list or IRC #ffmpeg on irc.freenode.net.
Include the log file "config.log" produced by configure as this will help
solve the problem.
        
そこで、pkg-configからlibquviを有効する必要がありそうです。

内部の
libquviを捜索しましょう。

            $ pkg-config --exists --print-errors libquvi
Package libquvi was not found in the pkg-config search path.
Perhaps you should add the directory containing `libquvi.pc'
to the PKG_CONFIG_PATH environment variable
No package 'libquvi' found
        
仕方ないのでlibquviをパッケージインストールしようとすると....、

            $ sudo apt install libquvi
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
E: Unable to locate package libquvi
        
なるほど、パッケージからは利用できそうにないようです。

そこで
libquviもソースコードインストールを試みます。

            $ git clone https://github.com/mogaal/libquvi.git
$ cd libquvi
$ ./configure && make

configure: error: a2x is required to create man pages when building from git
        
うーん、今度はa2xが無い。

Debianだと
a2xasciidoc-baseの一部らしいので、以下を叩きます。

            $ sudo apt install asciidoc-base
        
これで再度libquviをビルドしてみます。

            $ ./configure && make

configure: error: Package requirements (lua-5.1 >= 5.1) were not met:

No package 'lua-5.1' found
        
更に更に、lua-5.1も要求されます...こうなったらとことん不足の依存性入れてあげます。

            $ sudo apt install liblua5.1-0-dev liblua50-dev liblualib50-dev
        
で、再度ビルド...、

            No package 'libproxy-1.0' found
        
というのが出ました。

ただ、
libproxy-1.0のライブラリ依存性かなり古すぎて、最近のDebianでのソースコードビルドが不可能のようです。

これ以上はダメそうなので、
FFmpeg-SIXELのインストールはここでゲームオーバーとします。


ラズベリーパイ4B 4GB 技適対応品

Raspberry Pi Zero W (ヘッダーハンダ付け済)

Raspberry Pi Zero 2 W 技適取得済

ラズベリーパイピコ

ラズベリーパイ カメラモジュールV2

ラズパイZere/Zero W用カメラFFCケーブル 2本セット(15ピン22ピン15cm)

RAVPower USB充電器 2ポート 24W 【最大出力5V,4.8A】

ラズパイマガジン 2019年12月号 カメラ&センサー工作入門

IoTの基本・仕組み・重要事項が全部わかる教科書

コマ撮りしたjpeg画像をimg2sixelコマンドの表示から逐次更新させる

前節の内容からffmpegから出力する動画フォーマットをsixel形式に対応させることが無理そうということが分かりました。

ただし同じ逆転の発想で、動画を細切りにして連続するJPEG/PNG画像へ変換することができれば、その変換した静止画像を利用して
img2sixelコマンドでターミナルに表示&更新してあげると同じことができそうです。

例えば以下のブログでは、YoutubeLiveから一定間隔で取得した映像をpng画像化し、
img2sixelコマンドにパイプさせてターミナルへ表示させています。

参考|tmux Sixel でリモート画像を表示して遊ぶ

同じような理屈で、ffmpegコマンドが使える場合、画像からコマ撮りさせることが簡単で、そこに
img2sixelコマンドから一定間隔で撮りためた画像を表示させてみましょう。

            $ while true;\
    do ffmpeg -f v4l2 -i /dev/video0 -loglevel -8 \
        -vframes 1 -c:v png -f image2 - | img2sixel; sleep 0.2; \
    done
        
実際にはこれで動くはずなのですが、カメラモジュールV1/V2などの「レガシーカメラ」を使うと以下のようなエラーが発生します。

            #...
[video4linux2,v4l2 @ 0x15be900] ioctl(VIDIOC_G_PARM): Inappropriate ioctl for device
[video4linux2,v4l2 @ 0x15be900] Time per frame unknown
[video4linux2,v4l2 @ 0x15be900] ioctl(VIDIOC_STREAMON): Invalid argument
/dev/video0: Invalid argument
        
これはffmpegが内部で利用しているv4l2(video for linux2)がカーネルレベルで「レガシーカメラは使えないよ」とエラーを出していることに起因します。

つまり最近のラズパイOSを使う限りでは、カメラモジュールV3相当を装備するか、ffmpeg/v4l2を使うのを諦めるかの選択になります。

レガシーのラズパイカメラでもコマ撮り写真を撮影する方法

ラズパイカメラの連写には、現行のOS標準で利用することのできる
libcamera-vidコマンドが便利です。

libcamera-vidコマンドはラズパイのカメラデバイスから動画を作成するためのものです。

デフォルトでは動画のエンコーディング形式がハードウェアH264ですが、
--codecオプションからMotionJPEGを使うことも可能です。

            $ libcamera-vid -t 10000 --codec mjpeg -o test.mjpeg
        
ただし今回の目的でいうと、MotionJPEGそのものを動画として利用するのではなく、連番のJPEG画像として保存することが好ましいです。

これを可能にするのが、
--segmentオプションです。

--segmentオプションに連写間隔時間(ミリ秒)を指定することで、おおよそ指定の間隔ごとに写真を撮り、連続するJPEG画像として撮りためることができます。

以下の例であれば、1ミリ秒間隔で10秒(=10000ミリ秒)間JPEG画像を連続で取り続けます。

            $ libcamera-vid -t 10000 --codec mjpeg --segment 1 -o test%05d.jpeg
        
ハードウェアのスペックやカメラの取り込み解像度にもよりますが、手元のラズパイ4で480x320サイズの画像が310枚連写されています。

おおよその概算ですがこの設定だと、写真1コマあたり31ミリ秒強の時間を消費している計算になり、結構高速な撮影になっているように思います。


ラズベリーパイ4B 4GB 技適対応品

Raspberry Pi Zero W (ヘッダーハンダ付け済)

Raspberry Pi Zero 2 W 技適取得済

ラズベリーパイピコ

ラズベリーパイ カメラモジュールV2

ラズパイZere/Zero W用カメラFFCケーブル 2本セット(15ピン22ピン15cm)

RAVPower USB充電器 2ポート 24W 【最大出力5V,4.8A】

ラズパイマガジン 2019年12月号 カメラ&センサー工作入門

IoTの基本・仕組み・重要事項が全部わかる教科書

SSH接続したラズパイでコマ撮りした画像をターミナル上に動画として表示する

先程の内容までで、基礎となるテクニックとポイントを掻い摘んで解説していきました。

ということで、ようやく本題の
WezTerm越しにSSH接続したラズパイから直接ターミナル上に動画として表示させてみましょう。

なお、
Sixelプロトコルが扱えるターミナルソフトであればWezTermでなくても同じことができます。

なお、
WezTermの画面分割は以下の記事の内容を参考にしてください。

参考|【シェルコマンド】WezTermの画面操作

では、
WezTermからラズパイにSSH接続し、適当なディレクトリで以下のコマンドからコマ撮りを開始します。

            $ libcamera-vid -t 0 --codec mjpeg --segment 100 -o test.jpeg
        
そして別窓で、SSH接続し、コマ撮り中のJPEG画像のあるフォルダ内で、以下のコマンドを実行します。

            $ while true; \
    do img2sixel test.jpeg 2>/dev/null; sleep 0.1; \
    done
        
するとなんということでしょう。

1秒くらいの遅延は感じるものの、即席の監視カメラとして動かすことができています。

合同会社タコスキングダム|蛸壺の中の工作室

実際の監視カメラとしての実用性は乏しいですが、製品開発段階のカメラの動作チェックや、動画の品質チェックなどで利用できそうなテクニックになるでしょう。

GUIなしの無印ラズパイゼロでもlibsixelは動く

WezTermlibsixelの組み合わせの良いところは、SSH接続できるだけでカメラ側のハードウェアの性能にほぼ関係なく動作してくれる点にあります。

今となってはだいぶスペックも見劣りしてきたクラシックなラズパイゼロでも
libsixelが導入可能です。

            $ sudo apt install libsixel*
        
現行のカメラモジュールのユーティリティであるlibcamera-vidコマンドのご先祖にあたる「raspivid」コマンドの時代にはmotionJPEGフォーマットからJPEGを一枚づつコマ撮りするオプションは無いため、「raspistill」-tl(--timelapse)オプションで代替します。

-tlオプションを使うとミリ秒で指定した間隔でコマ撮り(連続撮影)モードを使うと良いでしょう。

ということで、古いOSで動いているラズパイでは以下のようにコマ撮りできます。

            $ raspistill -t 0 -w 480 -h 320 -tl 100 -o test.jpeg
        

ラズベリーパイ4B 4GB 技適対応品

Raspberry Pi Zero W (ヘッダーハンダ付け済)

Raspberry Pi Zero 2 W 技適取得済

ラズベリーパイピコ

ラズベリーパイ カメラモジュールV2

ラズパイZere/Zero W用カメラFFCケーブル 2本セット(15ピン22ピン15cm)

RAVPower USB充電器 2ポート 24W 【最大出力5V,4.8A】

ラズパイマガジン 2019年12月号 カメラ&センサー工作入門

IoTの基本・仕組み・重要事項が全部わかる教科書

まとめ

今回はSSH接続を介したラズパイからのカメラ撮影写真を動画風にsixelプロトコルを使ってCUI表示させるテクニックについて解説していきました。

個人的にはトイカメラに高い性能などを要求してはいないのですが、ラズパイカメラモジュールV3などは最近の相場で5,000円を越えてくる高価な製品になってきているため、辛うじてレガシーカメラもまだ利用できるのは少し安心します。

そのうちレガシーカメラが完全に使えなくなる可能性もあるので、今後はできるだけV3モジュールを検討したほうが良いかも知れませんが...。