首页 > 解决方案 > 如何从 RTMP 流(avc1 编码)中提取 SPS 和 PPS?

问题描述

我正在开发节点媒体服务器的扩展,以将传入的流作为 MP4 保存到磁盘。对于这种到 MP4 的转换,我非常依赖Apple QuickTime 电影规范ISO/IEC 14496-14 规范(我在 Rust-MP4 GitHub 存储库中免费发现)和HLS.js 源代码

我目前正在测试一个视频。一旦成功,我将开始尝试其他视频。对于我的用例,我只需要支持 H.264 视频和 AAC 音频。

目前,当建立 RTMP 连接时,我收到的前 3 个数据包是一致的:

在编写 MP4 moovatom 时,我需要在两个地方使用不在 AMF 元数据中的附加信息(并且可能位于这两个配置数据包中):

关于这 46 个字节的解析,我在Node Media ServerHLS.js中找到了似乎解析相同数据的代码。这两段代码之间的区别在于,Node Media Server 在数据包的开头需要额外的 13 个字节的数据。我收到的数据包似乎包含这些额外的 13 个字节,所以我只是按照他们的引导提取widthheightprofilecompatlevel信息。特别是 46 个字节是:

[0x17, 0x00, 0x00, 0x00, 0x00, 0x01, 0x42, 0xc0, 0x1f, 0xff, 0xe1, 0x00, 0x19, 0x67, 0x42, 0xc0, 0x1f, 0xa6, 0x11, 0x02, 0x80, 0xbf, 0xe5, 0x84, 0x00, 0x00, 0x03, 0x00, 0x04, 0x00, 0x00, 0x03, 0x00, 0xc2, 0x3c, 0x60, 0xc8, 0x46, 0x01, 0x00, 0x05, 0x68, 0xc8, 0x42, 0x32, 0xc8]

将其分解为我可以轻松解析的字节(在使用指数哥伦布编码之前):

[
    0x17, // "frame type", specifies H.264 or HVEC
    0x00, 0x00, 0x00, 0x00, 0x01, // ignored. Reserved?
    0x42, // profile
    0xc0, // compat
    0x1f, // level
    0xff, // "info.nalu" (per Node Media Server source)
    0xe1, // "info.nb_sps" (per Node Media Server source)
    0x00, 0x19, // "nal size"
    // Above here are the bits exclusively seen by Node Media Server (specific to RTMP?)
    // Below here are the bits passed to HLS.js as "unit.data" (common to all AVC1 streams?):
    0x67, // "nal type"
    0x42, // profile (again?)
    0xc0, // compat (again?)
    0x1f, // level (again?)
    // Below here, data is not necessarily byte-aligned as Exponential Golomb encoding is used
    // ...
]

现在我遇到的问题是在创建moov原子(avcC特别是原子)的过程中,我需要知道字节spspps字节。从 HLS.js 源来看,sps可能只是这个视频配置数据包减去前 13 个字节。但是我如何找到pps?实际上是pps这个数据包的最后几个字节,我应该把它拆分到某个地方吗?这将在另一个数据包中交付吗?如果预期有两个视频数据包,是否有某种方法可以区分它们,以便我知道哪个是sps哪个是哪个pps

如果我能弄清楚最后一点,那么我应该完全写完moov数据包(之后我只需要找出mdat数据包的正确格式,我应该有工作代码)

更新:为了记录,我刚刚检查了正在传递的第四个数据包,看它是否可能包含pps数据。在重新连接到流约 20 次后,第四个数据包始终是一个video数据包(RTMP cid = 5),但数据包的大小范围从 16000 字节到 21000 字节。我怀疑这是合法的视频数据。

第二次更新:当我完成 SPS 解析时,我刚刚检查了视频配置数据包中的偏移量,并且我在字节 23 ( 0x84) 上。因此,PPS 实际上很可能位于该字节数组的末尾,但我不确定有多少字节是分隔符/标头(NAL 类型、NAL 长度等)以及实际 PPS 有多少字节。

标签: node.jsvideomp4h.264rtmp

解决方案


推荐阅读