shell
RaspberryPi
IoT

Motion-Project/motionによる録画内容を、外部トリガをもとに動画生成する

前置き

RaspberryPiにカメラを接続し、録画や動画の生成を行うには、Motion-Project/motionが便利です。
簡単に導入することができ、また、USBカメラだけではなくRasPi純正のカメラにも対応しております [参考]。

しかし、Motion-Project/motionは、録画&動画の生成を開始するトリガとして、

  • motionプロセスが起動してから常に録画&動画の生成を行う
  • 動体を検知した場合に録画&動画の生成を行う

という設定を行うことができますが、ユーザ任意のタイミングで録画&動画の生成を行う、という設定ができません(少なくとも私の調べた限りでは)。
つまり、RasPiに向かって「今から10秒間録画してほしいんだけど・・・」とか「別のセンサが反応したときに録画を開始して」、ということができません。

それをなんとか、ワークアラウンド的に解決します。

ちなみにドキュメントのここにあるsignalや、ここにあるAPIに、

Motion will create an movie file of the current event.

など、動画を作る的な内容が書いてありますが、どうやら、現在の録画内容を動画に吐き出すための機能ではないようです(よくわかりません)。

やりたいこと

motionが録画している内容について、外部トリガをもとに動画生成します。

環境

  • RasbperryPi3
  • RasPi純正カメラ
$ lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 9.1 (stretch)
Release:        9.1
Codename:       stretch

$ motion -h
motion Version 4.1.1, Copyright 2000-2017 Jeroen Vreeken/Folkert van Heusden/Kenneth Lavrsen/Motion-Project maintainers

方法1

motionに常に録画&動画の生成をする設定をして、
トリガをもとに、任意秒だけmotionプロセスを立ち上げたり殺したりします。
単純ですが、motionが立ち上がるまでにラグがあります。

方法2

この記事を書いてる途中で見つけてしまいました。
HTTP APIのconfigに対して、emulate_motionをon/offさせることで実現できます。

# 録画開始
curl -s http://localhost:#{webcontrol_port}/0/config/set?emulate_motion=on
sleep 10
# 録画終了
curl -s http://localhost:#{webcontrol_port}/0/config/set?emulate_motion=off

動画は設定ファイルのtarget_dirに作られます。
motionの再起動も必要もありません。

追記:
この方法は、どうやら4.1系では動作しないようです。
https://github.com/Motion-Project/motion/issues/606

方法3

motionは、localhostに対して現在録画している内容をストリームで流しているため、
そこから内容を取得して動画を生成します。
以下のようなコマンドを実行し、動画を生成します。

$ ffmpeg -i http://localhost:#{stream_port} -an -t 00:00:10 out.mp4

エンコードされているものを、再度ffmpegで動画生成しているため、motionが生成するオリジナルの動画より画質がやや悪くなります。

雑談

方法2のconfigをon/offする方法が、今のところ一番よさそうです。
SIGUSER1makemovieが動作しないのが、いまいち納得できませんが・・・。
ソースコードは、途中まで追っかけてやめました。暇なときにまた見てみることにします。