使用带命名管道的 FFMPEG 记录 RTP VP8 数据包

Recording RTP VP8 packets with FFMPEG with named pipe

我正在用 C++ 开发的网关开发 WebRTC 视频会话记录器,我只能访问单个 RTP 数据包。

当会话开始时,我创建了两个线程,一个初始化命名管道,另一个启动 FFMPEG 从该管道获取数据并将其存储在 matroska 文件中,命令如下:

ffmpeg -i \.\pipe\screenRec -f matroska D:\djhfifj.mkv

每当我收到一个 RTP 数据包时,我都会通过管道将其发送到 FFMPEG。尽管所有通信工作正常,FFMPEG 似乎无法识别 RTP 数据包:

ffmpeg version N-73633-gdfc5858 Copyright (c) 2000-2015 the FFmpeg developers
  built with gcc 4.9.2 (GCC)
  configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libdcadec --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
  libavutil      54. 28.100 / 54. 28.100
  libavcodec     56. 47.100 / 56. 47.100
  libavformat    56. 40.100 / 56. 40.100
  libavdevice    56.  4.100 / 56.  4.100
  libavfilter     5. 21.100 /  5. 21.100
  libswscale      3.  1.101 /  3.  1.101
  libswresample   1.  2.100 /  1.  2.100
  libpostproc    53.  3.100 / 53.  3.100
[aac @ 031b3fc0] Format aac detected only with low score of 1, misdetection possible!
[aac @ 031bd820] More than one AAC RDB per ADTS frame is not implemented. Update your FFmpeg version to the newest one from Git. If the problem still occurs, it means that your file has a feature which has not been implemented.
[aac @ 031bd820] channel element 3.13 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (26) exceeds limit (9).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (60) exceeds limit (44).
[aac @ 031bd820] Number of bands (6) exceeds limit (4).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (30) exceeds limit (23).
[aac @ 031bd820] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 031bd820] Inconsistent channel configuration.
[aac @ 031bd820] get_buffer() failed
[aac @ 031bd820] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (16) exceeds limit (11).
[aac @ 031bd820] Dependent coupling is not supported together with LTP
    Last message repeated 9 times
[aac @ 031bd820] channel element 3.5 is not allocated
[aac @ 031bd820] channel element 3.13 is not allocated
[aac @ 031bd820] channel element 3.3 is not allocated
[aac @ 031bd820] Number of bands (16) exceeds limit (14).
[aac @ 031bd820] channel element 3.10 is not allocated
[aac @ 031bd820] channel element 3.2 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of scalefactor bands in group (61) exceeds limit (43).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (29) exceeds limit (13).
[aac @ 031bd820] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 031bd820] Inconsistent channel configuration.
[aac @ 031bd820] get_buffer() failed
[aac @ 031bd820] channel element 0.7 is not allocated
[aac @ 031bd820] Number of bands (24) exceeds limit (15).
[aac @ 031bd820] channel element 1.1 is not allocated
[aac @ 031bd820] channel element 2.0 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of scalefactor bands in group (62) exceeds limit (41).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (15) exceeds limit (13).
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (23) exceeds limit (2).
[aac @ 031bd820] channel element 1.4 is not allocated
[aac @ 031bd820] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 031bd820] channel element 1.2 is not allocated
[aac @ 031bd820] channel element 1.8 is not allocated
[aac @ 031bd820] channel element 3.7 is not allocated
[aac @ 031bd820] channel element 2.9 is not allocated
[aac @ 031bd820] channel element 3.8 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of scalefactor bands in group (48) exceeds limit (43).
[aac @ 031bd820] channel element 3.8 is not allocated
[aac @ 031bd820] channel element 2.13 is not allocated
[aac @ 031bd820] channel element 3.4 is not allocated
[aac @ 031bd820] Dependent coupling is not supported together with LTP
    Last message repeated 13 times
[aac @ 031bd820] channel element 2.14 is not allocated
[aac @ 031bd820] SBR was found before the first channel element.
[aac @ 031bd820] Sample rate index in program config element does not match the sample rate index configured by the container.
[aac @ 031bd820] Inconsistent channel configuration.
[aac @ 031bd820] get_buffer() failed
[aac @ 031bd820] Number of bands (6) exceeds limit (5).
[aac @ 031bd820] channel element 3.0 is not allocated
[aac @ 031bd820] channel element 1.5 is not allocated
[aac @ 031bd820] channel element 1.13 is not allocated
[aac @ 031bd820] channel element 1.7 is not allocated
[aac @ 031bd820] channel element 2.0 is not allocated
[aac @ 031bd820] Dependent coupling is not supported together with LTP
    Last message repeated 13 times
[aac @ 031bd820] channel element 3.0 is not allocated
[aac @ 031bd820] Assuming an incorrectly encoded 7.1 channel layout instead of a spec-compliant 7.1(wide) layout, use -strict 1 to decode according to the specification instead.
[aac @ 031bd820] SBR was found before the first channel element.
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (31) exceeds limit (30).
[aac @ 031bd820] channel element 1.12 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] Number of bands (29) exceeds limit (10).
[aac @ 031bd820] channel element 3.2 is not allocated
[aac @ 031bd820] channel element 3.15 is not allocated
[aac @ 031bd820] channel element 1.5 is not allocated
[aac @ 031bd820] channel element 2.7 is not allocated
[aac @ 031bd820] channel element 1.9 is not allocated
[aac @ 031bd820] Number of bands (54) exceeds limit (34).
[aac @ 031bd820] channel element 1.6 is not allocated
[aac @ 031bd820] channel element 1.2 is not allocated
[aac @ 031bd820] channel element 3.7 is not allocated
[aac @ 031bd820] Reserved bit set.
[aac @ 031bd820] ms_present = 3 is reserved.
[aac @ 031b3fc0] decoding for stream 0 failed
[aac @ 031b3fc0] Could not find codec parameters for stream 0 (Audio: aac (LTP), 4.0, fltp, 1506 kb/s): unspecified sample rate
Consider increasing the value for the 'analyzeduration' and 'probesize' options
\.\pipe\screenRec96: could not find codec parameters
Input #0, aac, from '\.\pipe\screenRec96':
  Duration: N/A, bitrate: 1506 kb/s
    Stream #0:0: Audio: aac (LTP), 4.0, fltp, 1506 kb/s
[abuffer @ 0435cd00] Value inf for parameter 'time_base' out of range [0 - 2.14748e+009]
    Last message repeated 3 times
[abuffer @ 0435cd00] Error setting option time_base to value 1/0.
[graph 0 input from stream 0:0 @ 0319afe0] Error applying options to the filter.
Error opening filters!

是否可以让FFMPEG明白发送的数据包是RTPVP8

所以,这会很棘手。在我们找到解决方案之前,让我先解释一下原因。 FFmpeg 支持两种类型的 RTP 通信层:UDP 和 TCP。大多数人将 TCP 用于无线电之类的东西,其中实时元素并不那么重要,提前几秒缓冲就可以了。 UDP 用于 p2p 通信,如 webrtc。所以我假设您想使用 UDP。 (TCP 的故事略有不同,但差别不大。)UDP 数据包有数据包边界,如果你只是 "dump" 它们到命名管道,它就会丢失。其次,您没有告诉 ffmpeg 命名管道中的数据类型,因此 ffmpeg 可能只是认为它是原始 aac 文件(中间的 rtp 位是随机垃圾)。垃圾进,垃圾出。

所以。你如何解决它?就像我说的,这并不容易。我认为您绝对想将 ffmpeg 用作库,而不是可执行文件。然后,我想你想初始化ffmpeg来读取你的数据流作为rtp,所以在你的应用程序控制代码中打开一个localhost(127.0.0.1)套接字,通过libavformat打开一个rtp://127.0.0.1/(localhost)连接,并让您的应用程序向其写入数据包,ffmpeg 将接收这些数据包。现在,它会理解它们是 UDP 数据包并执行适当的操作。还有其他方法可以完成同样的事情——事实上,如果你让 ffmpeg 为你做 UDP 连接管理会容易得多,但如果你不想那样做,也没关系。