2023/10/22(日)

FFmpeg apiによるRTMP映像送信を色々実験してみている。Windows環境だと以下のことをするだけで非常に簡単に、動画出力と同じ要領で成功した。

  • 出力先をrtmp://形式のURLとする
  • AVFormatContextの初期化時、avformat_alloc_output_context2の第3引数に"flv"形式を指定
  • 1フレーム送る毎に適宜次のフレームを送るのに適当な時間まで待機

ただ、同じコードをDocker環境に持っていったら全然動作しない。おそらくLinux環境だと勝手が違うということのように思われる。

  • しばらく動作したのちにav_interleaved_write_frame()End of fileエラーを吐いて停止。検索したところlibrtmpの問題であり、librtmpを無効化すればよいとのこと。(参考)
  • librtmpを無効化したところ、avcodec_open2Invalid argumentエラー。どうやら使われるエンコーダがlibx264からh264_v4l2m2mに変わっているように見える。
  • コーデックから適合するエンコーダを勝手に選ぶavcodec_find_encoderではなく明示的に特定のエンコーダを指定できるavcodec_find_encoder_by_nameを利用したところ、"libx264"の指定でエラー。
  • av_codec_iterateでコーデック一覧を表示したところ、どうやらlibrtmpを無効化した結果libx264も無効化されている。

ここで、そもそもエンコーダがどうなっているのかを整理。使いたいコーデックとしてはh264だが、それに対応したエンコーダがいくつもある。

  • h264_mf: Windowsで何も指定しない場合に選ばれる模様。快調に動く。
  • libx264: vcpkgで[x264]を指定した場合(=configureで–enable-libx264した場合)に選ばれる。Docker環境で途中で動かなくなる。驚いたことにWindows環境でも動かなくなる。
  • h264_v4l2m2m: Docker環境でlibx264が使えない場合に選ばれる模様。avcodec_open2で死ぬ。

ということで、実はh264_mf以外のエンコーダで正常動作が見れていない。libx264に任せておけば安心じゃなかったのかよ!

Categories: