NodeJS版本EasyDarwin开源流媒体服务器开发心得
title: Node版本EasyDarwin开发心得
date: 2018-03-27 22:46:15
tags:
年后着手Node版本EasyDarwin的开发工作,截止到今天2018年03月27日上线了第一个版本,今天小米发布了MIX2S, 致敬! 致敬!
关于RTSP协议
目前这个第一版暂时仅支持RTSP Over TCP, 不过RTSP Over UDP也会很快实现.总体来说, RTSP协议比较简单.开发过程中对RTSP协议的理解主要参考了 rtsp协议详解 这篇文章.sdp的解析一开始自己写的, 反复参考资料了解sdp各个字段的含义.后来偶然在npm上找到 sdp-transform 这个库, 处理sdp信息非常方便, 果断star了.
记录sdp两个细节的地方:
-
m
媒体描述下面有个属性名为control
的属性, 它的值和后续SETUP
请求的uri
的尾巴是对应的, 椐此可以明确SETUP
是音频还是视频. -
SETUP
携带的请求头Transport
中有个参数叫interleaved
, 这个东西常见的内容是一个偶数-一个奇数
, 这两个数值代表RTP传输的通道标识
.一个RTP包前面有4个节字的头: 1个字节的固定$(0x24)符;1个字节通道标识;2个字节的RTP包长度.对应的正是这个头里面的第2个字节.一般偶数表示数据通道, 奇数表示控制通道.
理解以上两点, 有助于在RTP传输过程中, 针对特定的视频格式, 缓存GOP,实现秒开效果.
NodeJS效率问题
从TCP流式数据中解析RTP包, 对NodeJS的处理效率是个考验.在初始阶段, 简单的利用 socket data 事件回调, 只要接收到数据, 就走一次协议解析. 实测发现一路播放的情况下都很卡顿. 最后是参考了 Node-Media-Server 中的 BufferPool 实现, 利用 Generator 和 yield. 只有当接收数据长度达到要求的时候, 才去做协议解析. 这样效率得到巨大提升, 播放不卡顿了. 中间还尝试过利用 socket pipe 将RTP包流转给播放端, 这样做确实效率很高, 也可以解决播放卡顿. 但是这种方式下, 解不到单个RTP包, 就无法做GOP缓存, 所以弃用了.
秒开实现
结合sdp中的媒体描述和 SETUP Transport interleaved 的值, 可以识别出一个RTP包携带的内容是媒体数据还是控制数据, 如果是媒体数据, 是音频还是视频, 如果是视频, 那么视频数据的编码格式是什么. 基于这些, 当收到携带h264数据的RTP包时, 做关键帧识别, 缓存GOP.
在RTP包中识别h264关键帧, 需要了解RTP包格式, h264 nalu type, fu-a 分包这些内容.这里我主要参考了CSDN上这篇博客 RTP协议全解析(H264码流和PS流)
总结
用Node实现EasyDarwin那样的RTSP流媒体转发, 最后的效果是令人满意的.目前的代码量很小.Node在处理字节流的过程中, 反复使用了自带的Buffer库函数. concat, slice, readXXXBE(以大端方式读网络字节序). 在这一版中, 我给它搭配了一个 HTTP Server, 提供了可视化的统计信息展示. 总之, Node.js 的引入将大大提高EasyDarwin开源流媒体服务的开发效率, 提升EasyDarwin的易用性.
获取更多信息
EasyDarwin开源流媒体服务器:www.EasyDarwin.org
EasyDSS商用流媒体解决方案:www.EasyDSS.com
EasyNVR无插件直播方案:www.EasyNVR.com
Copyright © EasyDarwin Team 2012-2019