OpenH264とDockerを用いて動画解析環境を構築する

f:id:aptpod_tech-writer:20200407192117j:plain

先端技術調査グループの南波です。ウイルスは大変な状況ですが、原則自宅勤務となったことで息子2人のお昼寝を眺められる時間が増え、すこしほっこりもしています☺️

さて、今回は最近のお仕事の中で

  • intdashのサーバーに蓄積されているH.264の動画データを解析したい
  • H.264のライセンスはもちろんクリーンに対処したい
  • プロダクト投入時には Amazon ECSなども利用してスケールさせたいので、解析環境はDocker上に用意したい

といった課題に対しOpenH264をDocker上で利用する方法を調査・検証したので、その内容の共有です。

背景

過去の独自ビデオエンコーダの記事でもご紹介あったように、弊社ではH.264のコーデックで圧縮された動画データを収集・伝送・保存・可視化するために必要となるハードウェア/ソフトウェアの開発にも力を入れています。

となると、もちろん次のステップとしては「その動画データを解析したい!機械学習したい!!」となり、実際に弊チームでもいくつかのテーマで取り組みを行なっています。

しかしいざ「作ったものをサービスとしてみなさまに使っていただこう」という段になると、重要な検討ポイントが浮かんできます。H.264のライセンスの扱いです。(参考:AVC/H.264 Patent Portfolio License Program | MPEG LA : MPEG LA

今回はOpenH264にて配布されているビルド済みバイナリを利用する方法を検討しました。

また、弊社のintdash Analytics ServicesではPythonスクリプトからSDKを用いてintdashに保存されている動画データにアクセスできることや、NumPy / Pandas / Tensorflow / PyTorchといった数値演算・機械学習ライブラリと併用することを見据えて、Pythonから動画データを扱うことを目指しました。

f:id:aptpod_tech-writer:20200406155016p:plain
intdashアセット図

(免責:ケースバイケースでライセンスへの対応方法は異なるかと思いますので、同様の課題に取り組まれる際は各人で法務部等にご確認ください。当記事によって損害が生じた場合でも当社は責任を負いません)

実施内容

コードはaptpod/openh264-ffmpeg-pyです。

Dockerfileの中ではライセンス的にクリーンなH.264動画エンコードのやり方 - Qiitaを参考に、記事作成時点で最新のOpenH264バイナリの配置とFFmpegのインストールを行なっています。

Pythonスクリプトでは、サンプルの(Mac上のQuickTime Playerで画面収録した)H.264コーデックの.movファイルをフレーム毎にJPEGファイルにデコードし、そのJPEGファイル群をH.264でエンコードし直した .mp4 ファイルを作成しています。

実行時の出力が以下のようになっていることから、エンコードにlibopenh264を利用できていることを確認できました。

re-encode them to a mp4 file using libopenh264:
ffmpeg version n4.2.2 Copyright (c) 2000-2019 the FFmpeg developers
  built with gcc 8 (Debian 8.3.0-6)
  configuration: --enable-libopenh264 --enable-libmp3lame --enable-libopus --enable-libvorbis --enable-libvpx
  libavutil      56. 31.100 / 56. 31.100
  libavcodec     58. 54.100 / 58. 54.100
  libavformat    58. 29.100 / 58. 29.100
  libavdevice    58.  8.100 / 58.  8.100
  libavfilter     7. 57.100 /  7. 57.100
  libswscale      5.  5.100 /  5.  5.100
  libswresample   3.  5.100 /  3.  5.100
Input #0, image2, from '/tmp/%05d.jpg':
  Duration: 00:00:14.44, start: 0.000000, bitrate: N/A
    Stream #0:0: Video: mjpeg (Baseline), yuvj420p(pc, bt470bg/unknown/unknown), 2052x728 [SAR 1:1 DAR 513:182], 25 fps, 25 tbr, 25 tbn, 25 tbc
Stream mapping:
  Stream #0:0 -> #0:0 (mjpeg (native) -> h264 (libopenh264))

今後は今回のスクリプトをベースに、中間出力物であるJPEGファイルを機械学習モデルに食わせた結果をオーバーレイしたり、逐次入力されるH.264のユニットを取り扱えるようにしたりなどの要素を追加していき、過去のお菓子の高速検出システムの記事のようなことも同等に実現できるようにしていきます 💪