复杂的 ffmpeg 多编码/流复制/多路复用场景:这实际上可行吗?

复杂的 ffmpeg 多编码/流复制/多路复用场景:这实际上可行吗?

我正在尝试使用 ffmpeg 对输入视频进行多次复用/重新编码/复制操作,但尝试的方法遇到了障碍;在继续测试之前,我想确认该软件是否真的可以做到这一点。(这是针对实时流媒体设置,它从我的 LAN 上的另一台 PC 接收一个实时流,并将其存档/重新流式传输到多个 RTMP 目标,因此需要标记-re并需要在一次操作中完成所有操作。)

输入视频有一个高比特率的h.264视频流和四个PCM音轨。

我需要的三个输出:

  • 一个 8Mbps 的 h.246 编码,仅音频轨道 1 的 aac 编码
  • 一个 12Mbps 的 h.264 编码,仅对音轨 1 进行 aac 编码(理想情况下使用与第一个输出相同的编码,即只需对音频进行一次编码)
  • 将整个输入纯流复制到 .mkv

(这些命令可能充满错误和不良做法,只是我要走的方向的一个大致想法。)

我已经尝试将split/asplit过滤器与tee多路复用器结合使用,这在理论上似乎是可行的,只是使用过滤器不允许流复制/编解码器直通(具有讽刺意味的是,在这种情况下,除了传递视频流之外,没有对视频流进行任何实际的过滤)。

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"

我也尝试过将简单的流映射到多个输出,但似乎它实际上只处理一个视频和音频输出,而且我不确定流映射是否可以通过这种方式使用,所以这个可能会很混乱。

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"

更复杂的是,我在这里使用快速同步硬件编码,并希望-vf hwupload=extra_hw_frames=64,format=qsv在可能的情况下将其应用于每次重新编码,但在我的初步测试中,不清楚是否可以采用两组过滤器,即使在不同的编码上。

无论如何,这是否可以通过 ffmpeg 实现?如果可以,如何实现?

答案1

我们可能会使用tee 解复用器重新使用编码的 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) 和“第二个”( 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"- 将相同的编码音频流与两个不同的视频流“混合”。
    第一个输出视频流 ( 0) 被“混合”到8mbps.mkv输出文件。
    第二个输出视频流 ( 1) 被“混合”到12mbps.mkv输出文件。
  • -map 0 -c copy copy.mkv- 应用第二个输出(因为它位于第一个输出之后)。
    -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编码器(我没有尝试解决这个问题)。

相关内容