raspberrypiにUVCカメラをつけて、HTTPでストリーミングを行いたいと考えた。
mjpg-streamerを使用することにしたが、
mjpg-streamerはレシピ化されていないため、レシピを自作する必要があった。^1
recipetoolの使用
レシピを作成する場合、ゼロから作成することもできるが、recipetool
を使用して雛形を作成することができる。
recipetoolを実行するにはbitbakeと同様にoe-init-build-env
をsourceコマンド等で読み込んでおく必要がある。
作業ディレクトリは%HOME/work/yocto/rpi
とする。
$ cd %HOME/work/yocto/rpi
$ source poky/oe-init-build-env build_webcam
mjpg-streamerのレシピを作成するには以下のコマンドを実行する。
$ recipetool create -o mjpg-streamer_git.bb --src-subdir=mjpg-streamer-experimental https://github.com/jacksonliam/mjpg-streamer.git
recipatoolはプロジェクトの中身を解析して、そのプロジェクトで使用しているautomakeやcmakeなどのビルドシステムに対応したレシピの雛形を生成する。
デフォルトではビルドシステムのソースディレクトリ=プロジェクトのルートディレクトリとして解析を行うが、mjpg-streamerではmjpg-streamer-experimentalがソースディレクトリとなっている。
その場合は--src-subdir=mjpg-streamer-experimental
オプションでソースディレクトリを指定することができる。
生成されたレシピは コード 1 のようになる。
コード 1: recipetoolで生成されたレシピ
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)
#
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
#
# NOTE: multiple licenses have been detected; if that is correct you should separate
# these in the LICENSE value using & if the multiple licenses all apply, or | if there
# is a choice between the multiple licenses. If in doubt, check the accompanying
# documentation to determine which situation is applicable.
LICENSE = "GPLv2 Unknown"
LIC_FILES_CHKSUM = "file://LICENSE;md5=751419260aa954499f7abaabaa882bbe \
file://www/LICENSE.txt;md5=713496289346a6c1c265f0e1f615ecd0"
SRC_URI = "git://github.com/jacksonliam/mjpg-streamer.git;protocol=https"
# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git/${BPN}-experimental"
# NOTE: unable to map the following CMake package dependencies: OpenCV Numpy Gphoto2
# NOTE: the following library dependencies are unknown, ignoring: v4l2
# (this is based on recipes that have previously been built and packaged)
DEPENDS = "libjpeg-turbo libsdl"
inherit cmake python-dir
# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""
mjpg-streamerはcmakeでビルドしているためinherit cmake
となっている。
その他、依存関係なども自動的に解決されている。
レシピのビルド
生成されたレシピがビルドできるかどうかbitbakeを実行してみる。
recipetoolで生成したmjpg-streamer_git.bb
はビルドディレクトリである%HOME/work/yocto/rpi/build_webcam
に格納されている。
これはどのレイヤにも属していない状態であるため、bitbakeの対象にならない。
そこで、作業用のレイヤmeta-webcam
を作成し、mjpg-streamer_git.bb
を含めるようにする。
下記の手順で作成する。
$ cd $HOME/work/yocto/rpi/build_webcam
$ mkdir -p $HOME/work/yocto/rpi/poky/meta-webcam/conf
$ mkdir -p $HOME/work/yocto/rpi/poky/meta-webcam/recipes-multimedia/mjpg-streamer
$ mv ./mjpg-streamer_git.bb $HOME/work/yocto/rpi/poky/meta-webcam/recipes-multimedia/mjpg-streamer
$ cat << 'EOF' > $HOME/work/yocto/rpi/poky/meta-webcam/conf/layer.conf
# We have a conf and classes directory, append to BBPATH
BBPATH .= ":${LAYERDIR}"
# We have a recipes directory containing .bb and .bbappend files, add to BBFILES
BBFILES += "${LAYERDIR}/recipes*/*/*.bb \
${LAYERDIR}/recipes*/*/*.bbappend"
BBFILE_COLLECTIONS += "webcam"
BBFILE_PATTERN_webcam := "^${LAYERDIR}/"
BBFILE_PRIORITY_webcam = "10"
LAYERDEPENDS_webcam = "core"
EOF
レイヤの構成は下記のツリーの様になる。
meta-webcam
├── conf
│ └── layer.conf
└── recipes-multimedia
└── mjpg-streamer
└── mjpg-streamer_git.bb
bblayers.conf
bblayers.confはbitbakeがビルド対象とするレイヤを定義する。
以下の手順で、bblayers.confの内容を置き換える。
$ cd $HOME/work/yocto/rpi/build_webcam
$ mv ./conf/bblayers.conf ./conf/bblayers.conf.bak
$ cat << 'EOF' > ./conf/bblayers.conf
# POKY_BBLAYERS_CONF_VERSION is increased each time build/conf/bblayers.conf
# changes incompatibly
POKY_BBLAYERS_CONF_VERSION = "2"
BBPATH = "${TOPDIR}"
BBFILES ?= ""
LAYERSTOP = "${TOPDIR}/.."
BBLAYERS ?= " \
${LAYERSTOP}/poky/meta \
${LAYERSTOP}/poky/meta-poky \
${LAYERSTOP}/poky/meta-yocto-bsp \
${LAYERSTOP}/poky/meta-raspberrypi \
${LAYERSTOP}/poky/meta-webcam \
"
EOF
local.conf
local.confは生成されたそのままの状態では、qemux86向けのイメージを作成するようになっているため、
raspberrypi向けのイメージが作成されるようにする。
コード 2 の内容をlocal.confの先頭の方に追加する。
コード 2: local.conf(抜粋)
MACHINE ?= "raspberrypi"
BB_NUMBER_THREADS ?= "${@oe.utils.cpu_count()}"
PARALLEL_MAKE ?= "-j ${@oe.utils.cpu_count()}"
GPU_MEM = "128"
DL_DIR ?= "${HOME}/work/yocto/downloads"
IMAGE_INSTALL_append = " mjpg-streamer"
bitbake実行
$ cd $HOME/work/yocto/rpi/build_webcam
$ bitbake mjpg-streamer
この時点でエラーが発生しなければ、ビルドまでは成功している。
以下の手順で結果を確認する。
$ cd tmp/work/arm1176jzfshf-vfp-poky-linux-gnueabi/mjpg-streamer/1.0+gitAUTOINC+2bd6f2c28d-r0/
$ tree ./image
treeの結果を以下に示す。
./image
└── usr
├── bin
│ └── mjpg_streamer
├── lib
│ └── mjpg-streamer
│ ├── input_file.so
│ ├── input_http.so
│ ├── input_uvc.so
│ ├── output_file.so
│ ├── output_http.so
│ ├── output_rtsp.so
│ ├── output_udp.so
│ └── output_viewer.so
└── share
└── mjpg-streamer
└── www
├── JQuerySpinBtn.css
├── JQuerySpinBtn.js
├── LICENSE.txt
├── bodybg.gif
├── cambozola.jar
├── control.htm
├── example.jpg
├── favicon.ico
├── favicon.png
├── fix.css
├── functions.js
├── index.html
├── java.html
├── java_control.html
├── java_simple.html
├── javascript.html
├── javascript_motiondetection.html
├── javascript_simple.html
├── jquery.js
├── jquery.rotate.js
├── jquery.ui.core.min.js
├── jquery.ui.custom.css
├── jquery.ui.tabs.min.js
├── jquery.ui.widget.min.js
├── rotateicons.png
├── sidebarbg.gif
├── spinbtn_updn.gif
├── static.html
├── static_simple.html
├── stream.html
├── stream_simple.html
├── style.css
└── videolan.html
無事にビルドおよび、ローカルへのインストールは成功している。
しかし、このままではOSイメージのRootFSへ反映されない。
インストールされたファイルをRootFSへ反映されるようにするためには、
レシピでFILES_${PN}
を定義する。
また、bitbakeした時にLicense関連でエラーが発生しているので、GPLv2 Unknown
からGPLv2
に変更する。
それらの修正を行った、一応の完成版のmjpg-streamer_git.bb
を
lst:mjpg_streamer_git_bb に示す。
コード 3: mjpg-streamer\_git.bb(完成版)
# Recipe created by recipetool
# This is the basis of a recipe and may need further editing in order to be fully functional.
# (Feel free to remove these comments when editing.)
#
# WARNING: the following LICENSE and LIC_FILES_CHKSUM values are best guesses - it is
# your responsibility to verify that the values are complete and correct.
#
# NOTE: multiple licenses have been detected; if that is correct you should separate
# these in the LICENSE value using & if the multiple licenses all apply, or | if there
# is a choice between the multiple licenses. If in doubt, check the accompanying
# documentation to determine which situation is applicable.
LICENSE = "GPLv2"
LIC_FILES_CHKSUM = "file://LICENSE;md5=751419260aa954499f7abaabaa882bbe \
file://www/LICENSE.txt;md5=713496289346a6c1c265f0e1f615ecd0"
SRC_URI = "git://github.com/jacksonliam/mjpg-streamer.git;protocol=https"
# Modify these as desired
PV = "1.0+git${SRCPV}"
SRCREV = "${AUTOREV}"
S = "${WORKDIR}/git/${BPN}-experimental"
# NOTE: unable to map the following CMake package dependencies: OpenCV Numpy Gphoto2
# NOTE: the following library dependencies are unknown, ignoring: v4l2
# (this is based on recipes that have previously been built and packaged)
DEPENDS = "libjpeg-turbo libsdl"
inherit cmake python-dir
# Specify any options you want to pass to cmake using EXTRA_OECMAKE:
EXTRA_OECMAKE = ""
FILES_${PN} = "${bindir}/* \
${libdir}/* \
${datadir}/* \
${sysconfdir}* \
"
イメージの作成
以下のコマンドを実行してOSイメージを作成する。
$ bitbake rpi-basic-image
イメージの書き込み
ddコマンドでrpi-basic-image-raspberrypi.rpi-sdimg
をSDカードに書き込む。
sudo dd if=tmp/deploy/images/raspberrypi/rpi-basic-image-raspberrypi.rpi-sdimg of=/dev/sdb bs=40M
実行
UVCカメラを接続したraspberrypiをSDカードのイメージで起動する。
ログインしたあと、以下のコマンドでmjpg-streamerを実行する。
mjpg_streamer -i "input_uvc.so -y" -o "output_http.so -w /usr/share/mjpg-streamer/www"
ブラウザでhttp://XXX.XXX.XXX.XXX:8080/?action=stream
にアクセスして、カメラの映像が表示されれば成功。
XXX.XXX.XXX.XXXはraspberrypiのIPアドレス