ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

Enhanced RTMP/FLV 扩展规范解析:在 Node-Media-Server 中支持 HEVC、VP9、AV1 与 HDR 元数据

Enhanced RTMP/FLV 扩展规范解析:在 Node-Media-Server 中支持 HEVC、VP9、AV1 与 HDR 元数据 【免费下载链接】Node-Media-ServerA Node.js implementation of RTMP/HTTP-FLV Media Server项目地址https://gitcode.com/gh_mirrors/no/Node-Media-Server点击查看免费下载导读本文以 Node-Media-Server 仓库内收录的 Enhanced RTMP 规范文档docs/enhanced-rtmp-v1.md为核心系统讲解 RTMP/FLV 协议如何在不破坏向后兼容的前提下扩展支持 HEVC/H.265、VP9、AV1 等新一代视频编码与 HDR高动态范围元数据。你将掌握 ExVideoTagHeader 位域布局、FourCC 编解码器信令、PacketTypeMetadata 元数据帧、connect 命令中的fourCcList能力协商以及colorInfoHDR 对象的结构与取值约束同时结合仓库源码看清这些规范点在真实流媒体服务器中如何被解析、打包与流转。1. 背景为什么 RTMP/FLV 需要一次增强RTMPReal Time Messaging Protocol首个公开版本发布于 2002 年距今已超过二十年。大量直播与点播系统至今仍以 RTMP 作为推流/拉流链路HTTP-FLV 则是最常见的播放分发形态。但 RTMP/FLV 的协议演进长期停滞FLV 容器内的视频 CodecID 只有 4 个比特位仅能表达 Sorenson H.263、Screen video、On2 VP6、AVCH.264等老编码不支持 VP9、HEVC、AV1 这些现代编码也没有在容器层面传递 HDR 元数据的能力。Enhanced RTMP 规范正是为弥合这一缺口而设计其目标能力包括三块新增能力说明新增视频编码类型HEVCH.265——流媒体硬件与软件方案中广泛使用VP9——正在获得流行度AV1——编码无关的云服务正在要求 AV1 支持HDR 能力支撑新编码与当前显示设备的宽色域、高亮度需求PacketTypeMetadata用于在容器/协议层携带多种视频元数据典型如 HDR 信息规范的首要设计原则是不定义任何破坏性变更存量客户端与它们推送的内容必须继续正常工作因此旧版 RTMP/FLV 规范Adobe RTMP Specification、Adobe Flash Video File Format Specification Version 10.1 等依然有效且重要本增强规范只在其上叠加新定义新旧规范合在一起才构成 RTMP 解决方案的完整信息。2. 规范关键词约定本文档中的 MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、RECOMMENDED、NOT RECOMMENDED、MAY、OPTIONAL 等关键词遵循 BCP 14RFC 2119 / RFC 8174的解释MUST / REQUIRED / SHALL规范的绝对要求MUST NOT / SHALL NOT规范的绝对禁止SHOULD / RECOMMENDED在特定情形下存在合理的忽略理由但选择其他路径前必须充分理解并权衡全部影响SHOULD NOT / NOT RECOMMENDED特定行为在个别情形下可能可接受甚至有用但实现前应理解全部影响并仔细权衡MAY / OPTIONAL真正可选。不包含某选项的实现 MUST 能与包含该选项的实现互操作功能可能有所缩减反之亦然。此外规范补充了一个关键词DEPRECATED指对某术语、特性、设计或实践的使用劝阻通常因其已被取代或不再被视为高效/安全但不会完全移除或禁止使用以保障遗留兼容或作为新方法失效时的后备。3. RTMP 消息格式与 FLV 容器基础3.1 RTMP 消息结构RTMP 是应用层协议用于在合适传输层如 TCP之上对多媒体传输流音视频、交互内容进行复用与打包。其核心特性是 Chunk Stream——在线上对消息进行复用、打包与优先级调度这正是RTReal Time的体现。一条 RTMP 消息由消息头与消息载荷两部分组成消息头布局如下0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 -------------------------------- | Message Type | Payload length | | (1 byte) | (3 bytes) | -------------------------------- | Timestamp | | (4 bytes) | -------------------------------- | Stream ID | | (3 bytes) | ------------------------其中两种消息类型保留给媒体消息消息类型值 8 保留给音频消息消息类型值 9 保留给视频消息。载荷紧随消息头例如可以是压缩后的音频数据或视频数据。RTMP 本身对载荷内容一无所知包括如何处理它——因此新增编码类型必须在真正定义载荷内部结构的地方即 FLV 容器格式进行。线上字节序endianness规则以原始 RTMP 与 FLV 规范为准。3.2 FLV 文件格式要义FLV 是音视频数据的容器文件由交替的 back-pointer 与 tag 组成每个 tag 附带与该 tag 相关的数据。每个 TagType 用 5 个比特位定义AUDIODATA 的 tag type 为 8VIDEODATA 的 tag type 为 9与 RTMP 消息类型 ID 一一对应——这是有意设计。TagType 为 8 或 9 时伴随 AudioTagHeader 或 VideoTagHeader。理解这一点很关键RTMP 是协议FLV 是文件容器两者分属不同规范而本增强规范同时增强二者。3.3 增强前的 VideoTagHeaderFLV 10.1.2.012023 年之前的 FLV 规范中VideoTagHeader 布局如下字段类型说明Frame TypeUB[4]视频帧类型1 key frame对 AVC 是可定位帧2 inter frame对 AVC 是不可定位帧3 disposable inter frame仅 H.2634 generated key frame仅服务器使用5 video info/command frameCodecIDUB[4]编码标识2 Sorenson H.2633 Screen video4 On2 VP65 On2 VP6 with alpha channel6 Screen video version 27 AVCAVCPacketType若 CodecID 7 则为 UI80 AVC sequence header1 AVC NALU2 AVC end of sequence低层 NALU 序列结束符不是 REQUIRED 或 supportedCompositionTime若 CodecID 7 则为 SI24若 AVCPacketType 1 则为合成时间偏移否则为 0。见 ISO 14496-12 8.15.3FLV 文件中的偏移单位永远是毫秒注意CodecID 只有 4 个比特位幸运的是并非所有取值都被占用——规范正是利用未占用的取值位来实现编码的无限扩展具体机制见下一节。4. 核心增强一Extended VideoTagHeader 与新增视频编码4.1 扩展头设计IsExHeader 标志位下面将 VideoTagHeader 扩展以定义新增编码及其信令同时保持向后兼容。扩展的 ExVideoTagHeader 为后续定义更多编码与伴随信令留足了空间。解析过程中如果遇到任何无法理解的关键信令/标志如 FrameType、IsExHeader、ExHeaderInfo逻辑 MUST 优雅失败gracefully fail。扩展后完整的 VideoTagHeader 定义字段类型说明IsExHeader | FrameTypeUB[4]解析逻辑若(UB[4] 0b1000) ! 0则IsExHeader true此时这 4 位不再解释为 CodecID而是解释为 PacketType随后紧跟 UI32 FourCC 值否则IsExHeader false按 2023 前 FLV 规范的 CodecID 取值解释。FrameType 取值0 reserved1 key frame可定位帧2 inter frame不可定位帧3 disposable inter frame仅 H.2634 generated key frame仅服务器使用5 video info/command frame6、7 reserved。当 FrameType 5 时载荷不含视频数据VideoTagHeader 后跟一个 UI80 客户端侧定位seek视频帧序列开始1 客户端侧定位视频帧序列结束。向后兼容性IsExHeader 位本就属于 FrameType UB[4] 的一部分只是从未被定义/使用——2023 年前的 FrameType 取值从未到达 8其最高位始终为 0因此存量流不受影响CodecID若 IsExHeader 0 则为 UB[4]取值与旧规范完全一致、无任何改动0、1 Reserved2 Sorenson H.2633 Screen video4 On2 VP65 On2 VP6 with alpha channel6 Screen video version 27 AVC8~15 Reserved。若 IsExHeader 置位则切换为下方 FourCC 视频模式CodecID UB[4] 不再被解释为编码标识而是被解释为 PacketType——即这 4 位要么是 CodecID 要么是 PacketType由 IsExHeader 标志决定ExVideoTagHeader仅当 IsExHeader 置位时出现见下方 PacketType 与 FourCC 定义VideoTagBody载荷语义随 PacketType 与 FourCC 组合而定见下方伪代码4.2 PacketType扩展头中的包类型当 IsExHeader 置位时原 CodecID 的 4 个比特位被重新解释为 PacketTypePacketType 值名称语义0PacketTypeSequenceStart序列开始携带配置记录1PacketTypeCodedFrames编码帧数据2PacketTypeSequenceEnd序列结束3PacketTypeCodedFramesX编码帧数据变体CompositionTime 偏移隐含为 0省去在线上携带零值 SI24 的开销见 VideoTagBody 伪代码4PacketTypeMetadata载荷不含视频数据而是AMF 编码的元数据见 Metadata Frame 一节典型用途如 HDR 信息也为未来面向下一视频序列的元数据表达开辟空间。注意出现 PacketTypeMetadata 意味着本表顶部的 FrameType 标志应被忽略5PacketTypeMPEG2TSSequenceStart以 MPEG-2 TS 格式携带码流。注意PacketTypeSequenceStart 与 PacketTypeMPEG2TSSequenceStart 互斥6~15Reserved保留4.3 Video FourCC编码的信令标识FourCCFour-character ASCII code以 UI32 形式编码目前定义的视频编码信号如下编码FourCC 字符序列AV1{ a, v, 0, 1 }VP9{ v, p, 0, 9 }HEVC{ h, v, c, 1 }4.4 VideoTagBody 语义伪代码VideoTagBody 的具体内容由 PacketType 与 FourCC 组合决定规范给出的完整伪代码如下IF PacketType PacketTypeMetadata { // 载荷不含视频数据而是 AMF 编码的元数据 // 由一系列 [name, value] 键值对表示 // 目前唯一定义的键值对是 [colorInfo, Object] // 编码细节参见 FLV 文件规范中的 SCRIPTDATA / SCRIPTDATAVALUE 描述 DATA [colorInfo, Object] } ELSE IF PacketType PacketTypeSequenceEnd { // 信号序列结束 } IF FourCC AV1 { IF PacketType PacketTypeSequenceStart { // 载荷为启动序列的配置记录 DATA [AV1CodecConfigurationRecord] } ELSE IF PacketType PacketTypeMPEG2TSSequenceStart { DATA [AV1VideoDescriptor] } ELSE IF PacketType PacketTypeCodedFrames { // 载荷包含一个或多个 OBU且 MUST 代表单一 temporal unit DATA [Series of coded frames] } } If FourCC VP9 { IF PacketType PacketTypeSequenceStart { // 载荷为启动序列的配置记录 DATA [VPCodecConfigurationRecord] } ELSE IF PacketType PacketTypeCodedFrames { // 载荷 MUST 包含完整帧 DATA [Series of coded frames] } } If FourCC HEVC { IF PacketType PacketTypeSequenceStart { // 载荷为启动序列的配置记录 // 见 ISO 14496-15, 8.3.3.1.2 对 HEVCDecoderConfigurationRecord 的描述 DATA [HEVCDecoderConfigurationRecord] } ELSE IF PacketType PacketTypeCodedFrames || PacketType PacketTypeCodedFramesX { IF PacketType PacketTypeCodedFrames { // 见 ISO 14496-12, 8.15.3FLV 中偏移单位永远是毫秒 SI24 [CompositionTime Offset] } ELSE { // CompositionTime Offset 隐含为 0 // 省去在线上携带零值 SI24 的开销 } // 载荷包含一个或多个 NALU要求完整帧 DATA [HEVC NALU] } }仓库实现对照Node-Media-Server 的 FLV 解析器src/protocol/flv.js完整实现了上述位域语义。其常量定义与规范一一对应FOURCC_AV1 Buffer.from(av01)、FOURCC_VP9 Buffer.from(vp09)、FOURCC_HEVC Buffer.from(hvc1)flv.js以及VideoPacketTypeSequenceStart 0、VideoPacketTypeCodedFrames 1、VideoPacketTypeSequenceEnd 2、VideoPacketTypeCodedFramesX 3、VideoPacketTypeMetadata 4、VideoPacketTypeMPEG2TSSequenceStart 5flv.js。在解析视频 tag 时flv.js代码先按frameType data[0] 4 0b0111、codecID data[0] 0x0f、isExHeader (data[0] 4 0b1000) ! 0拆解首字节随后若isExHeader置位则取出 1~4 字节的 FourCC与三种已知 FourCC 比较命中后把packet.codec_id写为fourCC.readUint32BE()大端 UI32与规范一致PacketTypeSequenceStart→flags 2PacketTypeCodedFrames/PacketTypeCodedFramesX→ 按 FrameType 是否为 key frame 置flags 3 / 4PacketTypeMetadata→flags 6源码中保留了AMF.parseScriptData解析 HDR 元数据的注释示例对于 HEVC若 PacketType 为PacketTypeCodedFrames则读取 5~7 字节的cts data.readUintBE(5, 3)并计算packet.pts packet.dts ctsflv.js——正是规范中 SI24 CompositionTime Offset 的落地实现。解析结果统一封装为 AVPacket 对象codec_id、codec_type、pts、dts、flags、size、data等字段供上层广播与分发。5. 核心增强二Enhancing onMetaDataFLV 元数据对象 SHALL 通过名为onMetaData的 SCRIPTDATA tag 承载。可用属性随创建 FLV 文件的软件而异见 FLV 10.1 规范。本规范对videocodecid属性进行了增强支持 FOURCC 值四字符 ASCII 码如av01以 UI32 编码。完整属性表如下属性名类型说明audiocodecidnumber文件中使用的音频编码 ID可用 SoundFormat 值见 E.4.2.1audiodataratenumber音频比特率kbpsaudiodelaynumber音频编码器引入的延迟秒audiosampleratenumber音频流回放频率audiosamplesizenumber单个音频采样的分辨率canSeekToEndboolean指示最后一帧视频是 key framecreationdatestring创建日期与时间durationnumber文件总时长秒filesizenumber文件总大小字节frameratenumber每秒帧数heightnumber视频高度像素stereoboolean指示是否为立体声音频videocodecidnumber文件中使用的视频编码 ID可用 CodecID 值见 E.4.3.1。当用 FourCC 信令编码时该属性被设为 FOURCC 值。注意FOURCC 值相对于底层 ASCII 字符序列是大端的例如av01 0x61763031 1635135537.0videodataratenumber视频比特率kbpswidthnumber视频宽度像素仓库实现对照在 Node-Media-Server 中onMetaData 的 AMF 解码由 src/protocol/amf.js 的decodeAmf0Data完成——rtmpDataCode表中注册了onMetaData: [dataObj]amf.js。广播服务器收到 SCRIPTDATA 包flags 5后用decodeAmf0Data(packet.data)解析并从中提取audiocodecid、stereo、audiosamplerate、audiodatarate、videocodecid、width、height、framerate、videodatarate写入发布者信息broadcast_server.js。一个非常直观的实战案例是RTSP 转推会话src/session/rtsp_client_session.js当拉取的 RTSP 流是 HEVCH.265时会话构建的 onMetaData 对象会把videocodecid置为FOURCC_HEVC大端 UI32常量定义见 rtsp_client_session.jsconst metaData { encoder: NodeMediaServer (RTSP relay) }; // ... metaData.videocodecid (videoCodec H265 || videoCodec HEVC) ? FOURCC_HEVC : 7; metaData.width info.width; metaData.height info.height; // ... metaData.audiocodecid FLV_CODEC_ID_AAC; metaData.audiosamplerate audioMedia.clockRate || 8000; metaData.audiosamplesize 16; metaData.stereo (audioMedia.channels || 1) 1;完整逻辑见 rtsp_client_session.js。之后通过encodeAmf0Data({ cmd: onMetaData, dataObj: metaData })打包为广播包发出并由 BroadcastServer 缓存flvMetaData/rtmpMetaData供后续订阅者获取。Webadmin 前端webadmin/src/pages/Streams.tsx也按 Enhanced RTMP 约定将大端 UI32 FourCC如0x68766331 hvc1映射为hvc1: H.265、av01: AV1、vp09: VP9进行展示API 层定义见 webadmin/src/lib/api.ts。6. 核心增强三扩展 NetConnection connect 命令fourCcList客户端连接 RTMP 服务器时会发送connect命令其结构包含一个 Command Object——由名称-值对构成客户端在此声明自身支持的音视频编码。为声明新定义的编码或其他增强能力connect 命令的 Command Object 新增如下名称-值对属性类型说明示例值fourCcListStrict Array of Strings增强后的受支持编码列表。是一个稠密序号索引的严格数组每个条目为 String 类型取值为代表某个受支持视频编码的 fourCC 值即四个字节的字符序列[av01, vp09, hvc1]仓库实现对照AMF0 的 Strict Array 编解码已内置于 src/protocol/amf.js解码侧amf0decSArray读取 UI32 计数后逐个解码元素amf.js编码侧amf0encSArray写类型字节0x0A与元素个数后逐个编码amf.jsconnect 命令的解析表注册为connect: [transId, cmdObj, args]amf.jsfourCcList即作为 cmdObj 内的一个属性被接收。7. 核心增强四Metadata FramePacketTypeMetadata 与 HDR7.1 设计动机为支持多种视频元数据FLV 容器规范被增强VideoTagHeader 扩展出了PacketTypeMetadata见第 4.2 节其载荷为 AMF 编码的元数据由一系列[name, value]键值对表示目前唯一定义的键值对是[colorInfo, Object]。有意使用视频消息Message Type 9而非其他 RTMP 消息类型来承载 PacketTypeMetadata其收益是避免视频消息与其他 RTMP 消息类型之间的竞态条件。因此一旦colorInfo对象被解析读取到的值 MUST 及时处理以作用于紧随colorInfo对象之后的视频段的第一帧。使用约束利用 PacketTypeMetadata 传递 HDR 元数据时元数据MUST 在其影响的视频序列、场景、帧之前发送每次收到新的colorInfo对象都会作废并替换当前对象要重置回原始颜色状态可发送值为Undefined的colorInfoRECOMMENDED 方式或发送空对象{}对内容创作者只要值得向 FLV 容器添加视频提示信息如 HDR元数据都推荐通过PacketTypeMetadata添加——这可以是在编码码流内直接编码元数据之外的补充也可以替代之对象编码格式AMF0 或 AMF3在 connect 命令时协商确定。7.2 colorInfo 对象结构colorInfo对象提供符合 BT.2020Rec. 2020标准的 HDR 元数据使图像源具备更高画质。以下为规范的完整定义并非所有属性在序列化时都保证存在取决于原始内容的母版制作、编码方式与意图// // 旨在协议/容器层而非编码码流内暴露的 HDR 元数据信息 // colorInfo { colorConfig: { // 每个像素每个颜色通道用于记录的比特数 bitDepth: Number, // SHOULD 为 8、10 或 12 // // colorPrimaries、transferCharacteristics 与 matrixCoefficients // 定义于 ISO/IEC 23091-4/ITU-T H.273取值为各自表格中的索引 // 参见 Colour primaries、Transfer characteristics、Matrix coefficients 章节。 // 推荐提供这些值。 // // 源颜色原色的色度坐标 colorPrimaries: Number, // 枚举 [0-255] // 光电转换特性函数如 PQ、HLG transferCharacteristics: Number, // 枚举 [0-255] // 用于推导亮度与色度信号的矩阵系数 matrixCoefficients: Number, // 枚举 [0-255] }, hdrCll: { // // 整个播放序列的帧平均光级最大值单位 1 cd/m2 // maxFall: Number, // [0.0001-10000] // // 整个播放序列中任一单像素的最大光级单位 1 cd/m2 // maxCLL: Number, // [0.0001-10000] }, // // hdrMdcv 定义母版显示即创作期间完成创意工作的显示设备色彩体积mdcv元数据 // 描述原色、白点与最小/最大亮度。推荐提供 hdrMdcv 对象。 // // 元数据规范及其取值范围遵循 ST 2086:2018 - SMPTE 标准 // minLuminance 除外见下方注释 // hdrMdcv: { // // 母版显示色彩体积mdcvxy 色度坐标CIE 1931 色彩空间。 // // 值 SHALL 指定四位小数。x 坐标 SHALL 在 [0.0001, 0.7400] 范围内 // y 坐标 SHALL 在 [0.0001, 0.8400] 范围内。 // redX: Number, redY: Number, greenX: Number, greenY: Number, blueX: Number, blueY: Number, whitePointX: Number, whitePointY: Number, // // 母版显示的最大/最小显示亮度单位 1 cd/m2即 nits。 // // 注意ST 2086:2018 - SMPTE 标准规定最小显示母版亮度以 0.0001 cd/m2 的倍数表示。 // 为保持一致我们统一以 1 cd/m2 为单位。 // 假设理想屏幕峰值亮度为 10,000 nits、黑电平为 0.0005 nits // 则无需切换单位为 0.0001 cd/m2 来提升 minLuminance 低端分辨率。 // 下述取值范围以 nits 计足以覆盖母版参考显示器的理论极限 // 且符合 SMPTE ST 2084即 PQ标准——该标准可表示完整亮度档位。 // maxLuminance: Number, // [5-10000] minLuminance: Number, // [0.0001-5] } };7.3 videoFunction 属性标志客户端对 HDR 及扩展特性的支持能力通过 connect 命令 Command Object 中的videoFunction属性以位标志声明各标志可用逻辑或OR组合功能标志用途值SUPPORT_VID_CLIENT_SEEK指示客户端可执行帧精确frame-accurate定位0x0001SUPPORT_VID_CLIENT_HDR指示客户端支持 HDR 视频。注意隐含支持 PacketTypeMetadata 内的 colorInfo 对象0x0002SUPPORT_VID_CLIENT_PACKET_TYPE_METADATA指示客户端支持 PacketTypeMetadata详见 Metadata Frame 一节0x0004SUPPORT_VID_CLIENT_LARGE_SCALE_TILE大规模瓦片tile允许解码器无需解压整帧即可提取帧内感兴趣区域。此特性支持并非必需除非该属性存在且为 true否则视为客户端未实现0x00088. Action Message FormatAMF0 与 AMF3AMFAction Message Format是用于序列化脚本数据的紧凑二进制格式存在AMF 0与AMF 3两个版本。AMF3 相比 AMF0 的一大改进是优化了线上载荷体积。规范RECOMMENDED 在 RTMP 解决方案中支持 AMF3在 FLV 文件中具备 AMF3 支持是锦上添花但在向 FLV 文件写入 AMF3 数据前应充分了解生态兼容情况。在 RTMP 中确保 AMF3 支持的方式支持以 AMF3 形式编码的 Command Message、Data Message 与 Shared Object Message 类型在 connect 命令中声明对象编码格式为 AMF3。注意RTMP 规范早已包含 AMF3——在握手期间客户端即声明其是否支持 AMF3。在 FLV 中确保 AMF3 支持的方式新增TagType 15而非 18以 AMF3 编码的 SCRIPTDATA 形式承载处理方式类似 Data Message。注意2023 年之前的 FLV 文件格式规范中SCRIPTDATA 并不包含 AMF3。9. 协议版本化与文档版本化9.1 协议版本无需版本号升级增强后的 RTMP 不需要对 RTMP 握手序列或 FLV 文件头版本字段进行任何版本号提升。所有增强都由新定义的位流格式触发且不破坏遗留实现——Enhanced RTMP 是**自描述self-describing**其能力的。9.2 文档版本化约定文件命名约定使用清晰的标识符与主版本号例如enhanced-rtmp-v2.pdf文档内版本信息在文档内专设一节或元数据说明版本细节包括主版本号、日期与开发阶段alpha/beta/release例如Status: v2-2024-02-26-a1日历版本Calendar Versioning格式v#-yyyy-mm-dd-[a|b|r]#其中v#主版本号跟踪 Enhanced RTMP 开发的推进yyyy-mm-dd文档更新日期[a|b|r]后缀区分 alpha、beta 与 release 阶段#同日期内的次版本号同日多次版本时递增。仓库中收录的该规范当前版本即为v1-2025-01-22-r2release 阶段其修订历史记录了从 v1-2023-03-23-b1 起的关键演进例如设置 IsExHeader 为 false 的 else 分支修正、HDR 元数据投递时序的细化、PacketTypeSequenceStart 与 PacketTypeMPEG2TSSequenceStart 互斥说明、videocodecid 支持 FOURCC、协议与文档版本化细则等。10. 在 Node-Media-Server 中端到端的落地验证以上规范并非纸上谈兵——Node-Media-Server 的源码将其落到了实际媒体链路上可归纳为一条完整的证据链打包侧生产者RTSP 拉流会话src/session/rtsp_client_session.js在检测到 HEVC 源后把videocodecid写成大端 FourCChvc1rtsp_client_session.js并通过encodeAmf0Data构造 onMetaData 广播包RTP 去载荷器src/protocol/rtp_depayloader.js则按 Enhanced FLV 格式打包 HEVC 数据[0]0x80|frameType4|0x01、[1-4]hvc1、[5-7]cts、[8-11]naluLength、[12..]nalurtp_depayloader.js序列头则写为0x80|frameType4|0x00hvc1 HEVCDecoderConfigurationRecordrtp_depayloader.js其注释明确标注Format per enhanced-rtmp-v1。广播侧分发广播服务器src/server/broadcast_server.js把 flags 为 2序列头、3/4关键帧/普通帧的包分别缓存为 FLV/RTMP 视频头与 GOP 缓存flags 为 5 的元数据包缓存为flvMetaData/rtmpMetaData同时提取videocodecid等字段回填发布者信息broadcast_server.js最终统一转成 FLV tag 与 RTMP 消息分发给订阅者。解析侧消费者FLV 解析器src/protocol/flv.js按第 4 节的位域逻辑识别 IsExHeader、FourCC 与 PacketType把 HEVC/VP9/AV1 流正确转成携带 codec_id 与 pts/dts 的 AVPacketHTTP-FLV、WS-FLV 等播放路径复用同一套广播链路因此 Enhanced RTMP 编码流可无缝分发到 FLV 播放器。可视化Webadmin 控制台按 FourCC 映射显示编码类型webadmin/src/pages/Streams.tsx使运维人员能直接辨认 H.265/AV1/VP9 直播流。仓库中的架构文档docs/architecture-overview.md、docs/data-flow.md对上述广播/分发链路有更完整的描述可作为进一步阅读入口。11. 总结与使用建议Enhanced RTMP/FLV 规范通过三个精妙的兼容性设计完成协议现代化位域复用——借用 FrameType UB[4] 的最高位定义 IsExHeader存量流该位恒为 0因此天然向后兼容无需握手或 FLV 头版本升级FourCC 信令——av01/vp09/hvc1以 UI32 编码既用于 VideoTagHeaderPacketType FourCC也用于 onMetaData 的videocodecid还通过 connect 命令的fourCcList做能力协商三处信令自洽统一元数据通道——PacketTypeMetadata 让 HDR 等视频元数据以 AMF 键值对colorInfo形式在视频消息内传递规避跨消息类型竞态并定义了严格的投递时序先于所影响的视频段与重置语义Undefined 或空对象。对于希望接入 HEVC/AV1/VP9 直播的开发者建议按以下顺序实践推流端按第 4 节格式发送PacketTypeSequenceStart携带编解码配置记录PacketTypeCodedFrames/CodedFramesX携带完整帧HEVC 的 CompositionTime 偏移按 SI24 毫秒编码或使用 CodedFramesX 省略零值若需要 HDR在对应视频段之前发送PacketTypeMetadata的colorInfo对象元数据声明在 onMetaData 中把videocodecid设为对应 FourCC 的大端 UI32 值并在 connect 命令中通过fourCcList与videoFunction0x0002 / 0x0004 等声明编码与元数据能力服务端验证直接以 Node-Media-Server 的 src/protocol/flv.js 解析逻辑为参考实现核对首字节位域拆分、FourCC 匹配与 HEVC CTS 计算是否符合预期。需要说明的是本文基于仓库收录的规范文档版本v1-2025-01-22-r2与当前源码状态撰写协议本身是自描述且向后兼容的未来规范版本如 enhanced-rtmp-v2若出现新的 PacketType 或 FourCC 取值应遵循解析到不理解的信令时优雅失败的原则处理。赞分享【免费下载链接】Node-Media-ServerA Node.js implementation of RTMP/HTTP-FLV Media Server项目地址https://gitcode.com/gh_mirrors/no/Node-Media-Server点击查看免费下载相关推荐Node-Media-Server 数据流架构全解析从 RTMP 推流到 HTTP-FLV 播放的完整链路Node Media Server 数据流架构全解析从 RTMP 推流到 HTTP FLV 播放的完整链路 Node Media Server 是一个基于 NMedia Downloader扩展元数据规范name、version与依赖声明Media Downloader扩展元数据规范name、version与依赖声明 Media Downloader作为一个基于Qt/C的youtube d桌面应用音视频SVG Crowbar深度解析从D3.js可视化到Adobe Illustrator的无缝转换SVG Crowbar深度解析从D3.js可视化到Adobe Illustrator的无缝转换 SVG Crowbar是一款专为Chrome浏览器设计的书签工开发工具上一篇MobileNetV4 Hybrid Medium.e200_r256_in12k移动端AI视觉的终极解决方案下一篇Matter协议权威解读官方白皮书与第三方分析深度对比指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表