通过 rtmp 发送的 FLV 视频数据包使用 ffmpeg 与 OBS 进行流式传输

FLV Video packets sent over rtmp streamed with ffmpeg vs OBS

我正在使用 node-media-server npm 模块来托管我的 rtmp 服务器。我从服务器捕获了视频数据包,我注意到以 ffmpeg -f gdigrab -offset_x 1920 -framerate 60 -video_size hd1080 -i desktop -crf 0 -preset ultrafast -f flv rtmp://localhost 流式传输的视频数据包以

开头

当我使用 OBS 流式传输到我的 rtmp 服务器时,我捕获以

开头的视频数据包

我想做的是捕获这些数据包,存储它,并在它们连接到我的服务器时将这些数据包发送到 'players'。我使用 ffmpeg 捕获的数据包和使用 ffmpeg.

将视频转换为 flv 格式的视频

但是播放器不播放使用 OBS 流式传输的视频包。然而,当我的 rtmp 服务器只是 'relaying' 它收到的而不是 'replaying' 捕获的数据包时,播放器确实播放得很好。但音频播放效果很好。

我想知道那些开头的十六进制代表什么(是否表示OBS没有使用flv文件格式)。

(1)

"...And when I stream to my RTMP server with OBS, I capture video packets that start with

  • 27 01 00 00 00 00 00 and

  • the very first packet starts with 17 01 00 00 00 00

I would like to know what those starting hexadecimals represent (whether it indicates that OBS is not using the FLV file format)."

这些字节值对于 FLV 格式是正确的(参见:"Video encoding" section under FLV Structure

假设数据包以字节 XY 01 00 00...

开头
  • X 是帧类型...X == 1 用于关键帧 (I-frame),X == 2 用于支持 P/B-frames.

  • Y 是编解码器类型...Y == 7 用于编解码器 H.264 (MPEG)。

您会注意到,在您的 FFmpeg 生成的 FLV 中,Y 编解码器类型是 2。默认情况下,FFmpeg 使用 Sorenson Spark 编解码器(图像质量较低)输出 FLV。

要让 FFmpeg 在 FLV 中输出 H264,请使用 -c:v libx264,示例:

ffmpeg -f gdigrab -offset_x 1920 -framerate 60 -video_size hd1080 -i desktop -c:v libx264 -crf 0 -preset ultrafast -f flv rtmp://localhost


(2)

"However the players don't play the video packets streamed with OBS."

我假设 OBS 意味着 Open Broadcaster Software?有没有办法提供一个简短的示例输出 FLV 文件以供分析?或者尝试捕获流式处理发送的每个字节(按出现顺序)。如果我是 player/decoder 我从您的 RTMP link 收到的前 100 多个字节是多少?

你能确定发送给播放器的 FLV 数据包含正确的数据吗例如:

馈入 player/decoder...

  • 一个 FLV header,然后是
  • A/V 元数据(分辨率、FPS、时长等)。

这之后应该是(个别帧)...

  • (每帧)A/V 包含视频数据包的标签设置(例如: 09... 直到 27 01 00 00... etc)。

基本上确保FLV数据正确工作。玩家对音频编解码器怎么说?

另外,您的音频是以 MP3 格式发送的吗?这是我能想象你的 "The audio plays nicely" 的唯一方式,因为每个 MP3 帧都有自己的 header 并且这些数据可能会在你发送给播放器的字节中被识别(例如: 播放器忽略未知字节但理解 MP3 部分,因此将其解码到您的扬声器)。使用 ADTS header 发送的 AAC 音频也可能有效,但 ADTS header 永远不应位于媒体容器内(不是 FLV、MP4 或 AVI)。

(3) 我建议您为 OS 下载一个 hex editor(如果使用 Windows,试试 HxD)。

比较来自 FFmpeg 和 OBS 的两个 FLV 文件的字节数。寻找典型的结构,例如...
(这是 FLV header 和元数据):

46 4C 56 01 01 00 00 00 09 00 00 00 00 12 00 01     FLV............. 
25 00 00 00 00 00 00 00 02 00 0A 6F 6E 4D 65 74     %..........onMet
61 44 61 74 61 08 00 00 00 0C 00 08 64 75 72 61     aData.......dura
74 69 6F 6E 00 40 46 D9 99 99 99 99 9A 00 05 77     tion.@FÙ™™™™š..w
69 64 74 68 00 40 77 00 00 00 00 00 00 00 06 68     idth.@w........h
65 69 67 68 74 00 40 75 00 00 00 00 00 00 00 0D     eight.@u........
76 69 64 65 6F 64 61 74 61 72 61 74 65 00 40 8A     videodatarate.@Š
0B F6 00 00 00 00 00 09 66 72 61 6D 65 72 61 74     .ö......framerat
65 00 40 48 1A 20 84 C4 02 3E 00 0C 76 69 64 65     e.@H. „Ä.>..vide
6F 63 6F 64 65 63 69 64 00 40 1C 00 00 00 00 00     ocodecid.@......

然后一个 audio/video 帧被打包到一个 AV 标签中(如果是视频,数据从 09 开始,如果是音频,则从 08 开始):

09 XX XX XX XX XX XX 00 00 00 00 后跟帧数据 27 01 00 00 XX 00 00 XX XX XX XX etc