はじめに
本記事はJetson Nanoに取り付けたカメラC920を使って映像と音声をRTSPで配信する試みである。
この記事の前に「Jetson Nanoでストリーミング配信を行う」でC920の映像をMotion JPEGで配信する試みを行った。うまく動作したかに見えたが、悲しいことにiPhoneのブラウザではMotion JPEGを再生することができなかった。さらにはiPhoneにインストールしたVLCでもこのMotion JPEGは見えなかった。
仕方がないのでGStreamerを使ってiPhoneでも閲覧可能な配信を行うことにした。またC920はカメラの両サイドにマイクがついており映像と音声の両方が取得できるので、これを同じネットワーク内に接続された別の端末から受信したいと思う。
環境
マシン | 役割 | 内容 |
---|---|---|
Jetson Nano | サーバ | 接続されたカメラ(C920)の映像・音声を配信 |
MacBook Air | クライアント | VLCを使ってサーバの映像・音声を受信 |
iPhone | クライアント | VLC Appを使ってサーバの映像・音声を受信 |
事前準備
カメラの状態を確認するためにv4l2-ctl
コマンドを使うため次のようにv4l-utils
パッケージをインストールしておく。
sudo apt install v4l-utils
また恒例となりつつあるRTSPで配信するためのtest-launchというプログラムを使用する。下記からダウンロードしてコンパイルする必要がある。
https://github.com/GStreamer/gst-rtsp-server/blob/master/examples/test-launch.c
sudo apt install libgstrtspserver-1.0-dev
gcc -o test-launch test-launch.c `pkg-config --cflags --libs gstreamer-rtsp-server-1.0`
C920について
対応フォーマット
C920は3種類のフォーマット(YUYV, H264, MJPG)に対応している。
$ v4l2-ctl -d /dev/video0 --list-formats
ioctl: VIDIOC_ENUM_FMT
Index : 0
Type : Video Capture
Pixel Format: 'YUYV'
Name : YUYV 4:2:2
Index : 1
Type : Video Capture
Pixel Format: 'H264' (compressed)
Name : H.264
Index : 2
Type : Video Capture
Pixel Format: 'MJPG' (compressed)
Name : Motion-JPEG
H264やMJPGと聞くと、あぁ動画で良く聞くアレか、と考えたが同時に「え!?C920ってH264で出せるの?」などと知ったのはつい先日の出来事である。
壮大なる勘違い
カメラとマイクがセットでついているので、漠然と「映像と音声の両方が含まれたコンテナ」がカメラの出力として渡されるものだと考えていた。すなわち下記のような設計になるものだと考えていた。
残念ながらこのイメージは間違っていて、正しくは下のようなイメージである。
カメラはカメラ、マイクはマイクとして、それぞれ設定することになる。
GStreamerの設定
カメラ編
自分の環境ではJetson NanoにUSBで取り付けたC920だけがある。他にカメラはないため/dev/video0
にカメラがある。
$ v4l2-ctl --list-devices
HD Pro Webcam C920 (usb-70090000.xusb-2.4):
/dev/video0
GStreamerのパイプラインでは、C920はH264で出力できるためRTSPのH264にそのまま渡せば良い。
v4l2src device=/dev/video0 ! video/x-h264,width=640,height=480,framerate=30/1 ! rtph264pay name=pay0 pt=96
マイク編
pactl list
コマンドで利用可能なマイクの一覧が表示される。長いのでalsa_input
だけを抽出する。
$ pactl list | grep alsa_input
Name: alsa_input.platform-sound.analog-stereo
Name: alsa_input.usb-046d_HD_Pro_Webcam_C920_87B53EDF-02.iec958-stereo
2つ目の長い文字列がC920のマイクのデバイス名である。これを使ってGStreamerのパイプラインを記述すると以下のようになる。
pulsesrc device=alsa_input.usb-046d_HD_Pro_Webcam_C920_87B53EDF-02.iec958-stereo ! audioconvert ! vorbisenc ! rtpvorbispay name=pay1 pt=97
特に意味はないが音声のコーデックにはVorbisを使った。
RTSPでの配信
あとは上の2つをマージするだけである。長いのでスクリプトにした。
スクリプト中のvideo_device
やaudio_device
は同じC920であっても環境ごとに異なるため、環境にあったデバイス名に置き換える必要がある。
#!/bin/bash
video_device=/dev/video0
audio_device=alsa_input.usb-046d_HD_Pro_Webcam_C920_87B53EDF-02.iec958-stereo
video=(
"v4l2src device=$video_device"
"video/x-h264,width=640,height=480,framerate=30/1"
"rtph264pay name=pay0 pt=96"
)
audio=(
"pulsesrc device=$audio_device"
"audioconvert"
"vorbisenc"
"rtpvorbispay name=pay1 pt=97"
)
pipeline_video="$(IFS=!; echo "${video[*]}" | sed 's/!/ ! /g')"
pipeline_audio="$(IFS=!; echo "${audio[*]}" | sed 's/!/ ! /g')"
pipeline="$pipeline_video $pipeline_audio"
echo "$pipeline"
./test-launch "$pipeline"
VLCでの受信
VLCを使ってのアクセスは下記のURLを開く。MacBook AirもiPhoneも同じである。
rtsp://IPアドレス:8554/test
RTSPで配信すると複数のクライアントで同時に受信が可能となる。iPhoneのVLC Appで受信しているところをカメラで撮像したのが下記である。
iPhoneでも動画が受信できているのが分かる。音も出ている!
まとめ
Jetson Nanoに取り付けたカメラC920
を使って、映像と音声の両方をRTSPにより配信することが可能となり、iPhoneのVLCを使って閲覧することが可能となった。