我正在进行一个项目,我只需要将FFMEPG用作解复用器复用器,以便接收带有音频和视频流的MPEG源,并分别输出不同的流。我还需要它来引入尽可能小的延迟。为了做到这一点,我有关于输入的所有必要信息:使用的容器、音频和视频编解码器、音频和音频速率以及音频通道,所以我想向FFMPEG提供这些信息,并避免验证阶段。然而,如果不指定一个大问题,我就无法让FFMPEG工作,这会导致延迟,并且根据输入,会导致FFMPEG由于无法获得所需信息(我事先有)而失败。
我一直在研究FFMPEG提供的不同选项,我发现以下选项可以帮助我:
-
-codec:a
和-codec:v
以提供关于输入的音频和视频编解码器的信息。 -
-f
以提供关于所用容器的信息。 -
-r:v
以提供关于视频帧速率的信息。(我也尝试过-framerate
,但似乎只有少数解复用器支持,mpeg不是其中之一)。 -
-probesize
以避免花费时间探测输入,因为我可以提供信息。 -
-copy_unknown
只需复制流,而不是在无法识别的情况下失败。
对于所有这些,我使用以下命令:./ffmpeg -hide_banner -loglevel debug -codec:v h264 -codec:a pcm_alaw -flags low_delay -probesize 32 -analyzeduration 0 -r:v 15 -f mpeg -i udp://127.0.0.1:41071?listen -y -map 0:a:0? -acodec copy -copy_unknown -ar 8000 -payload_type 8 -f rtp udp://127.0.0.1:33605?pkt_size=1200 -map 0:v:0? -vcodec copy -copy_unknown -payload_type 96 -f rtp udp://127.0.0.1:48527?pkt_size=1200
Splitting the commandline. Reading option '-hide_banner' ... matched as option 'hide_banner' (do not show program banner) with argument '1'. Reading option '-loglevel' ... matched as option 'loglevel' (set logging level) with argument 'debug'. Reading option '-codec:v' ... matched as option 'codec' (codec name) with argument 'h264'. Reading option '-codec:a' ... matched as option 'codec' (codec name) with argument 'pcm_alaw'. Reading option '-flags' ... matched as AVOption 'flags' with argument 'low_delay'. Reading option '-probesize' ... matched as AVOption 'probesize' with argument '32'. Reading option '-analyzeduration' ... matched as AVOption 'analyzeduration' with argument '0'. Reading option '-r:v' ... matched as option 'r' (set frame rate (Hz value, fraction or abbreviation)) with argument '15'. Reading option '-f' ... matched as option 'f' (force format) with argument 'mpeg'. Reading option '-i' ... matched as input url with argument 'udp://127.0.0.1:41071?listen'. Reading option '-y' ... matched as option 'y' (overwrite output files) with argument '1'. Reading option '-map' ... matched as option 'map' (set input stream mapping) with argument '0:a:0?'. Reading option '-acodec' ... matched as option 'acodec' (force audio codec ('copy' to copy stream)) with argument 'copy'. Reading option '-copy_unknown' ... matched as option 'copy_unknown' (Copy unknown stream types) with argument '1'. Reading option '-ar' ... matched as option 'ar' (set audio sampling rate (in Hz)) with argument '8000'. Reading option '-payload_type' ... matched as AVOption 'payload_type' with argument '8'. Reading option '-f' ... matched as option 'f' (force format) with argument 'rtp'. Reading option 'udp://127.0.0.1:33605?pkt_size=1200' ... matched as output url. Reading option '-map' ... matched as option 'map' (set input stream mapping) with argument '0:v:0?'. Reading option '-vcodec' ... matched as option 'vcodec' (force video codec ('copy' to copy stream)) with argument 'copy'. Reading option '-copy_unknown' ... matched as option 'copy_unknown' (Copy unknown stream types) with argument '1'. Reading option '-payload_type' ... matched as AVOption 'payload_type' with argument '96'. Reading option '-f' ... matched as option 'f' (force format) with argument 'rtp'. Reading option 'udp://127.0.0.1:48527?pkt_size=1200' ... matched as output url. Finished splitting the commandline. Parsing a group of options: global . Applying option hide_banner (do not show program banner) with argument 1. Applying option loglevel (set logging level) with argument debug. Applying option y (overwrite output files) with argument 1. Applying option copy_unknown (Copy unknown stream types) with argument 1. Last message repeated 1 times Successfully parsed a group of options. Parsing a group of options: input url udp://127.0.0.1:41071?listen. Applying option codec:v (codec name) with argument h264. Applying option codec:a (codec name) with argument pcm_alaw. Applying option r:v (set frame rate (Hz value, fraction or abbreviation)) with argument 15. Applying option f (force format) with argument mpeg. Successfully parsed a group of options. Opening an input file: udp://127.0.0.1:41071?listen. [mpeg @ 0x55a769cc3d40] Opening 'udp://127.0.0.1:41071?listen' for reading [udp @ 0x55a769cc4b00] No default whitelist set [udp @ 0x55a769cc4b00] end receive buffer size reported is 425984 [mpeg @ 0x55a769cc3d40] Before avformat_find_stream_info() pos: 6 bytes read:40 seeks:0 nb_streams:0 [mpeg @ 0x55a769cc3d40] probing stream 1 pp:2500 [mpeg @ 0x55a769cc3d40] probed stream 1 [mpeg @ 0x55a769cc3d40] parser not found for codec pcm_alaw, packets or times may be invalid. [mpeg @ 0x55a769cc3d40] Probe buffer size limit of 32 bytes reached [mpeg @ 0x55a769cc3d40] Stream #0: not enough frames to estimate rate; consider increasing probesize [mpeg @ 0x55a769cc3d40] Could not find codec parameters for stream 0 (Video: h264, 1 reference frame, none): unspecified size Consider increasing the value for the 'analyzeduration' (0) and 'probesize' (32) options [mpeg @ 0x55a769cc3d40] After avformat_find_stream_info() pos: 87804 bytes read:88476 seeks:0 frames:1 Input #0, mpeg, from 'udp://127.0.0.1:41071?listen': Duration: N/A, start: 50436.772978, bitrate: 64 kb/s Stream #0:0[0x1e0], 0, 1/90000: Video: h264, 1 reference frame, none, 90k tbr, 90k tbn Stream #0:1[0x1c0], 1, 1/90000: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s Successfully opened the file. Parsing a group of options: output url udp://127.0.0.1:33605?pkt_size=1200. Applying option map (set input stream mapping) with argument 0:a:0?. Applying option acodec (force audio codec ('copy' to copy stream)) with argument copy. Applying option ar (set audio sampling rate (in Hz)) with argument 8000. Applying option f (force format) with argument rtp. Successfully parsed a group of options. Opening an output file: udp://127.0.0.1:33605?pkt_size=1200. [udp @ 0x55a769cf6500] No default whitelist set Successfully opened the file. Parsing a group of options: output url udp://127.0.0.1:48527?pkt_size=1200. Applying option map (set input stream mapping) with argument 0:v:0?. Applying option vcodec (force video codec ('copy' to copy stream)) with argument copy. Applying option f (force format) with argument rtp. Successfully parsed a group of options. Opening an output file: udp://127.0.0.1:48527?pkt_size=1200. [udp @ 0x55a769d08fc0] No default whitelist set Successfully opened the file. Output #0, rtp, to 'udp://127.0.0.1:33605?pkt_size=1200': Metadata: encoder : Lavf59.16.100 Stream #0:0, 0, 1/8000: Audio: pcm_alaw, 8000 Hz, mono, s16, 64 kb/s [rtp @ 0x55a769d06f40] dimensions not set Could not write header for output file #1 (incorrect codec parameters ?): Invalid argument Error initializing output stream 1:0 -- Stream mapping: Stream #0:1 -> #0:0 (copy) Stream #0:0 -> #1:0 (copy) Last message repeated 1 times [AVIOContext @ 0x55a769d06d40] Statistics: 0 bytes written, 0 seeks, 0 writeouts [AVIOContext @ 0x55a769d19800] Statistics: 0 bytes written, 0 seeks, 0 writeouts [AVIOContext @ 0x55a769cd4fc0] Statistics: 88476 bytes read, 0 seeks
我使用的是FFMPEG 5.0.2,这是一个相当更新的版本。
正如您所看到的,-copy_unknown
选项没有效果,因为FFMPEG在尝试识别输入时仍然会崩溃(我也尝试过在输入上指定它,但结果是一样的)。从日志中,我认为主要问题是FFMPEG没有正确解释帧速率,这阻止了它对视频进行解复用。我一直在寻找另一种方法来指定它,但找不到。
这是一个bug吗?或者可能是遗漏了什么?有人知道我如何实现目标吗?