代码之家  ›  专栏  ›  技术社区  ›  stevendesu

如何从rtmp流(avc1编码)中提取sps和pps?

  •  0
  • stevendesu  · 技术社区  · 6 年前

    我正在做一个扩展 Node Media Server 将传入的流保存到磁盘为mp4。为了这个转换到MP4我非常依赖 Apple QuickTime Movie Specification ,请 The ISO/IEC 14496-14 Specification (这是我在rust-mp4 github存储库中免费发现的),以及 The HLS.js Source Code

    我正在用一个视频测试。一旦这个工作,我将开始试验其他视频。对于我的用例,我只需要支持H.264视频和AAC音频。

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

    • 1个 AMF metadata 包含视频宽度、视频高度、比特率、音频采样率等信息的包(rtmp cid=6)
    • 1个 audio 包含7字节数据的包(rmtp cid=4)。我想这是aac配置包
    • 1个 video 包含46字节数据的包(rtmp cid=5)。我想这是avc配置包

    写MP4的时候 moov atom,有两个地方需要利用amf元数据中没有的附加信息(可能位于这两个配置包中):

    • esds 原子, The HLS.js source 追加“配置”数据。我想我只是把音频配置包中的7字节有效负载附加到这里
    • avcC 原子, The HLS.js source 附加“sps”和“pps”数据。这是我问题的根源

    关于这46个字节的解析,我在 Node Media Server HLS.js 似乎在分析相同的数据。这两段代码的区别在于,节点媒体服务器期望在数据包的开头有额外的13字节的数据。我收到的数据包似乎包含这些额外的13个字节,所以我只是按照它们的引导来提取 width 我是说, height ,请 profile 我是说, compat ,和 level 信息。尤其是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]
    

    把这个分解成我能做的字节 容易地 解析(在使用指数golomb编码之前):

    [
        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
        // ...
    ]
    

    现在我遇到的问题是 莫夫 原子 平均成本 原子,特别是)我需要知道 sps 以及 pps 字节。 From the HLS.js source 看起来像是 sps系统 可能只是这个视频配置包减去前13个字节。但是我如何找到 聚苯硫醚 是吗?是 聚苯硫醚 实际上是这个包的最后几个字节,我应该把它分成几个部分?这个会用另一个包裹寄出吗?如果两个视频包是预期的,有什么方法我应该区分它们以便我知道哪一个是 sps系统 哪一个是 聚苯硫醚 是吗?

    如果我能搞清楚这最后一点,那么我应该把 莫夫 数据包(在这之后,我只需要找出 mdat 包和我应该有工作代码)

    更新: 为了记录,我刚刚检查了第四个包裹,看看它是否包含 聚苯硫醚 数据。在重新连接到流~20次后,第四个包始终是 视频 数据包(rtmp cid=5),但数据包的大小从16000字节到21000字节不等。我怀疑这是合法的视频数据。

    第二次更新: 解析完sps后,我刚刚检查了视频配置包中的偏移量,结果是字节23( 0x84 )中。因此,PPS很可能 实际上在这个字节数组的末尾,但我不确定有多少字节是分隔符/头(nal类型、nal长度等)和多少字节是实际的pps。

    0 回复  |  直到 6 年前