ffmpeg 使用来自同一源的 --filter_complex 和 tee 伪复用器对具有不同视频和音频设置的多个流进行处理

ffmpeg 使用来自同一源的 --filter_complex 和 tee 伪复用器对具有不同视频和音频设置的多个流进行处理

我正在从 DeckLink 迷你录音机录制带有嵌入音频的视频,需要创建 6 个不同的流。我已经为视频创建了过滤器,它可以工作,但无法弄清楚如何为每个流设置不同的音频设置。我需要一些视频使用 44100hz 的 AAC,其余视频使用 48000hz 的 Opus。有人能帮忙吗?

这是我现在使用的:

 /usr/bin/ffmpeg -thread_queue_size 2048 -f decklink -video_input sdi -audio_input embedded -i 'DeckLink Mini Recorder 4K' -threads 4 \
-filter_complex \
"[0:v]fps=25,split=6[s720][s540][s180][l720][l360][l180]; \
[s720]scale=-2:720[v720]; \
[s540]scale=-2:540[v540]; \
[s180]scale=-2:180[v180]; \
[l720]scale=-2:720[lv720]; \
[l360]scale=-2:540[lv540]; \
[l180]scale=-2:180[lv180]" \
-map "[v720]" -bufsize:v:0 800k -maxrate:v:0 2500k -flvflags no_duration_filesize -flags +global_header \
-map "[v540]" -bufsize:v:1 500k -maxrate:v:1 1400k -flvflags no_duration_filesize -flags +global_header \
-map "[v180]" -bufsize:v:2 100k -maxrate:v:2 400k -flvflags no_duration_filesize -flags +global_header \
-map "[lv720]" -bufsize:v:3 800k -maxrate:v:3 2500k -flvflags no_duration_filesize -flags +global_header \
-map "[lv540]" -bufsize:v:4 200k -maxrate:v:4 700k -flvflags no_duration_filesize -flags +global_header \
-map "[lv180]" -bufsize:v:5 100k -maxrate:v:5 400k -flvflags no_duration_filesize -flags +global_header \
-map a:0 \
-af "pan=mono|c0=FL" -c:a aac -b:a 128k -ar 44100 -profile:v:0 main -bf 0 -c:v libx264 -tune zerolatency -preset veryfast -crf 25 -pix_fmt yuv420p -g 50 -f tee \
"[select=\'v:0,a\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://........................|\
 [select=\'v:0,a\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://........................|\
 [select=\'v:1,a\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://........................|\
 [select=\'v:3,a\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtsp://.......................|\
 [select=\'v:4,a\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtsp://.......................|\
 [select=\'v:5,a\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtsp://......................."

当我添加 -acodec 和 -ar 选项时,它似乎从最后一个 -map 选项中获取参数:

-map "[v720]" -acodec aac -b 128k -ar 44100 -bufsize:v:0 800k -maxrate:v:0 2500k -flvflags no_duration_filesize -flags +global_header \
-map "[v540]" -acodec aac -b 96k -ar 44100 -bufsize:v:1 500k -maxrate:v:1 1400k -flvflags no_duration_filesize -flags +global_header \
-map "[v180]" -acodec aac -b 96k -ar 44100 -bufsize:v:2 100k -maxrate:v:2 400k -flvflags no_duration_filesize -flags +global_header \
-map "[lv720]" -acodec libopus -b 128k -ar 48000 -bufsize:v:3 800k -maxrate:v:3 2500k -flvflags no_duration_filesize -flags +global_header \
-map "[lv540]" -acodec libopus -b 96k -ar 48000 -bufsize:v:4 200k -maxrate:v:4 700k -flvflags no_duration_filesize -flags +global_header \
-map "[lv180]" -acodec libopus -b 96k -ar 48000 -bufsize:v:5 100k -maxrate:v:5 400k -flvflags no_duration_filesize -flags +global_header \
-map a:0 \
-af "pan=mono|c0=FL" -profile:v:0 main -bf 0 -c:v libx264 -tune zerolatency -preset veryfast -crf 25 -pix_fmt yuv420p -g 50 -f tee \
"[select=\'v:0,a\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://...........................................|\
 [select=\'v:0,a\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://...........................................|\
 [select=\'v:1,a\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://...........................................|\
 [select=\'v:3,a\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtsp://...........................................|\
 [select=\'v:4,a\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtsp://...........................................|\
 [select=\'v:5,a\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtsp://..........................................."

我得到的回报是:

[flv @ 0x55df601d4f40] FLV does not support sample rate 48000, choose from (44100, 22050, 11025)
[flv @ 0x55df601d4f40] Audio codec opus not compatible with flv
[tee @ 0x55df5cd5bf40] Slave muxer #0 failed, aborting.
av_interleaved_write_frame(): Function not implemented

答案1

https://trac.ffmpeg.org/wiki/Creating%20multiple%20outputs

您已将其分成 6 个通道,并且可以使用 -acodec 标签在单独的 -map 标签上定义 acodec。

答案2

看来,仅分割视频并向每个地图添加 -acodec、-b、-ar 不起作用,ffmpeg 将这些参数的最后一个选项作为所有地图的默认值。我也尝试设置 -acodec:a:0 等,但似乎也不起作用。

最后,经过大量的研究和测试,我添加了 [a:0]asplit=2...,然后分别映射每个音频。还把 -codec:a:0 替换为 -acodec...,最后终于成功了。希望它也能帮助别人。这是最终的命令:

/usr/bin/ffmpeg -thread_queue_size 2048 -f decklink -video_input sdi -audio_input embedded -i 'DeckLink Mini Recorder 4K' -threads 4 \
-filter_complex \
"[0:v]fps=25,split=6[s720][s540][s180][l720][l360][l180]; \
[s720]scale=-2:720[v720]; \
[s540]scale=-2:540[v540]; \
[s180]scale=-2:180[v180]; \
[l720]scale=-2:720[lv720]; \
[l360]scale=-2:540[lv540]; \
[l180]scale=-2:180[lv180]; \
[0:a]asplit=2[opus][aac]" \
-map "[lv720]" -bufsize:v:0 800k -maxrate:v:0 2500k -flvflags no_duration_filesize -flags +global_header \
-map "[lv540]" -bufsize:v:1 200k -maxrate:v:1 700k -flvflags no_duration_filesize -flags +global_header \
-map "[lv180]" -bufsize:v:2 100k -maxrate:v:2 400k -flvflags no_duration_filesize -flags +global_header \
-map "[v720]" -bufsize:v:3 800k -maxrate:v:3 2500k -flvflags no_duration_filesize -flags +global_header \
-map "[v540]" -bufsize:v:4 500k -maxrate:v:4 1400k -flvflags no_duration_filesize -flags +global_header \
-map "[v180]" -bufsize:v:5 100k -maxrate:v:5 400k -flvflags no_duration_filesize -flags +global_header \
-map "[opus]" -codec:a:0 libopus -ar:a:0 48000 -b:a:0 128k \
-map "[aac]" -codec:a:1 aac -ar:a:1 44100 -b:a:1 128k \
-profile:v:0 main -bf 0 -c:v libx264 -tune zerolatency -preset veryfast -crf 25 -bf 0 -pix_fmt yuv420p -g 50 -f tee \
"[select=\'v:0,a:0\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://.......................|\
[select=\'v:1,a:0\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://.......................|\
[select=\'v:2,a:0\':f=fifo:fifo_format=rtsp:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://.......................|\
[select=\'v:3,a:1\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://.......................|\
[select=\'v:3,a:1\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://.......................|\
[select=\'v:4,a:1\':f=fifo:fifo_format=flv:drop_pkts_on_overflow=1:attempt_recovery=1:recovery_wait_time=1]rtmp://......................."

答案3

这是我对 5a68656e4e6975 评论的回答。它似乎太长了,不适合评论部分,所以我把它放在这里 :)

当我使用 -acodec 时,它会从最后一个 -map 中获取其值并将其放入所有映射中。这绝对不是比特率问题。FLV 不支持 opus 仅处理以下音频频率之一:44100hz、22050hz、11025hz。另一方面,OPUS 编解码器仅支持 48000hz。Limelight CDN 需要一个使用 aac 编码的 41000hz 音频的 flv 输入,而 Wowza Streaming Engine 需要使用 opus 编解码器和 48khz 编码的音频,以便它可以通过 WebRTC 重新流式传输(我不希望服务器转码)。所以这个写入权限错误是由于给 Limelight 提供了 opus 和 48khz 音频。使用我答案中的代码,一切都很顺利。我正在切换到单通道,因为我的麦克风只连接到 ATEM HD TV Switch 的左声道,但我需要在两个扬声器/耳机上听到声音。并且,ATEM 没有将音频从一个通道复制到另一个通道的选项,这就是我在 ffmpeg 中执行此操作的原因。

相关内容