スマートフォン・ジン | Smartphone-Zine

引っ越し先→ https://smartphone-zine.com/

【ドラレコ】Raspberry pi Zere2 W を起動したら、前方カメラ、後方カメラの録画を開始する【スマートバイク】

前後カメラの録画プログラムを考える

ドラレコの要件としては、

  1. 前後カメラの録画
  2. 録画は最高画質で行う(もしもの時の資料)
  3. コーディックはH264(データ量が少ないので長い時間記録を残せる)
  4. 録画データは1分毎に別ファイルにする。
  5. メモリが一杯になったら、古いファイルから消していく
  6. 本体とは別のSDカードに記録する。SDカードは差し替え可能であること。

となります。

1. 前後カメラの録画は、カメラ2台用意したのでOK。Raspberry pi Zero 2 W次第ですが、パフォーマンス的にもなんとかなりそうです。

2. 録画は最高画質で行うも、大丈夫かな?ここもRaspberry pi Zero 2 W次第な部分ですね。とりあえずプログラム中で解像度を切り替え出来るようにしときましょう。

3. コーディックはH264は、カメラのハードウェアでH264にしてくれるので、2台のカメラともH264でできそう

4. 録画データは1分毎に別ファイルは、ffmpegの機能で出来ます。

5番目の要件「SDカードのメモリが一杯になったら古いファイル消す」の部分はプログラムを書かないと実現できなさそうです。これが一番大変かも?

でははずは、6. 本体とは別のSDカードに記録するから対応していきましょう。

動画保存用のSDカードをどうするか?

まずは、

6. 本体とは別のSDカードに記録する。SDカードは差し替え可能であること。

を行うために、SDカードリーダーとSDカードを用意します。

ドラレコに使用するSDカードは、消耗品です。常に古いデータを消して新しいデータを書き込み続けるのですが、そもそもSDカードやUSBメモリもですが、これらは書き換え可能回数はきまっていて、書き換えているとそのうち書き込めなくなります。MLCチップを使ったものが書き換え可能回数が多いので、ドラレコにはMLCチップのmicroSDカードを選択します。 万全を期すなら、SDカードは1年ぐらいで交換してあげるのが良いらしいです。

簡単に交換できるように、ラズパイのOSが入っているSDカードとは別に、SDカードを用意することにします。

USBハブにカードリーダーを入れます。製品はコレにしました。

耐久性の高いMLCのSDカードとして、これを選択しました。

USBメモリという手もあるのですが、通常ドラレコmicroSDを採用しておりSDカードの方が入手しやすいと思うので、SDカードリーダーとSDカードという構成としました。

動画で見るとわかりやすいですが物凄くピッタリ収まってます。 【ドラレコ】microSDリーダーを用意する - YouTube

USBメモリの自動マウント

SDカードが認識されているか確認

sudo blkid /dev/sda1

中略
Device     Boot Start       End   Sectors  Size Id Type
/dev/sda1       32768 249526271 249493504  119G  7 HPFS/NTFS/exFAT

/dev/sda1 として認識されていますね。

USBメモリバイスの情報を表示します。

sudo blkid /dev/sda1

/dev/sda1: UUID="9C33-6BBD" BLOCK_SIZE="512" TYPE="exfat"

あとでマウントするためにUUIDとTYPEの情報を使用します。

マウントするフォルダを作成します。

sudo mkdir /mnt/usb1

/etc/fstabを編集します。 UUID="9C33-6BBD...の1行を追加して、リブートします。自動でマウントされていれば、成功です。

sudo vim /etc/fstab

UUID="9C33-6BBD"  /mnt/usb1             exfat    defaults,noatime,nofail  0       0       #←この行を追加

再起動したらdfコマンドでマウントされたか確認します。

pi@raspberrypi:~ $ df
Filesystem     1K-blocks    Used Available Use% Mounted on
/dev/root       14900440 9836872   4424900  69% /
devtmpfs          185492       0    185492   0% /dev
tmpfs             218772       0    218772   0% /dev/shm
tmpfs              87512     992     86520   2% /run
tmpfs               5120       4      5116   1% /run/lock
/dev/mmcblk0p1    261108   52102    209006  20% /boot
/dev/sda1      124730368     384 124729984   1% /mnt/usb1
tmpfs              43752       0     43752   0% /run/user/1000

ただし、この方法だと、新しいメモリカードを差し替えるたびに、この作業をしないといけません。

なぜなら、UUIDはメモリカード毎に異なるからです。これは不便すぎですね。不採用です。

/etc/fstabを編集して元に戻すことにしました。

UUID="9C33-6BBD...の1行をコメントアウトしてリブートします。

作成したフォルダも消しておきます。

sudo rmdir /mnt/usb1

usbmountで自動マウント

SDカードを別のものにするたびにfstabを編集するのは不便なので、差し替えて再起動すれば自動マウントしてくれるように構成しましょう。

usbmountというパッケージを使うと手軽に自動マウントできるようになります。

インストール及び自動起動設定

sudo apt install usbmount -y
sudo mkdir /etc/systemd/system/systemd-udevd.service.d

設定ファイルをつくます。

sudo vim /etc/systemd/system/systemd-udevd.service.d/00-my-custom-mountflags.conf
[Service]
PrivateMounts=no

保存して再起動。dfでマウントされていることを確認します。

パーテーションを2つ持つSDカードだと、usb0,usb1としてそれぞれのパーティションがマウントされているのがわかります。

$ df
Filesystem     1K-blocks    Used Available Use% Mounted on
省略
/dev/sda1         261108   52108    209000  20% /media/usb0
/dev/sda2       14585536 3782972  10151892  28% /media/usb1
省略

電源をOFFし、SDカードを入れ替えてみます。今度は1パーテーションのみのSDカードに差し替えました。

設定ファイルを確認します。

sudo vim /etc/usbmount/usbmount.conf

FILESYSTEMS= の行を探して、exfatがなければ追記します。

FILESYSTEMS="exfat vfat ext2 ext3 ext4 hfsplu xfs"

FS_MOUNTOPTIONS= の行を探して、次のように設定します。これをしておかないと、いちいちrootにならないと書き込み出来ないためです。

#FS_MOUNTOPTIONS=""
FS_MOUNTOPTIONS="-fstype=exfat,iocharset=utf8,codepage=932,uid=pi,gid=pi,umask=000,dmask=000,fmask=011"

保存して再起動します。再起動したらdfで確認します。

pi@raspberrypi:~ $ df
Filesystem     1K-blocks    Used Available Use% Mounted on
省略
/dev/sda1      124730368     384 124729984   1% /media/usb0

無事ラズパイでSDカードを自動マウント出来るようになりました。

書き込みできるか確認します

pi@raspberrypi:/media/usb0 $ cd /media/usb0
pi@raspberrypi:/media/usb0 $ touch hoge
pi@raspberrypi:/media/usb0 $ ls
hoge
pi@raspberrypi:/media/usb0 $ rm hoge
pi@raspberrypi:/media/usb0 $ ls
pi@raspberrypi:/media/usb0 $ 

できました。

プログラム作る。

それでは、本題です。「2台のカメラでH264最高画質で録画し、1分毎に動画ファイルを作る」というプログラムを作っていきます。

ffmpegでファイル分割

次のように設定すると、60秒毎に1ファイルのファイルに分割してくれます。これを使えばファイル分割の要件もクリアですね。

まずは、最高画質 h264 mp4形式で1分ごとに保存します。

ffmpeg -rtbufsize 30M \
-f v4l2 -input_format h264 -video_size 1920x1080 -framerate 30 \
-i /dev/video0 -c:v copy \
-f segment -strftime 1 -segment_time 60 \
-segment_format_options movflags=+faststart -segment_format mp4 \
-reset_timestamps 1 \
/media/usb0/front_%Y-%m-%d_%H-%M-%S.mp4

ファイルの頭が途切れる。困った。aviにしてみようか。

最高画質 h264 avi形式で1分ごとに保存します。1280x720

ffmpeg -rtbufsize 300M \
-use_wallclock_as_timestamps 1 \
-f v4l2 -input_format h264 -video_size 1920x1080 -framerate 30 \
-i /dev/video2 -c:v h264_v4l2m2m \
-f segment -strftime 1 -segment_time 60 \
-reset_timestamps 1 \
-pix_fmt yuv420p \
/media/usb0/rear_%Y-%m-%d_%H-%M-%S.avi

よしよし、aviは良いみたいです。

h264も試してみる。うまく分割されるかな?

ffmpeg \
-f v4l2 -input_format h264 -video_size 1920x1080 -framerate 30 \
-i /dev/video0 -c:v copy \
-f segment -strftime 1 -segment_time 60 \
-reset_timestamps 1 \
/media/usb0/front_%Y-%m-%d_%H-%M-%S.h264

生の画像データをそのまま格納するだけなので、一番安定している。ただ一番再生が大変そう。

mp4はファイルの切替時に崩れる事が多い感じだが、aviは安定している。.h264は再生ソフトがないと再生できない。ファイルフォーマットはaviで決定ですね。

では、お手軽にpythonスクリプトを組んで行きましょう。

ファイル名はdashcam.pyとします。dashcam=英語でドラレコの事だそうです。ダッシュボードに置くカメラだからかな?

#!/usr/bin/env python3

from usbVideoDevice import UsbVideoDevice  # https://smartphone-zine.hatenablog.com/entry/2023/02/25/065957
import subprocess
import psutil  # フォルダ残量確認
import os  # ファイル操作に使う
import sys  # プログラムを途中で終了させるのに使う
from operator import itemgetter  # イテラブルから任意の要素を抜き出す
import signal  # 非同期イベントにハンドラを設定する
import threading
import time  # スリープ用


# データを保存するフォルダ EX) folder = '/media/usb0/'
folder = '/media/usb0/'

# 保存形式
extension = ".avi"

# デスク使用率がこの%を超えたら古いファイルを削除
dsk_usage_ratio = 90.0

# 前方カメラのUSBポート番号と画像サイズ
front_cam_port = 1
front_cam_size = '1920x1080'

# 後方カメラのUSBポート番号
rear_cam_port = 4
rear_cam_size = '1280x720'

video_front_p = None  # 録画用のプロセスです
video_rear_p = None  # 録画用のプロセスです

# カメラのVideoポート判定
usbVideoDevice = UsbVideoDevice()
video_front = "/dev/video" + str(usbVideoDevice.getId(front_cam_port))
video_rear = "/dev/video" + str(usbVideoDevice.getId(rear_cam_port))


# Ctrl+C or KILL で止められた時の処理
def sig_handler(signum, frame) -> None:
    print('\n\n\n------------sig_handler()\n\n\n')
    global video_front_p
    global video_rear_p

    if not video_front_p is None:
        #video_front_p.terminate()
        video_front_p.kill()

    if not video_rear_p is None:
        #video_rear_p.terminate()
        video_rear_p.kill()

    sys.exit(1)  # プログラムを途中で終了させる


# 録画処理
def record():
    global video_front_p
    global video_rear_p
    video_front_p = subprocess.Popen(
        ['ffmpeg',
         '-rtbufsize', '300M',
         '-f', 'v4l2', '-input_format', 'h264', '-video_size', front_cam_size, '-framerate', '30',
         '-i', video_front, '-c:v', 'copy',
         '-f', 'segment', '-strftime', '1', '-segment_time', '60',
         '-reset_timestamps', '1',
         folder + '%Y-%m-%d_%H-%M-%S_f' + extension])
    video_rear_p = subprocess.Popen(
        ['ffmpeg',
         '-rtbufsize', '30M',
         '-f', 'v4l2', '-input_format', 'h264', '-video_size', rear_cam_size, '-framerate', '30',
         '-i', video_rear, '-c:v', 'copy',
         '-f', 'segment', '-strftime', '1', '-segment_time', '60',
         '-reset_timestamps', '1',
         folder + '%Y-%m-%d_%H-%M-%S_r' + extension])

def diskfree():
    file_list = []
    # ディスク使用率を取得
    dsk = psutil.disk_usage(folder)
    print('\n------------usage:' + str(dsk.percent))
    if dsk.percent <= dsk_usage_ratio:
        return

    # ファイルデータ取得
    for file in os.listdir(folder):
        file_info = os.stat(folder + file)
        file_list.append([folder + file, file_info.st_mtime, int(file_info.st_size / 1024)])

    # 古い順にソート
    file_list.sort(key=itemgetter(1))

    # ファイルの削除
    for file in file_list:
        if dsk.percent > dsk_usage_ratio:
            print('\n------------[DELETE]' + file[0])
            os.remove(file[0])
            dsk = psutil.disk_usage(folder)
            print('\n------------usage:' + str(dsk.percent))
        else:
            break


def main():
    # スクリプトが止められたらプロセスを停止する
    signal.signal(signal.SIGTERM, sig_handler) # KILLされたとき
    signal.signal(signal.SIGINT, sig_handler) # Ctrl+Cされたとき

    # 録画開始、メインスレッド
    record()

    while True:
        # ディスクが使用率を超えたら古いファイルを削除する
        thread = threading.Thread(target=diskfree)
        thread.start()

        # 暫く待つ
        time.sleep(60)


if __name__ == '__main__':
    main()

実行可能ファイルにする

chmod 755 dashcam.py

実行してみる

./dashcam.py

さてここでまた問題発生、前後とも1920x1080で同時に撮影すると処理が追いつかず片方のカメラがfpsが5くらいまで落ちてしまう。

仕方ありません。泣く泣く、後方のカメラを1280x720に変更します。これで安定して30fps出ています。流石にラズパイZero2Wの限界でしょうか?USBカメラ2台ともフルHD録画とsdカード保存はゼロには荷が重いようです。

ただ、ラズパイZero2WでH264で前後カメラで録画出来るのは快挙ですよね!

ラズパイ起動時にドラレコの録画を開始する。

スクリプトも完成しましたので、サービス登録して起動時にスクリプトを起動するように設定しましょう。dashcam.serviceという名前のユニットファイルを作成します。

vim dashcam.service

次の内容で保存します。

# dash cam unit file
[Unit]
Description=dashcam
# 保存先USBメディアが使用可能になるのを待つ
RequiresMountsFor=/media/usb0

[Service]
# Type=simpleはコマンドを実行したタイミングで起動完了と判断します
Type=simple
User=pi
Group=pi

# 作業ディレクトリ指定
WorkingDirectory=/home/pi/

# サービスの起動コマンド
ExecStart=/home/pi/dashcam.py

# Pythonのprint 関数の内容をログに残す設定
Environment=PYTHONUNBUFFERED=1

# 停止完了までに待機する時間
TimeoutStopSec=5

# /bin/sleepを使うと起動時にWaitかけることができる
ExecStartPre=/bin/sleep 5

# ログ出力関連
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=dashcam

[Install]
WantedBy = multi-user.target

SyslogIdentifier=dashcam の名前を使って使ってログを設定。

sudo vim /etc/rsyslog.d/dashcam.conf
if $programname == 'dashcam' then {
    action(type="omfile" file="/var/log/dashcam.log")
}

syslog再起動

sudo systemctl restart rsyslog

ユニットファイルは、/etc/systemd/systemに配置します。ここは管理者が変更した設定ファイルが配置されるディレクトリです。

ユニットファイルを配置したらdaemon-reloadで反映し、dashcamサービスの起動・終了のテストを行い、dashcamサービスを自動起動するように設定しましょう。

sudo cp dashcam.service /etc/systemd/system/
sudo systemctl daemon-reload
sudo systemctl start dashcam
sudo systemctl stop dashcam
sudo systemctl enable dashcam

ログを確認してみましょう。

tail -f /var/log/dashcam.log

エラーが出てきます。

ModuleNotFoundError: No module named 'psutil'

あ、これは多分psutilがsudoで実行出来ないからですね。sudoで実行できるようにインストールします。

sudo pip3 install psutil

これで解決しました。

さて、これでサービスとしてdashcamを実行出来るようになりました。ドラレコスクリプトも完成ですね。

おっと、まだスクリプトにバグが有るようです。削除処理ですね。

Feb 27 08:41:51 raspberrypi dashcam[1009]: ------------usage:90.4
Feb 27 08:41:51 raspberrypi dashcam[1014]: frame=1159046 fps= 36 q=-1.0 size=N/A time=08:49:25.13 bitrate=N/A speed=   1x
Feb 27 08:41:51 raspberrypi dashcam[1009]: Exception in thread Thread-529:
Feb 27 08:41:51 raspberrypi dashcam[1009]: Traceback (most recent call last):
Feb 27 08:41:52 raspberrypi dashcam[1009]:   File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
Feb 27 08:41:52 raspberrypi dashcam[1009]:     self.run()
Feb 27 08:41:52 raspberrypi dashcam[1009]:   File "/usr/lib/python3.9/threading.py", line 892, in run
Feb 27 08:41:52 raspberrypi dashcam[1009]:     self._target(*self._args, **self._kwargs)
Feb 27 08:41:52 raspberrypi dashcam[1009]:   File "/home/pi/dashcam.py", line 88, in diskfree
Feb 27 08:41:52 raspberrypi dashcam[1009]:     file_info = os.stat(folder + file)
Feb 27 08:41:52 raspberrypi dashcam[1009]: FileNotFoundError: [Errno 2] No such file or directory: '/media/usb02023-02-25_16-17-45_r.avi'

フォルダとファイル名の間にスラッシュが抜けていました。(上のdashcam.pyはバグ修正済みです)

今日はここまでです。

長時間稼働試験

丸一日稼働させてみてffmpegが安定稼働するか見ていますが、たまに

Conversion failed!

というエラーでffmpegが終了してしまします。

Google検索すると、-max_muxing_queue_size 512すると良いとか書かれていたので試してみます。

しかしmax_muxing_queue_sizeを付けると負荷が高くなり、FPSが7くらいまで落ちてしまい安定しませんでした。もう少し様子を見て、ダメなら拡張子を.AVIから.H465に変更してみようかと思います。

【ドラレコ】バイクにディスプレイを搭載してリアカメラの画像を写せないか【スマートバイク】

AliExpressで横長のディスプレイを購入しました。これをバイクに取り付けてバックミラー見たく出来ないかなぁと夢想してます。

www.waveshare.com

7.9インチ静電容量式タッチスクリーンlcd、400*1280、hdmi互換、ips、raspberry pi/jetson nano/pc windows 10/10/8/8/7をサポート|デモボード| - AliExpress

ラズパイに取り付けます。

取り付け方は、ディスプレイメーカーのWikiに詳しく記載されてます。助かるなぁ。

7.9inch HDMI LCD - Waveshare Wiki

sudo vim /boot/config.txt

次のように追加します。

#for waveshare 7.9inch HDMI LCD
hdmi_group=2
hdmi_mode=87
hdmi_timings=400 0 100 10 140 1280 10 20 20 2 0 0 0 60 0 43000000 3
display_rotate=1

display_rotateはディスプレイの方向です。今回は横で使いたいので、1にしています。

また、これで反映されない場合、 dtoverlay=vc4-fkms-V3D をコメントアウトします。

私の環境だと、dtoverlay=vc4-fkms-V3D をコメントアウトしないと、display_rotateが反映されませんでした。

【ドラレコ】バックミラーみたいに出来ないか試してみる。

pygameを使えば、カメラの画像を取得してCUIの画面(フレームバッファ)に書き込めないか・・・

Raspberry Piのタッチパネル対応アプリ開発TIPS - karaage. [からあげ]

を試してみる。

pip3 install pygame

タッチディスプレイも使いたかったのですが、残念ながら、タッチディスプレイをCUIで使う方法がわわかりません。

evtest - 入力デバイスのイベントモニタおよびクエリツール

sudo apt install evtest

表示してみましょう。

$ sudo evtest 
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:  CS-USB-IMX307: UVC Camera
/dev/input/event1:  Mitsumi Electric Apple Extended USB Keyboard
/dev/input/event2:  Mitsumi Electric Apple Extended USB Keyboard System Control
/dev/input/event3:  Mitsumi Electric Apple Extended USB Keyboard Consumer Control
/dev/input/event4:  CS-USB-IMX307: UVC Camera
/dev/input/event5:  WaveShare WaveShare
Select the device event number [0-5]: 

今回のディスプレイのメーカ名が「/dev/input/event5: WaveShare WaveShare」として表示されています。どうもこのevent5ってのが怪しい。

Select the device event number [0-5]: 5 [enter]

とすると、イベントが表示されます。タッチパネルを触ると反応がありました!!やはり「/dev/input/event5」がタッチパネルのようです!!

ただし、このevent5と限らず、再起動すると「/dev/input/event0: WaveShare WaveShare」となりました。

$ evtest 
No device specified, trying to scan all of /dev/input/event*
Not running as root, no devices may be available.
Available devices:
/dev/input/event0:  WaveShare WaveShare
/dev/input/event1:  CS-USB-IMX307: UVC Camera
/dev/input/event2:  CS-USB-IMX307: UVC Camera

うーん、pygameもうちょっと勉強しないとわからないかも。

ffmpeg使ってカメラの画像をリアルタイムに画面に表示できるか

v4l2-ctl -v width=1920,height=1080,pixelformat=H264 --device /dev/video0
v4l2-ctl -p 30 --device /dev/video0
v4l2-ctl --device /dev/video0 --stream-mmap=0 --stream-to=- | ffmpeg -y -i pipe:0 -pix_fmt bgra -s 1280x400 -f fbdev /dev/fb0

出るけど、なんかぼやけてる。

ffmpegだけならどうか?

ffmpeg -y -i /dev/video0 -input_format h264 -pix_fmt bgra -s 1280x400 -f fbdev /dev/fb0
Input #0, video4linux2,v4l2, from '/dev/video0':
  Duration: N/A, start: 6311.371615, bitrate: 110592 kb/s
  Stream #0:0: Video: rawvideo (YUY2 / 0x32595559), yuyv422, 640x360, 110592 kb/s, 30 fps, 30 tbr, 1000k tbn
Stream mapping:
  Stream #0:0 -> #0:0 (rawvideo (native) -> rawvideo (native))
Press [q] to stop, [?] for help
Output #0, fbdev, to '/dev/fb0':
  Metadata:
    encoder         : Lavf59.16.100
  Stream #0:0: Video: rawvideo (BGRA / 0x41524742), bgra(pc, gbr/unknown/unknown, progressive), 1280x400, q=2-31, 491520 kb/s, 30 fps, 30 tbn
    Metadata:
      encoder         : Lavc59.18.100 rawvideo

-input_format h264を指定していますが、全く効果ない感じです。相変わらずおかしい動きです。 しかし、yuyv422 640x360の入力ならばパフォーマンスは十分、ほぼリアルタイムでカメラ画像を画面に表示出来ています。

どうも、設定が悪かったようです。この構文で h264にも反応するようになりました。-f v4l2 を明示的に指定すればOKです。

ffmpeg \
-f v4l2 -input_format h264 -video_size 640x360 -framerate 30 -i /dev/video0 \
-f fbdev -s 1280x400 -vf hflip -pix_fmt bgra /dev/fb0

ただし、h264 だと遅延が1秒くらいはある感じで、使い物になりません。

 フォーマットをyuyv422にすればほとんど遅延なし。(このカメラのyuyv422対応解像度は640x360のみ)

ffmpeg \
-f v4l2 -input_format yuyv422 -video_size 640x360 -framerate 30 -i /dev/video0 \
-f fbdev -s 1280x400 -vf hflip -pix_fmt bgra /dev/fb0

解像度をmmpeg最大(1920x1080)にしてみる。

ffmpeg \
-f v4l2 -input_format mjpeg -video_size 1920x1080 -framerate 30 -i /dev/video0 \
-f fbdev -s 1280x400 -vf hflip -pix_fmt bgra /dev/fb0

これでは遅延と画面の崩れが酷く使い物にならない。

mmpegによるカメラのディスプレイ表示は、

  • h264 640x360 遅延と画面の崩れ
  • mmpeg 1920x1080 遅延と画面の崩れ
  • yuyv422 640x360 遅延、画面の崩れもなく良好。

このような結果になった。

色々調べた結果、「Corrupt JPEG data: premature end of data segment」というエラーが起きている。 これは、処理能力が足りず、JPEGを受信出来ていないようだ。ラズパイの限界なのかもしれない。

ffmpeg -y -i /dev/video0 -input_format h264 -pix_fmt bgra -s 1280x400 -f fbdev /dev/fb0

しかし、実際には、カメラはドラレコの為に1920x1080、H.264で録画中なわけなので、録画しつつ画面に表示する方法を模索しないといけない。

どうしたものか?

OpenCVはどうか?

OpenCVでカメラ画像を取得して画面に表示してはどうだろうか?

>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'cv2'

おっと、opencvがインストールされていないようだ。インストールしましょう。

pip install --upgrade pip

バージョン指定しないと、インストールに失敗しました。

この問題を回避するため、バージョン指定でインストールが必要です。

sudo pip3 --default-timeout=1000 install opencv-contrib-python==3.4.14.51

しかし、import cv2でエラーになります。

$ python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/dist-packages/cv2/__init__.py", line 5, in <module>
    from .cv2 import *
ImportError: libhdf5_serial.so.103: cannot open shared object file: No such file or directory

依存関係ライブラリのインストール

$ sudo apt install libhdf5-dev libhdf5-serial-dev libhdf5-103
$ sudo apt install libatlas-base-dev
$ sudo apt install libjasper-dev

import cv2して確認してみる。

$ python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import cv2
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/local/lib/python3.9/dist-packages/cv2/__init__.py", line 5, in <module>
    from .cv2 import *
ImportError: numpy.core.multiarray failed to import
>>> 

エラーになった。今度はnumpyのエラーだ。numpyをアップグレードする。

pip3 install numpy --upgrade

これでエラー解消された。

仮想ビデオデバイス

sudo apt install v4l2loopback-dkms

2つのデバイスを作成したい場合は次のようにします。

pi@raspberrypi:~ $ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
    /dev/video10
    /dev/video11
    /dev/video12
    /dev/video18
    /dev/video31
    /dev/media2

bcm2835-isp (platform:bcm2835-isp):
    /dev/video13
    /dev/video14
    /dev/video15
    /dev/video16
    /dev/video20
    /dev/video21
    /dev/video22
    /dev/video23
    /dev/media0
    /dev/media1

CS-USB-IMX307: UVC Camera (usb-3f980000.usb-1.1):
    /dev/video2
    /dev/video3
    /dev/media4

CS-USB-IMX307: UVC Camera (usb-3f980000.usb-1.4):
    /dev/video0
    /dev/video1
    /dev/media3

42,43の2つの仮想デバイスを追加します。

pi@raspberrypi:~ $ sudo modprobe v4l2loopback video_nr=42,43

追加されたか確認します。

pi@raspberrypi:~ $ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
    /dev/video10
    /dev/video11
    /dev/video12
    /dev/video18
    /dev/video31
    /dev/media2

bcm2835-isp (platform:bcm2835-isp):
    /dev/video13
    /dev/video14
    /dev/video15
    /dev/video16
    /dev/video20
    /dev/video21
    /dev/video22
    /dev/video23
    /dev/media0
    /dev/media1

Dummy video device (0x0000) (platform:v4l2loopback-000):
    /dev/video42

Dummy video device (0x0001) (platform:v4l2loopback-001):
    /dev/video43

CS-USB-IMX307: UVC Camera (usb-3f980000.usb-1.1):
    /dev/video2
    /dev/video3
    /dev/media4

CS-USB-IMX307: UVC Camera (usb-3f980000.usb-1.4):
    /dev/video0
    /dev/video1
    /dev/media3

追加されているのが確認できました。

あとは、再起動時にもこの設定で読み込まれるように設定しておきましょう。

echo "options v4l2loopback video_nr=42,43" | sudo tee -a /etc/modprobe.d/v4l2loopback.conf
echo v4l2loopback | sudo tee -a /etc/modules-load.d/modules.conf
sudo systemctl restart systemd-modules-load.service
sudo reboot

ffmpegを使って、データをvideo42, video43に流し込みます。

ffmpeg \
-f v4l2 -input_format h264 -video_size 1920x1080 -framerate 30 -i /dev/video0 \
-f v4l2 -c:v copy /dev/video42 -f v4l2 -c:v copy /dev/video43

video42からデータを取得して、画面に表示してみる。

ffmpeg \
-f v4l2 -i /dev/video42 \
-f fbdev -vf hflip -s 1280x400 -pix_fmt bgra /dev/fb0

できた。しかし、やはり、 h264 1920x1080 のデータはリアルタイム表示には向かない。カクカクしている。

同じく、video43をデータ保存してみる。

ffmpeg \
-y \
-f v4l2 -i /dev/video43 \
-c:v copy testshot.mp4

出来た。

高解像度 → カクカクしてディスプレイ表示は出来ない。

低解像度 → ディスプレイ表示OK。しかしドラレコの録画としては画質が低すぎて事故の際の参考にしかならない。(もしもの時に相手のナンバーとか判別つかない)

うーん困った。高解像度で保存しつつ、ディスプレイ表示出来る方法を模索しなければならない。

案1:もう一台カメラを装着すれば万事解決。

案2:ffmpgeではなくPythonで自前のコードを書いてみたらどうか?

video42とvideo43に流す解像度をかえられないか。かえられる。しかし、高解像度だと間に合わない。

ffmpeg \ -f v4l2 -input_format mjpeg -video_size 1920x1080 -framerate 30 -i /dev/video0 \ -f v4l2 -c:v mjpeg -s 640x360 /dev/video42 \ -f v4l2 -c:v copy /dev/video43

1280x720ではどうか。

h264はやはり画像がぼやける。

ffmpeg \ -f v4l2 -input_format h264 -video_size 1280x720 -framerate 30 -i /dev/video0 \ -f v4l2 -c:v copy /dev/video42 \ -f v4l2 -c:v copy /dev/video43

mjpegは優秀だがたまに画面が崩れる。

ffmpeg \
-f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video0 \
-f v4l2 -c:v copy /dev/video42 \
-f v4l2 -c:v copy /dev/video43

ffmpeg \
-f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video2 \
-f v4l2 -c:v copy /dev/video42 \
-f v4l2 -c:v copy /dev/video43

色々試して、一番安定しているのがこれ。

 mjpegで1280x720に解像度を抑えめにする。

ffmpeg \
-re -f v4l2 -input_format mjpeg -video_size 1280x720 -framerate 30 -i /dev/video0 \
-f v4l2 -c:v copy /dev/video42 \
-f v4l2 -c:v copy /dev/video43

電子バックミラー側は、hflip, fps=15をつける。

  • hflipは左右反転して鏡像をつくる。
  • ミラーとしてはfps=15くらいで十分
ffmpeg \
-f v4l2 -i /dev/video42 \
-f fbdev -vf "hflip, fps=15" -pix_fmt bgra /dev/fb0

これで、だいぶ落ち着く。ただしmjpegエラーが発生する。

[mjpeg @ 0x1e77890] EOI missing, emulating
[mjpeg @ 0x1e77890] mjpeg_decode_dc: bad vlc: 0:0 (0x1e78f00)
[mjpeg @ 0x1e77890] error dc
[mjpeg @ 0x1e77890] error y=42 x=68
[mjpeg @ 0x1e77890] overread 8

あとは上記エラーがなくなれば実用レベルになりそうなのだが・・・

他のカメラだとどうだろうか。同じくmjpeg 1280x720 30fps出せるはずの、BUFFALO BSWHD06M USB Cameraを繋いで動作確認してみる。

あれ。こちらは一切エラーも起きないでとても安定動作している。うーん、AliExpressで買ったカメラに問題あるのかも。安いカメラだったからなぁ・・・

色々ためそう。今度はv4l2経由の1280x720

v4l2-ctl -v width=1280,height=720,pixelformat=MJPEG --device /dev/video0 v4l2-ctl -p 30 --device /dev/video0 v4l2-ctl --device /dev/video0 --stream-mmap=3 --stream-to=- | ffmpeg -y -i pipe:0 -pix_fmt bgra -s 1280x400 -f fbdev /dev/fb0

これもダメでした。

640x360ならどうか?

ffmpeg \
-re -f v4l2 -input_format mjpeg -video_size 640x360 -framerate 30 -i /dev/video0 \
-f v4l2 -c:v copy /dev/video42 \
-f v4l2 -c:v copy /dev/video43

ffmpeg \
-f v4l2 -i /dev/video42 \
-f fbdev -vf "hflip, fps=15" -pix_fmt bgra /dev/fb0

撮影した動画をコンソールで確認

ffmpeg -re -i out.mp4 -c:v rawvideo -pix_fmt bgra -f fbdev /dev/fb0

OpenCVでカメラ画像を画面に表示

これもうまくいかない。同じように画面が時折崩れる。

そこで、このカメラを、パソコンに繋いでみよう。

  • Macに繋いで、QuickTime Playerで表示してみる。→問題ない。
  • ノートパソコン上のUbuntuで、guvcviewで表示してみる→問題ない。

  • Raspberry pi 4 で、uvcviewで表示してみる→画像がときおり崩れる。JPEGエラー。

  • Raspberry pi Zero 2 W で、uvcviewで表示してみる→画像がときおり崩れる。JPEGエラー。

つまり、PCでは大丈夫だが、ラズパイだと崩れる。ラズパイでも解像度が低ければ崩れない。

これらから、単純に「ラズパイのCPU・GPUでは、能力的にカメラの高解像度データをリアルタイムに画面に表示できない」と結論付ける事ができる。

というわけで、 「ラズパイゼロ2で、電子バックミラー(高解像度)は無理、解像度落とせばOK」 という結果となりました。 ただ、ドラレコとしてはバックモニターの解像度を落とすわけにはいかないです。もしもの事故の時の証拠がメインの目的であり、電子バックミラーはオマケ機能なのです。

電子バックミラーの選択肢としては

  • PCクラスのCPUを用意する。
  • 電子バックミラー用にもう1台カメラ用意する → 割と現実的かも。ただし3台のカメラの通信量耐えられるか心配ではある。
  • ちらつくけど我慢して使う。→ バックミラーとして致命的なので無理。
  • 潔く諦める。

今回は、ドラレコ作成、バックミラーは目的ではありませんので、一旦見送ってもいいかな。

複数のUSBカメラがある場合、どれが後方カメラなのか判断つかない問題

複数のUSBカメラをさした場合、指した順番でvideo0, video2に割り振られる。

再起動すると、video0, video2が入れ替わる可能性もある。

どちらが前方カメラで、どちらが後方カメラなのかを認識して、後方カメラをディスプレイに映したい(バックミラーなので)

そこで下記の記事を参考に、後方カメラを判定する。

dev.classmethod.jp

私の環境ではデバイス名の箇所がそのままでは動作しなかったので修正して使用している。

vim usbVideoDevice.py
import subprocess

class UsbVideoDevice():
    def __init__(self):
        self.__deviceList = []

        try:
            cmd = 'ls -la /dev/v4l/by-id'
            res = subprocess.check_output(cmd.split())
            by_id = res.decode()
        except:
            return

        try:
            cmd = 'ls -la /dev/v4l/by-path'
            res = subprocess.check_output(cmd.split())
            by_path = res.decode()
        except:
            return

        # ポート番号取得
        for line in by_path.split('\n'):
            if('usb-0' in line):
                tmp = self.__split(line, '-usb-0:1.')
                tmp = self.__split(tmp[1], ':')
                port = int(tmp[0])
                tmp = self.__split(tmp[1], '../../video')
                deviceId = int(tmp[1])
                if deviceId % 2 == 0:
                    #name = deviceNames[str(deviceId)]
                    self.__deviceList.append((deviceId , port))
    
    def __split(self, str, val):
        tmp = str.split(val)
        if('' in tmp):
            tmp.remove('')
        return tmp

    # 認識しているVideoデバイスの一覧を表示する
    def disp(self):
        for (deviceId, port) in self.__deviceList:
            print("/dev/video{} port:{}".format(deviceId, port))

    # ポート番号(1..)を指定してVideoIDを取得する
    def getId(self, port):
        for (deviceId, p) in self.__deviceList:
            if(p == port):
                return deviceId
        return -1

実行してみる。

$ python3
Python 3.9.2 (default, Mar 12 2021, 04:06:34) 
[GCC 10.2.1 20210110] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> from usbVideoDevice import UsbVideoDevice
>>> usbVideoDevice = UsbVideoDevice()
>>> usbVideoDevice.disp()
/dev/video2 port:1
/dev/video0 port:4
>>> print(usbVideoDevice.getId(1))
2
>>> print(usbVideoDevice.getId(4))
0
>>> 

getIdでポート番号(USBの刺さっている場所)を渡せば、今そのポート番号に接続されているカメラの番号を返してくれている。 これで、ポート番号でカメラ指定出来るようになった。

今日はここまでです。

【ドラレコ】ラズパイで作るバイク用ドラレコ用のGPSを初期設定する【スマートバイク】

ラズパイで作るバイク用ドラレコ用のGPSを初期設定する

Raspberry Pi用にGPSモジュールを購入しました。使えるように準備していきます。

  • ピンコネクタ(メス)の取り付け
  • USBシリアル変換モジュールのはんだ付け
  • u-center(GPSの設定を行うアプリ)のインストール
  • WindowsPCとGPSの接続確認
  • GPSの通信速度設定

GPSモジュールはこちらを購入しました

GPS/GLONASS受信機(Galileo/BeiDou可)u‐blox M8搭載 みちびき3機受信対応: センサ一般 秋月電子通商-電子部品・ネット通販

USBシリアル変換モジュールはこちらです

FT234X 超小型USBシリアル変換モジュール: 半導体(モジュール) 秋月電子通商-電子部品・ネット通販

コネクタ(メス)

購入したGPSモジュールはケーブルがむき出しなので、ラズパイと気軽に接続出来るようにメスのコネクタを取り付けておきます。

youtu.be

USBシリアル変換モジュール

Windows用アプリでGPSモジュールの初期設定をするために使います。ピンが付属しますがはんだ付けされていないのではんだ付けします。

接続

USBシリアル変換モジュールとGPSを次のように接続します。

  • 5V ー 赤
  • GND ー 黒
  • TXD ー 緑(RXD)
  • RXD ー 橙(TXD)

youtu.be

バイスマネージャで接続を確認

USBシリアル変換モジュールをWindows機に接続します。初回はドライバーソフトウェアがインストールされます。インストールされたら、デバイスマネージャを開きCOMポート番号を確認します。このWindows機の場合はCOM6に割り当てられています。

u-centerのインストール

u-centerを使いGPSの動作確認と設定を行います。

「u-center 2」の方ではなく「u-center」の方をダウンロード、インストールします。

https://www.u-blox.com/en/product/u-center

インストールしたらu-centerを起動します。

接続先の指定

Receiver - Connection - COM6(先ほど調べたCOMポート)

しばらく待って画面上にGPSが取得した情報が表示されればOKです。

gpsdの動作安定の為、通信速度を1152000に変更します

設定画面を開く

View - Message View

UBX - CFG(Config) - PRT(Ports) を選択

1152000に変更

Sendボタンを押す

一旦接続を切る 

Receiver - Connection - Disconnect

ボーレートを変更

Receiver - Baudlate - 1152000 を選択。

変更すると再度接続され、画面上の情報が更新されます。

変更内容を不揮発性メモリに書き込み

UBX - CFG - CFG を開く

Save Current Configuration を選択

Sendボタンを押す

これで準備はOKです。Windows機とUSBシリアル変換モジュールを外し、Raspberry Piに接続して利用します。今日はここまでです。

【ドラレコ】ラズパイで作るバイク用ドラレコ用のGPSで時刻合わせ【スマートバイク】

GPSとラズパイ接続

gpsdインストール

sudo apt install gpsd gpsd-clients pps-tools

シリアルコンソールを無効化

sudo vim /boot/cmdline.txt

既存の行をコメントアウトして無効化します。

新たに1行追加します。console=serial0,115200 を削除した行です。

#console=serial0,115200 console=tty1 root=PARTUUID=8d7b71ea-02 rootfstype=ext4 fsck.repair=yes rootwait
console=tty1 root=PARTUUID=8d7b71ea-02 rootfstype=ext4 fsck.repair=yes rootwait

ついでに、logo.nologo quiteをつけておきます。

console=tty1 root=PARTUUID=8d7b71ea-02 rootfstype=ext4 fsck.repair=yes rootwait logo.nologo quite

Config編集

sudo vim /boot/config.txt

dtoverlay=vc4-kms-v3d は、コメントアウトしておきます。ディスプレイ関係です max_framebuffers=2 は、Raspberry Pi 4のデュアルディスプレイ用。ディスプレイ1個しか繋がないなら不要なのでコメントアウト

[all]以下を追記します。

#dtoverlay=vc4-kms-v3d
#max_framebuffers=2

[all]
dtoverlay=pps-gpio,gpiopin=18,assert_falling_edge=true
dtoverlay=disable-bt
enable_uart=1
core_freq=250

後に マイクモジュールのSPH0645LM4Hが、gpiopin=18を使うことが分かったので GPSのgpiopin=18をgpiopin=17に変更しました。

PPS信号(Pulse-per-second signal)を有効にする

1秒毎のパルス信号です。

GPIOでPPSを受けるモジュールを組み込み

/etc/modulesを編集し、pps-gpioを追加します。

sudo vim /etc/modules

次の一行を追加します

pps-gpio

設定反映のため再起動します

sudo reboot

gpsdの設定

sudo vim /etc/default/gpsd

gpsdが起動時に収集すべきデバイスを指定します。(それらはユーザー gpsd かグループ dialout が読み書きできるようにする必要があります) その他gpsdに渡したいオプションでは、通信速度を115200に設定します。

gpsdctlによるUSB GPSバイスの自動ホットアド/リムーバブル化はOFFにしておきます。

次のように変更

# Devices gpsd should collect to at boot time.
# They need to be read/writeable, either by user gpsd or the group dialout.
#DEVICES=""
DEVICES="/dev/ttyAMA0 /dev/pps0"

# Other options you want to pass to gpsd
#GPSD_OPTIONS=""
GPSD_OPTIONS="-n -s 115200"

# Automatically hot add/remove USB GPS devices via gpsdctl
#USBAUTO="true"
USBAUTO="false"

START_DAEMON="true"
sudo vim /lib/systemd/system/gpsd.socket

IPv6構成をOFFにします。

ListenStream=[::1]:2947 と BindIPv6Only=yes をコメントアウト

[Unit]
Description=GPS (Global Positioning System) Daemon Sockets

[Socket]
ListenStream=/run/gpsd.sock
#ListenStream=[::1]:2947
ListenStream=127.0.0.1:2947
# To allow gpsd remote access, start gpsd with the -G option and
# uncomment the next two lines:
# ListenStream=[::]:2947
# ListenStream=0.0.0.0:2947
SocketMode=0600
#BindIPv6Only=yes

[Install]
WantedBy=sockets.target

gpsdの自動起動設定

sudo systemctl daemon-reload
sudo systemctl enable gpsd
sudo systemctl start gpsd
sudo systemctl enable gpsd.socket
sudo systemctl start gpsd.socket

動作確認します。

信号を受信していると、以下のように1秒おきに受信している内容を表示します。

sudo ppstest /dev/pps0

OKです。念のためラズパイをを再起動してgpsmonコマンドで確認しておきましょう。

sudo gpsmon -n

GPSで受信しているデータから日時情報を得るスクリプト

gpsdata.sh

#!/bin/sh
echo start at `/bin/date`
GPSDATE="`/usr/bin/gpspipe -w | /usr/bin/head -10 | /bin/grep TPV | /bin/sed -r 's/.*"time":"([^"]*)".*/\1/' | /usr/bin/head -1`"
echo $GPSDATE
/bin/date -s "$GPSDATE"
echo end at `/bin/date`
chmod 755 gpsdata.sh 

crontabで定期実行

crontab -e

10分毎に実行されるように設定。

*/10 * * * * sudo bash /home/pi/gpsdata.sh

起動時に毎回実行されるように設定する場合はこうする。ログ出力付き。

@reboot sudo bash /home/pi/gpsdata.sh > /home/pi/gpsdata.log 2>&1

これで、ネットワークが無い状態でもGPSの時計からRaspberry Piの時計設定ができるようになりました。

今日はここまでです。

Raspberry Pi Zero 2 w に、ffmpegをインストールしてカメラのチェックを行う その3(解決編)

ffmpegだとうまくh264入力に切り替えられない様子なので、v4l2の標準出力(stdout)をつかう

まとめ

Raspberry Pi Zero 2 wの場合、本来ならffmpegがカメラからH.264データを取得できるはずが、コマンドがKilledで止まってしまい、うまくいかない。

Raspberry Pi 4ならうまくいった。

  • PiZero2とPi4とのメモリやハードウェア性能の違いによるものか?
  • もしかしたら、ffmpegのバージョンの問題か?

とにかく、Raspberry Pi Zero 2 wではffmpegだけではやりたいことが実現できない。

そのため、間にv4l2を挟んでstdout経由でH.264データを渡す。

これでうまくいくはず。

解決方法

v4l2でh264に切り替えて録画、その標準出力をパイプでffmpegに繋いでそのまま保存しようという作戦

$ v4l2-ctl -v width=1920,height=1080,pixelformat=H264 --device /dev/video0
$ v4l2-ctl -p 30 --device /dev/video0
$ v4l2-ctl --device /dev/video0 --stream-mmap=3 --stream-to=- | ffmpeg -y -i pipe:0 -c:v copy https://blog.hatena.ne.jp/eeesode/smartphone-zine.hatenablog.com/out0.mp4 &

録画を止めるときは別のターミナルを開いて次のコマンドを実行します。

killall v4l2-ctl

うまくいきました!!ようやく、USBカメラ側のハードウェアエンコードを用いたH264録画が完成です。

ここまで本当に長い道のりでした・・・

2台のUSBカメラで、フルハイビジョン(フルHD)画像を撮影する!形式はデータ量の少ないH264形式!

v4l2-ctl -v width=1920,height=1080,pixelformat=H264 --device /dev/video0
v4l2-ctl -p 30 --device /dev/video0
v4l2-ctl -v width=1920,height=1080,pixelformat=H264 --device /dev/video2
v4l2-ctl -p 30 --device /dev/video2
v4l2-ctl --device /dev/video0 --stream-mmap=3 --stream-to=- | ffmpeg -y -i pipe:0 -c:v copy out0.mp4 &
v4l2-ctl --device /dev/video2 --stream-mmap=3 --stream-to=- | ffmpeg -y -i pipe:0 -c:v copy out2.mp4 &

問題なく動作しました!!良かった、これで一歩前進です。

色々試した結果、次のコマンドならffmpegだけでも録画出来ました!!

v4l2-ctl でパイプなんてしなくてもffmpegだけでうまく録画出来たパターンです。

ffmpeg -f v4l2 -input_format h264 -video_size 1920x1080 -framerate 30 -i /dev/video0 -c:v copy tesutout.mp4

今日はここまで。

Raspberry Pi Zero 2 w に、ffmpegをインストールしてカメラのチェックを行う その2

前回、うまく行かなかったファイル出力を再チャレンジ。

試行錯誤してみる。

まずは、Zero2のキャッシュを増やしてみる。→駄目

  1. $ sudo dphys-swapfile swapoff
  2. $ sudo nano /etc/dphys-swapfile
  3. Edit in nano CONF_SWAPSIZE=4096 ,CONF_MAXSWAP=4096 ans save the file 4.$ sudo dphys-swapfile setup 5.$ sudo dphys-swapfile swapon

下記サイトを参考にffmpegRaspberry Pi Zero 2 Wでビルドしてみる。→駄目

pimylifeup.com

ラズパイ4で実行してみる→OK

結果

Raspberry Pi 4では問題なく

ffmpeg -input_format h264 -s 1280x720 -r 60 -i /dev/video0 -c:v copy testshot.mp4

できるが、 Raspberry Pi zero 2 wではKilledになってしまうようだ。

 $ ffmpeg -input_format h264 -s 1280x720 -r 60 -i /dev/video0 -c:v copy testshot.mp4
ffmpeg version 376a1eb Copyright (c) 2000-2022 the FFmpeg developers
  built with gcc 10 (Raspbian 10.2.1-6+rpi1)
  configuration: --extra-cflags=-I/usr/local/include --extra-ldflags=-L/usr/local/lib --extra-libs='-lpthread -lm -latomic' --arch=armel --enable-gmp --enable-gpl --enable-libaom --enable-libass --enable-libdav1d --enable-libdrm --enable-libfdk-aac --enable-libfreetype --enable-libkvazaar --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopus --enable-librtmp --enable-libsnappy --enable-libsoxr --enable-libssh --enable-libvorbis --enable-libvpx --enable-libzimg --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-mmal --enable-nonfree --enable-version3 --target-os=linux --enable-pthreads --enable-openssl --enable-hardcoded-tables
  libavutil      57. 17.100 / 57. 17.100
  libavcodec     59. 18.100 / 59. 18.100
  libavformat    59. 16.100 / 59. 16.100
  libavdevice    59.  4.100 / 59.  4.100
  libavfilter     8. 24.100 /  8. 24.100
  libswscale      6.  4.100 /  6.  4.100
  libswresample   4.  3.100 /  4.  3.100
  libpostproc    56.  3.100 / 56.  3.100
Killed

ラズパイZero2Wを諦めてラズパイ4にするか、Zero2Wでのffmpegは諦めるか。

今日はここまでです。