
ffmpeg を使用して入力ビデオに対して複数の多重化/再エンコード/コピー操作を実行しようとしていますが、試した方法で障害に遭遇しました。テストを続ける前に、これがソフトウェアで実際に可能かどうかを確認したいと思います。(これは、LAN 上の別の PC から 1 つのライブ ストリームを取得し、それを複数の RTMP ターゲットにアーカイブ/再ストリームするライブ ストリーミング セットアップ用です。そのため、フラグがあり-re
、すべてを 1 つの操作で実行する必要があります。)
入力ビデオには、高ビットレートの h.264 ビデオ ストリームが 1 つと、PCM オーディオ トラックが 4 つあります。
必要な 3 つの出力:
- 8Mbps での h.246 エンコード 1 回、オーディオ トラック 1 のみの aac エンコード
- 12Mbps での h.264 エンコード 1 回、オーディオ トラック 1 のみの aac エンコード (理想的には最初の出力と同じエンコードを使用する、つまりオーディオを 1 回だけエンコードすればよい)
- 入力全体を .mkv に純粋にストリームコピーする
(これらのコマンドにはエラーや悪い習慣がたくさんあるかもしれませんが、これは私が目指している方向性についての大まかなアイデアにすぎません。)
私は、この方向に沿ってsplit
/asplit
フィルターを muxer と組み合わせて使用してみましtee
たが、フィルターを使用すると streamcopy/codec のパススルーが許可されないことを除けば、理論的には機能するようです (皮肉なことに、この場合、ビデオ ストリームを通過させる以外に、実際のフィルタリングは行われません)。
ffmpeg -re -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv -c:v h264_qsv -i $INPUT \
-filter_complex "[0:v]split=3[twitch][youtube][passv];[0:a]asplit[stream][passa]" \
-map:v "[twitch]" -map:v "[youtube]" -map:v "[passv]" -map:a "[stream]:0" -map:a "[passa]" \
-c:v:0 h264_qsv -profile:v:0 high -preset:v:0 medium -g 120 -b:v:0 8M -maxrate:v:0 8M -bufsize:v:0 4M \
-c:v:1 h264_qsv -profile:v:1 high -preset:v:0 medium -g 120 -b:v:1 12M -maxrate:v:1 12M -bufsize:v:1 6M \
-c:v:2 copy \
-c:a:0 aac -b:a:0 320k \
-c:a:1 copy \
-f tee "[select=\'v:0,a:0\']8mbps.mkv|[select=\'v:1,a:0\']12mbps.mkv|[select=\'v:2,a:1\']copy.mkv"
また、複数の出力への単純なストリーム マッピングも試してみましたが、実際にはビデオ出力とオーディオ出力をそれぞれ 1 つずつしか処理していないようで、ストリーム マッピングをこのように使用できるかどうかもわからないため、この方法はおそらく混乱を招きます。
ffmpeg -re -init_hw_device qsv=hw -filter_hw_device hw -hwaccel qsv -hwaccel_output_format qsv -c:v h264_qsv -i $INPUT \
-map 0:0 -c h264_qsv -profile high -preset medium -g 120 -b 8M -maxrate 8M -bufsize 4M \
-map 0:0 -c h264_qsv -profile high -preset medium -g 120 -b 12M -maxrate 12M -bufsize 6M \
-map 0:1 -c aac -b 320k \
-map 0:a -c copy \
-f tee "[select=\'v:0,a:0\']8mbps.mkv|[select=\'v:1,a:1\']12mbps.mkv|[select=\'v:2,a:1\']copy.mkv"
さらに複雑なことに、ここでは Quick Sync ハードウェア エンコードを使用しており、-vf hwupload=extra_hw_frames=64,format=qsv
可能であれば各再エンコードに適用したいのですが、最初のテストでは、異なるエンコードであっても 2 セットのフィルターが可能かどうかは不明でした。
いずれにせよ、これは ffmpeg で実現可能でしょうか。もし可能であれば、どのように実現するのでしょうか。
答え1
我々は使用する可能性があるティーデマルチプレクサエンコードされたAACオーディオを再利用し、ストリームマッピング、 そしてストリーム指定子:
ffmpeg -y -c:v h264_qsv -i in.mkv -map 0:v -map 0:v -map 0:a -c:v:0 h264_qsv -profile:v:0 high -preset:v:0 medium -g 120 -b:v:0 8M -minrate:v:0 8M -maxrate:v:0 8M -c:v:1 h264_qsv -profile:v:1 high -preset:v:1 medium -g 120 -b:v:1 12M -minrate:v:1 12M -maxrate:v:1 12M -c:a:0 aac -b:a:0 320k -f tee "[select=\'v:0,a\']8mbps.mkv|[select=\'v:1,a\']12mbps.mkv" -map 0 -c copy copy.mkv
-re
必要に応じて入力と出力を追加および置き換えます。
-c:v h264_qsv
- QSV H.264 ハードウェア アクセラレーション デコードを適用します ( も使用される場合があります-hwaccel qsv
)。-map 0:v -map 0:v -map 0:a
- 入力ビデオ ストリームを「最初の」(0
) および「2 番目の」(1
) 出力ビデオ ストリームにマッピングします (オーディオ ストリームもマッピングします)。-c:v:0 h264_qsv -profile:v:0 high -preset:v:0 medium -g 120 -b:v:0 8M -minrate:v:0 8M -maxrate:v:0 8M
-h264_qsv
出力ビデオ ストリームに適用されるすべてのパラメータを使用して、ビデオ エンコーダーを選択します0
。-c:v:1 h264_qsv -profile:v:1 high -preset:v:1 medium -g 120 -b:v:1 12M -minrate:v:1 12M -maxrate:v:1 12M
-h264_qsv
出力ビデオ ストリームに適用されるすべてのパラメータを使用して、ビデオ エンコーダーを選択します1
。-c:a:0 aac -b:a:0 320k
- オーディオ エンコーダーとビットレートを選択します。-f tee "[select=\'v:0,a\']8mbps.mkv|[select=\'v:1,a\']12mbps.mkv"
- 同じエンコードされたオーディオ ストリームを 2 つの異なるビデオ ストリームと「多重化」します。
最初の出力ビデオ ストリーム (0
) は出力ファイルに「多重化」され8mbps.mkv
ます。2
番目の出力ビデオ ストリーム ( ) は出力ファイル1
に「多重化」されます。12mbps.mkv
-map 0 -c copy copy.mkv
- 2 番目の出力を適用します (最初の出力の後に来るため)。
-map 0
- 入力からのすべての入力ストリームを出力にマップします。
-c copy
- 再エンコードせずにすべての入力ストリームをコピーします。
テスト用に合成ビデオファイルを作成しましたin.mkv
:
ffmpeg -y -f lavfi -i mandelbrot=size=1920x1080:rate=30 -f lavfi -i sine=frequency=400 -c:v libx264 -strict -2 -c:a dca -ar 44100 -pix_fmt yuv420p -t 5 in.mkv
ノート:
-b:v:0 4M -minrate:v:0 4M -maxrate:v:0 4M
一定のビットレートを適用します (本当に必要かどうかはわかりません)。bufsize
引数はエンコーダーでは機能しませんh264_qsv
(これを解決しようとはしませんでした)。