Raspberry Pi並の大きさながらコア128基のGPUを詰んだシングルボードコンピュータ、Jetson Nanoをご存じでしょうか。エッジデバイスで機械学習にチャレンジしたい人たちに人気のデバイスで、金額も高くないことから並列実行するのにも向いています。

今回はそんなJetson Nanoを使って動画配信、それもYouTube Live配信にチャレンジしてみました。今回のチャレンジのきっかけはYouTubeが2019年3月から1000人以上のフォロワーがいないとスマホからの配信が出来なくなったことです。同じ問題でお困りの方にこの記事はきっと役に立つはずです。

配信の基本

Raspberry PiにもGPU(Broadcom VideoCore IV)は積まれていますが、サイズが小さいので高速な動画変換処理などには向いていません。配信を行ったとしても画質も悪く、FPSも5程度でしょう。定点カメラなどであれば十分ですが、よりインタラクティブな利用には向きません。

今回はJetson Nanoにロジクール社のWebカメラ、C922を接続しています。このC922は1080pでの撮影はもちろん、マイクもついています。このC922を使って動画と音声を取り込み、そのままYouTube Liveに配信します。

Gstreamerの利用

動画の配信というとFFMPEGを思い浮かべますが、NVIDIAのフォーラムによるとFFMPEGはサポートされていません。その代わりにGStreamerがサポートされています。そこで、今回はGStreamerを使っています。

OSのインストール

JetsonのOSインストールはかつては面倒だったようですが、JetPackを使うことでRaspbian並に簡単になります。まずイメージをダウンロードします。

JetPack | NVIDIA Developer

このイメージファイルをSDカードに焼き込みます。焼き込みはEtcherを使うと簡単でしょう。

ライブラリのインストール

そしてGstreamerをインストールします。

$ sudo apt-get install libgstreamer1.0-0 gstreamer1.0-plugins-base \
                       gstreamer1.0-plugins-good gstreamer1.0-plugins-bad \
                       gstreamer1.0-plugins-ugly gstreamer1.0-libav \
                       gstreamer1.0-doc gstreamer1.0-tools \
                       gstreamer1.0-x gstreamer1.0-alsa \
                       gstreamer1.0-gl gstreamer1.0-gtk3 \
                       gstreamer1.0-qt5 gstreamer1.0-pulseaudio

Webカメラの認識を確認

まずカメラとして認識されているかは下記のコマンドで分かります。この場合は Logitech, Inc. が該当します。そして /dev/video0 が存在するのを確認してください。

$ lsusb
Bus 002 Device 002: ID 0bda:0411 Realtek Semiconductor Corp. 
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 003: ID 05af:0808 Jing-Mold Enterprise Co., Ltd 
Bus 001 Device 004: ID 046d:085c Logitech, Inc. 
Bus 001 Device 002: ID 0bda:5411 Realtek Semiconductor Corp. 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

マイクの認識は下記のコマンドで確認できます。この場合はcard 22という数字が肝になります。

$ arecord -l
**** List of CAPTURE Hardware Devices ****
  :
card 2: Webcam [C922 Pro Stream Webcam], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

YouTube Liveを作成する

YouTubeの管理画面からLive配信を作成します。YouTube Liveは申請が必要で、最初は一日程度待たなければなりません。配信をしようと思ったら事前に申請しておくのが良いでしょう。そして、エンコーダ配信を選択します。

そうするとストリームURLとして rtmp://a.rtmp.youtube.com/live2 、ストリームキーが生成されます(ストリームキーは通常閲覧できないようになっています)。

この時、Gstreamerのコマンドは次のようになります。動画サイズを1920×1080、30fps、ビットレートは6Mbpsとしています。

$ gst-launch-1.0 -v -e v4l2src device=/dev/video0 ! videorate ! \
    'video/x-raw, width=(int)1920, height=(int)1080, framerate=30/1' ! \
    nvvidconv ! \
    'video/x-raw(memory:NVMM), width=(int)1920, height=(int)1080, framerate=30/1' ! \
    omxh264enc bitrate=6000000 iframeinterval=1 ! video/x-h264 ! h264parse ! \
    queue ! flvmux name=mux streamable=true ! \
    rtmpsink location=rtmp://a.rtmp.youtube.com/live2/(ストリームキー) \
    alsasrc device=hw:(カードの番号) ! queue ! audioresample ! audioconvert ! \
    audioresample ! audio/x-raw,rate=48000 ! \
    voaacenc bitrate=128000 ! audio/mpeg ! aacparse ! audio/mpeg, mpegversion=4 ! mux.

実行して少しするとYouTubeの管理画面でプレビューが確認できます。なお、この数字の設定については色々と変えながら微調整したものです。カメラの性能や取り込む動画のサイズによって変わってくるはずです。

実際にテストしているところです。

Webカメラの性能について

Webカメラによって性能が異なり、撮影できる動画サイズが異なります。その時には下記のコマンドで性能を確認できます。今回用いたC922は1920×1080(1080p)で30fpsまで出せるのが分かります。

$ v4l2-ctl --list-formats-ext --device=/dev/video0
ioctl: VIDIOC_ENUM_FMT
  :(省略)
    Index       : 1
    Type        : Video Capture
    Pixel Format: 'MJPG' (compressed)
    Name        : Motion-JPEG
    :(省略)
        Size: Discrete 1920x1080
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.042s (24.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.133s (7.500 fps)
            Interval: Discrete 0.200s (5.000 fps)

まとめ

Gstreamerのオプションは独特で、かつ多数あります。また、GPUはどんなソフトウェアからも触れるものではないので、情報を調べつつトライしてみる必要があります。そんな中、NVIDIAのGstreamerユーザガイドが役立ちましたので参考にしてください。

Jetson NanoとWebカメラでのYouTube Live配信は、勉強会などでのリアルタイム配信にも使えるでしょう。機械学習以外の用途でも活躍できそうです。


0 Comments

Leave a Reply

Your email address will not be published. Required fields are marked *