Raspberry Piを使ったテレプロンプタの試作

category: make
tags: linux

はじめに

流行性感染症の拡大により、オンライン・プレゼンテーションを行うことが多くなりました。パソコン画面とカメラは離れた位置にあるため、画面を見つめて話すと、伏し目がちになり、不自然です。カメラ目線でプレゼンテーションを行いたいのです。

ハーフミラーを使うと、映像位置とカメラ位置を一致させることができます。このような装置は、テレプロンプタやプロンプタと呼ばれ、テレビの報道番組などでよく利用されています。このテレプロンプタを自作してみました。

raspberry pi based teleprompter

機器

ここで用いた機器は次のとおりです。

PoEにより、イーサネットケーブル1本で運用できるようにしました。

鏡像表示

テレプロンプタでの映像は、鏡像(左右を反転した鏡文字)にしなければなりません。

しかし、最新のRaspberry Pi OS(Bullseye)にて起動したところ、公式タッチディスプレイの映像が上下逆さまに映り、いきなり詰みました。

様々なウェブページには、この対策法が書かれていますが、今回の用途に対してはうまくいきません。この上下逆さま表示を直すために/boot/config.txt[all]セクションにlcd_rotate=2を追加することが一般的ですが、これでは解決しないことがあります。そのときは、/boot/config.txtdtoverlay=vc4-kms-v3dラインをコメントアウトして(先頭に#を加える)ビデオアクセラレータをオフにすればlcd_rotate文が有効になります。さらに、display_lcd_rotate=0x10000を追加すれば鏡像表示も可能です。パネルのタッチ位置と表示位置を一致させるためには、さらにdtoverlay=rpi-ft5406,touchscreen-inverted-xを追加します。しかし、このようにビデオアクセラレータをオフにすると、カメラ撮影ができなくなりました。

[0:00:48.605058262] [1503]  INFO Camera camera_manager.cpp:299 libcamera v0.0.2+55-5df5b72c
[0:00:48.689807637] [1506]  INFO RPI raspberrypi.cpp:1425 Registered camera /base/soc/i2c0mux/i2c@1/ov5647@36 to Unicam device /dev/media3 and ISP device /dev/media0
[0:00:48.691469407] [1503]  INFO Camera camera.cpp:1026 configuring streams: (0) 1296x972-YUV420
[0:00:48.692088574] [1506]  INFO RPI raspberrypi.cpp:805 Sensor: /base/soc/i2c0mux/i2c@1/ov5647@36 - Selected sensor format: 1296x972-SGBRG10_1X10 - Selected unicam format: 1296x972-pGAA
[0:01:00.994665132] [1503]  INFO Camera camera.cpp:1026 configuring streams: (0) 2592x1944-YUV420 (1) 2592x1944-SGBRG10_CSI2P
[0:01:00.999886174] [1506]  INFO RPI raspberrypi.cpp:805 Sensor: /base/soc/i2c0mux/i2c@1/ov5647@36 - Selected sensor format: 2592x1944-SGBRG10_1X10 - Selected unicam format: 2592x1944-pGAA
[0:01:08.415809452] [1506]  WARN V4L2 v4l2_videodevice.cpp:2007 /dev/video0[12:cap]: Dequeue timer of 2130000.00us has expired!
[0:01:08.416135910] [1506] ERROR RPI raspberrypi.cpp:1887 Unicam has timed out!
[0:01:08.416231952] [1506] ERROR RPI raspberrypi.cpp:1888 Please check that your camera sensor connector is attached securely.
[0:01:08.416323931] [1506] ERROR RPI raspberrypi.cpp:1889 Alternatively, try another cable and/or sensor.
ERROR: Device timeout detected, attempting a restart!!!

そこで、GUIメニューで上下反転させて正しく表示させた上で、テレプロンプタ使用時にはxrandrコマンドで鏡像表示します。GUIメニューで上下反転させたときに自動設定された~/.config/monitors.xmlファイルの内容は次のとおりです。XMLファイルに<rotation>upside_down</rotation>を加えることがポイントです。

<monitors version="2">
  <configuration>
    <logicalmonitor>
      <x>0</x>
      <y>0</y>
      <primary>no</primary>
      <monitor>
        <monitorspec>
          <connector>DSI-1</connector>
          <vendor>unknown</vendor>
          <product>unknown</product>
          <serial>unknown</serial>
        </monitorspec>
        <mode>
          <width>800</width>
          <height>480</height>
          <rate>59.928</rate>
        </mode>
      </monitor>
      <transform>
        <rotation>upside_down</rotation>
      </transform>
    </logicalmonitor>
  </configuration>
</monitors>

鏡像表示にはxrandr --output DSI-1 --reflect xを実行します。この鏡像表示設定は、monitors.xmlに保存できないようですので、再起動するたびに入力する必要があります。また、この方法では、パネルのタッチ位置が画面位置と一致しません。今後の課題です。

raspberry pi based teleprompter

カメラの利用

Raspberry Piカメラモジュールをテレプロンプタの裏面に固定します。カメラモジュールに添付されているリボンケーブルでは長さが足りなかったので、より長いリボンケーブルを別途、購入しました。

raspberry pi based teleprompter

OSから利用できるカメラは、libcamera-hello --list-camerasにて確認できます。

libcamera-hello --list-cameras
Available cameras
-----------------
0 : ov5647 [2592x1944] (/base/soc/i2c0mux/i2c@1/ov5647@36)
    Modes: 'SGBRG10_CSI2P' : 640x480 [30.00 fps - (0, 0)/0x0 crop]
                             1296x972 [30.00 fps - (0, 0)/0x0 crop]
                             1920x1080 [30.00 fps - (0, 0)/0x0 crop]
                             2592x1944 [30.00 fps - (0, 0)/0x0 crop]

静止画の撮影には、libcamera-stillコマンドを使います。動画の撮影コマンドはlibcamera-vidです。これらのカメラ操作コマンドは、Raspberry Pi OSに標準でインストールされています。

ここでは、ストリーミング再生をしたいので、libcamera-vidコマンドを用います。ポート番号8888への映像ストリーミング送信には、次のコマンドを用います(参考:ラズパイ新OS「Bullseye」でのカメラモジュールの使い方)。

libcamera-vid -t 0 --inline --listen -o tcp://0.0.0.0:8888

このRaspberry Piポート番号8888に対して、別PCにインストールしたVLC media playerからアクセスしてみます。VLCにてtcp/h264://raspberrypi.local:8888を開きます。

raspberry pi based teleprompter

あとは、このタッチパネル画面いっぱいに文字を表示すればOKです(参考:How to Build a Raspberry Pi-Powered Teleprompter)。このタッチディスプレイに、自らの発表スライドを表示したり、さらにはElgato Stream Deckのような機器操作機能を実装することもできそうで、希望が湧いてきます。

しかしながら…現状では、映像が表示されるまでに3秒くらいの時間遅れが生じて、実用性は今ひとつです。

まとめ

とりあえず、自作テレプロンプタは製作できました。パネルの表示位置とタッチ位置との不一致と、映像表示の時間遅れの2点を解決したいです。