web-dev-qa-db-ja.com

FFmpegを使用してiOSで書き込み中にfMP4をHLSにトランスコードする

TL; DR

IOSデバイスでFFmpegを使用してフラグメントが書き込まれているため、fMP4フラグメントをTSセグメント(HLS用)に変換したいと思います。

どうして?

シームレスなHDコピーをローカルで維持しながら、iOSでライブアップロードを実現しようとしています。

私が試したこと

  1. AVAssetWritersをローリングし、それぞれが8秒間書き込みを行ってから、FFmpegを介してMP4を連結します。

    何が悪かったのか-オーディオとビデオに時々ブリップがあります。私はこれの3つの理由を特定しました。

    1)ギャップを作成するAACエンコーダーによって書き込まれたオーディオのプライミングフレーム。

    2)ビデオフレームの長さは33.33ミリ秒、オーディオフレームの長さは0.022ミリ秒であるため、ファイルの最後に並んでいない可能性があります。

    3)Mac OSにはフレーム精度の高いエンコーディングがないが、iOSでは利用できない 詳細はこちら

  2. FFmpegは、生のオーディオを含む大きなビデオのみのMP4ファイルをTSセグメントに多重化します。作業は Kickflip SDK に基づいていました

    何が悪かったのか-たまに音声のみのファイルがアップロードされ、ビデオはまったくありませんでした。社内で再現することはできませんでしたが、ユーザーが自分の考えていることを記録しなかったため、ユーザーはかなり腹を立てました。 TSセグメントに誤ったタイムスタンプが付けられたように、最終セグメントでの正確なシークにも問題がありました。

私が今考えていること

Appleは今年(2016年)にWWDCでfMP4をプッシュしていましたが、それまではあまり調べていませんでした。 fMP4ファイルは読み取って再生できるのでwhile書き込み中なので、FFmpegは、ファイルの送信を保留している限り、書き込み中にファイルをトランスコードすることも可能だと思いました。ファイル内の各フラグメントが終了するまで、バイトをFFmpegに変換します。

しかし、私はFFmpeg C APIに精通しておらず、試行#2で簡単に使用しただけです。

私があなたから必要なもの

  1. これは実行可能な解決策ですか?私が実際にこれを達成できるかどうかを知るのに十分なfMP4に精通している人はいますか?
  2. AVFoundationがファイル内のフラグメントの書き込みを終了し、FFmpegにパイプできるようになったことをどのようにして知ることができますか?
  3. ディスク上のファイルからデータを取得し、一度にチャンクして、FFmpegに渡し、TSセグメントを吐き出すにはどうすればよいですか?
57
bclymer

厳密に言えば、h264 + aacが含まれている場合はfmp4をトランスコードする必要はなく、サンプルデータをTSとして再パッケージ化するだけです。 (ffmpeg -codec copyまたは gpac を使用)

に関して。アラインメント(1.2)これはすべてエンコーダー設定(フレームレート、サンプルレート、GOPサイズ)に依存すると思います。オーディオとビデオがフラグメントの境界で正確に整列していることを確認することは確かに可能です(例: この表 を参照)。 iOSをターゲットにしている場合は、 HLSプロトコル バージョン3(または4)を使用して、タイミングをより正確に表現できるようにすることをお勧めします。これにより、オーディオとビデオを別々に(多重化せずに)ストリーミングすることもできます。

Ffmpegはライブfmp4ストリームをプッシュできるはずだと思います(つまり、長時間実行されるHTTP POSTを使用します)が、プレイアウトには Originソフトウェア が何か意味のあることをする必要があります(つまり、HLSへのストリーム)。

2
Tijn Porcelijn