Processing 4 で Webカメラが使えない現象を修正する

Ubuntu 24.04.3 LTSのアプリセンターからインストールしたProcessing 4.xx.xxでWebカメラから画像を取り込もうとすると以下のようなエラーが出て正常に動作しない。一方で、以前のProcessing 3では問題なく動作している。やっと何が原因で、どうすればうまく動くのかがわかったのでメモしておく。

Processing 4のエラーメッセージは以下の通り。

(process:26237): libsoup-ERROR **: 15:24:36.396: libsoup3 symbols detected. Using libsoup2 and libsoup3 in the same process is not supported.
Could not run the sketch (Target VM failed to initialize).
For more information, read Help → Troubleshooting.

ライブラリのlibsoup2とlibsoup3がコンフリクトを起こしているようだった。修正方法がわからず、とりあえずProcessing 3では動いているのでProcessing 3を使っていた。

/usr/libの下にはlibsoup2もlibsoup3も入っているので、きっとライブラリのリンク先がまちがっているんだろう、と思っていた。ふと、確かにまちがえているわけだが、本当に参照しているlibsoupのライブラリはどこにあるんだろうと思った。たしかProcessingのライブラリは、ターゲットのLinuxだけではなくMacやWindowsなどもライブラリをまるごと抱えていたな、と思い出した。

そこでProcessingのライブラリのディレクトリで次のコマンドを実行してみた。

$ find .  -name 'libsoup*'
./video/library/linux-amd64/libsoup-2.4.so
./video/library/linux-amd64/libsoup-2.4.so.1
./video/library/linux-amd64/libsoup-2.4.so.1.11.1
./video/library/linux-amd64/libsoup-gnome-2.4.so
./video/library/linux-amd64/libsoup-gnome-2.4.so.1
./video/library/linux-amd64/libsoup-gnome-2.4.so.1.11.1
./video/library/macos-aarch64/libsoup-2.4.1.dylib
./video/library/macos-x86_64/libsoup-2.4.1.dylib

Ubuntuのシステムに入っているライブラリをみているのではなく、ProcessingのVideoライブラリ “Video Library for Processing 4 / GStreamer-based video library for Processing. by The Processing Foundation” が用意しているバイナリのライブラリを参照しているということに気づいた。また、大量に出ているエラーの中に次のようなメッセージもみつけた。

(省略)/libraries/video/library/linux-amd64/libavresample.so: ファイルが小さすぎます
(省略)/libraries/video/library/linux-amd64/libavresample.so: ファイルが小さすぎます
libavutil.so.56: 共有オブジェクトファイルを開けません: そのようなファイルやディレクトリはありません
(省略)/libraries/video/library/linux-amd64/libmp3lame.so: ファイルが小さすぎます
(省略)/libraries/video/library/linux-amd64/libmp3lame.so: ファイルが小さすぎます
(省略)/libraries/video/library/linux-amd64/libmp3lame.so.0: ファイルが小さすぎます

致命的なエラーにはなっていないが、そもそもlinux-amd64以下に用意しているバイナリー形式のライブラリがUbuntu標準のライブラリとの不整合を発生させているのだ。これで理由はわかった。

Pythonでも同じようなコードを書いていて、問題なく動作しているので、自分が使っているUbuntuには開発に必要なこの周りのライブラリはぜんぶ揃っているはずである。わざわざProcessingのローカルを参照しているバイナリなど必要がない。そこでバッサリとlinux-amd64ディレクトリを消した。ついでに使わないmacos-aarch64、macos-x86_64、windows-amd64以下も大量のバイナリのライブラリを含んでいるので、これもディレクトリごとバッサリと消した。

Processing 4でVideoを使うプログラムを動かしたら、何のエラーも出さずにWebカメラからの画像取り込みは動作した。しばらく放置していた問題はこれで解決した。とりあえずメモとして残す。

XIAO ESP32S3 + ILI9341 + TFT_eSPI トラブルシュートまとめ

症状

Adafruit_ILI9341 ライブラリでは表示できるのに、TFT_eSPI を使うと Guru Meditation Error (StoreProhibited) でリブートを繰り返す。

Adafruit_ILI9341 ライブラリでは問題なく動作しているのでピン接続に問題があるとは考えづらかった。とにかくいろいろな方法を試して見つけたのが以下の原因(たぶん)と解決策である。

原因

  • SPI ポートが正しくなかった。

直接の原因はSPIポートの設定が正しくなかったことである。ESP32S3 では SPI ポートが複数あり、TFT_eSPI が誤ってポートを掴むことがあるらしい。そのため結果的に Guru Meditation Error (StoreProhibited)のエラーとなったと推測される。

解決策

User_Setup.h に以下を追加した。

これでクラッシュが解消した。

以下にこちらで使った設定を示す。

以上

アマゾンでSeeed Studio XIAO ESP32 S3を探す

Mozillaの認証局証明書をArduino/ESPに取り込む

通常Webブラウザは複数の認証局の証明書を内部に用意しているので色々なサイトにhttpsでアクセスできる。Arduino/ESPのような組み込みシステムでhttpsのクライアントを作成するときは、多くの場合は1つのサイトを対象にしているので、そのサイトに適した認証局証明書(cacert)を用意すれば問題ない。しかしながら、色々なサイトにhttpsでアクセスするニーズもあるかも知れない。Firefoxブラウザが使っているMozillaが用意している認証局証明書を使って、Webブラウザのように色々なサイトをアクセスする組み込みシステムをつくるためのヒントを載せておく。

ESP32のためのRoot CA証明書

次のステップで作成する。

  1. 変換ツールgen_crt_bundle.pyの入手
  2. cacert.pemを入手
  3. x509_crt_bundle.h を生成

ESP32で使うためのフォーマットを作成するツールを入手する

まずespressifがgithubで公開しているgen_crt_bundle.pyを入手する。


https://github.com/espressif/esp-idf/blob/master/components/mbedtls/esp_crt_bundle/gen_crt_bundle.py

ブラウザでアクセスしてダウンロードするかwgetでダウンロードをするときのURLは次の通り。

https://raw.githubusercontent.com/espressif/esp-idf/master/components/mbedtls/esp_crt_bundle/gen_crt_bundle.py

cacert.pemを入手

以下のサイトにcacert.pemがあるので、そこから最新のcacert.pem取ってくる。これはMozillaが用意している認証局証明書リストをx.509フォーマットに変換したものとのことである。


https://curl.se/docs/caextract.html

直接ダウンロードするURLは次の通りである。サイトには歴代のcapem.pemが用意されているが、以下のURLは最新のcacert.pemとなっている

https://curl.haxx.se/ca/cacert.pem

ツールでx509形式のフォーマットにする

先程ダウンロードしてきたgen_crt_bundle.pyを使いフォーマット変換する。

$ python gen_crt_bundle.py -i cacert.pem

するとx509_crt_bundleというファイルができる。さらにそれをc langで使える形にする。

$ xxd -i x509_crt_bundle | sed "s/unsigned/const unsigned/g" >x509_crt_bundle.h

プログラムへの取り込み

x509_crt_bundle.hには


const unsigned char x509_crt_bundle[] = {
…}

const unsigned int x509_crt_bundle_len = (ここには数値がある);

が入っていて、それを使えば問題なく処理できる。なおx509_crt_bundleのサイズはsizeof(x509_crt_bundle)でもx509_crt_bundle_lenでも同じ。あとはx509_crt_bundle(と、そのサイズ)をsetCACertBundleにセットすれば良い。

Let’s encryptの証明書でTLS化されているサイトの認証局証明書を入手する方法

一番簡単なのはGoogle Chromeに入っている認証局の証明書を取り出して使う方法だと思う。ではやってみよう。

手順は以下の通り

  1. Google Chromeでchrome://certificate-manager/crscertsをアクセスする。
  2. 証明書マネージャのページになるので、そこでChrome Root Storeを選択する。
  3. ISRG Root X1の証明書を探して、右端の表示アイコンをクリックすると証明書ビューアーに表示される。
  4. 詳細タブを選択し、右下にあるエクスポートをクリックするとファイル保存になるのでファイルを保存する。

このファイルの中身にISRC Root X1の証明書が入っている。ArduinoIDEのサンプルコードBasicHTTPSClientのコードの中にあるrootCACertificateを取り出した証明書に置き換えればLet’s encryptのTLS証明書を使っているサイトに問題なくTLS (https)でアクセスすることができるようになる。