最近正在开发的NMSv3版本,新增了一个激动人心的特性:KMP协议。
这是一个基于可靠UDP传输的流媒体协议,支持推流与播放。

K是什么意思呢,当然是快啦 😛 ,不保留的说,是kcp。
KMP全称 Kuai-Media-Protocol, 又土又俗,我喜欢。kcp相信各位善于【那啥】的老哥都懂,不清楚的请自行google。

我接触RTMP协议,初算下,大概8年多了。 一个我自认为互联网历史里最具色彩的flash技术中的一个网络传输协议。眼见flash起高楼,宴宾客,楼塌了,chrome每天都在善意的提醒判决死缓2020 年12 月执行。当然这丝毫不改变我觉得Adobe是伟大的公司。 就这么个遗产,成为了当今世界视频直播领域的标准,带动了多少产业–游戏主播与平台、网红直播带货等等等等,创造的价值那真是数不清, http-flv也是它家的技术。

RTMP是基于TCP协议设计的,设计之初估计也没预料到3G, 4G环境, 1080P高码率。可以预见到5G时,直播4k会是很平常的事。网络基础决定上层应用。 网络状况好的时候,体验那是相当好,但稍微开始掉包或者信道拥堵,弊端出现,TCP重传机制这时候会卡成狗。不是说谁的不好,而是交互型视频直播非常在意低延迟,像http协议,也是TCP,但遇到这种情况你不会太在意,因为就是多等一下,结果都一样。但视频就不一样了,一卡一动,音频更难受。HLS协议设计之初就说,咱多缓冲些,大缓存抵消抖动。但国内不喜欢这个,就爱低延迟的。经常有老板说,咱能整进毫秒级延迟不。

Adobe也设计了基于UDP传输的RTMFP协议,还能P2P分流,那是相当牛逼,可惜设计的太复杂了,至今我了解的只有mona一家实现了客、服两端,我也不打算看这个,太南了。

如果网络从来不丢包,那么你直接用 TCP就行了,甚至直接裸UDP都没关系,但是网络因为丢包造成卡顿,特别是高峰时期丢包会上到10%的情况,移动设备上这个情况更糟糕。

skywind3000/kcp

kcp协议快就快在重传机制上,具体细节咱就不在这儿讨论了。实际上google也提出了BBR算法来加速TCP重传,效果也非常不错,服务器一经开启提升特别明显,而且对现有应用架构没有任何改动,但是只能在linux内核4.9以上开启。

我在kcp基础上,增加了视频封装等应用层协议,实际效果非常理想。

我开了一台洛杉矶机房的VPS,在服务器上部署NMS v3.2.5, 使用ffmpeg循环推流一个1.2M码率的720p视频。大部分时候,国内rtmp协议访问很卡顿,大概有200ms的延迟,30%以上的丢包率。而使用kmp协议访问的话,基本上是流畅的。

windows测试工具: http://www.nodemedia.cn/products/node-media-client/windows/
kmp测试地址:kmp://shoe.nodemedia.cn/demo/xxm
rtmp测试地址:rtmp://shoe.nodemedia.cn/demo/xxm

当然也可以在本地部署测试服务器,只需要使用linux的tc工具模拟丢包就行。
http://senlinzhan.github.io/2019/04/15/linux-loss-delay/

接下来我会将这个协议加入到android,iOS的SDK中,为移动应用提速。

实际上我也实现了推流的规范,使用KMP协议推流相比RTMP有什么好处呢?显而易见,当你的流媒体服务器在国外,而你还有一部分国内用户需要推流,需求反过来也一样。那直播体验效果绝对飞跃。要知道,播流卡一个,推流卡全部。

KMP协议还可以应用在服务器之间relay,试想如果在全球部署流媒体服务器,那么流分发时使用KMP协议,即使是跨越大洲大洋,依然能保持低延迟!

另外,文中提到的KMP协议只有我开发的NMSv3支持。

说明

HLS是目前浏览器无插件直播兼容度最高的协议,但是存在延迟大的问题。
http-flv普遍可以达到秒级甚至毫秒级延迟,HLS在Apple官方推荐的参数是10秒一个切片,一个m3u8列表包含3个ts切片,这就是为什么大部分HLS协议延迟30秒的原因。

nms 支持自定义切片时长和列表长度,默认配置未开启HLS,因为开启后会产生文件IO, 若有这方面需求请手动开启。

开启方式

打开config.ini
删除hls_path前的注释

延迟说明

代表每2秒切片一个ts,m3u8列表中保持3个ts,这样算下来,延迟是6秒。

极限低延迟

代表每1秒切片一个ts,m3u8列表中保持2个ts,这样算下来,延迟是2秒。
这种低延迟的设置,有两个必要的前提:推流时,视频编码的关键帧间隔是1秒一个关键帧,网络延迟低于100毫秒且带宽足够。
可用做内网环境应用,需要自行评估是否能满足流畅度。

播放方式

nms v3版的HLS流同样遵循 /app/stream 资源定位规范,只需要添加.m3u8后缀。
如推流地址:

则hls地址为

会话型HLS

nginx-rtmp对HLS的实现模式,只是简单的在推流后只生成m3u8和ts文件,并提供http的静态文件服务。无法进行会话管理,无法统计hls播放量,无法获得播放和结束的事件。
nmsv3的HLS实现,采用了session会话管理,可以定位访问资源的用户id,ip,访问参数,可以使用内置鉴权规则,可以统计播放量,可以统计用户使用的流量,可以获得用户开始播放和结束播放的事件。

H265/HEVC 编码的 HLS流

nms支持H265/HEVC编码的视频输出HLS流,m3u8采用v7,视频采用fMP4切片。
注意,只有MacOS 10.13,iOS 11之后支持,所有chrome,firefox不支持。Windows下,ie11,edge12-18在硬件支持的情况下支持。部分手机内置浏览器支持(小米)。
具体分析请看:浏览器播放H265/HEVC视频的可行性分析

向流媒体服务器推流

NMS v3支持RTMP, HTTP-FLVT推流

使用ffmpeg读取本地文件,向nms推送RTMP流

INPUT_FILE.mp4 是h264+aac编码

INPUT_FILE.mp4 是h264+其他音频编码

INPUT_FILE.mp4 是其他音视频编码

使用ffmpeg读取本地文件,向nms推送HTTP-FLV流

INPUT_FILE.mp4 是h264+aac编码

使用ffmpeg读取RTSP流,向nms推送RTMP流

INPUT_RTSP 是h264+aac编码

使用ffmpeg读取本地H265视频,向nms推送RTMP流

Adobe官方定义RTMP,FLV是不支持H265的,需要使用打过补丁的ffmpeg, 若需要,请与客服联系。

从流媒体服务器播放视频

先确保流媒体服务器存在 /live/stream 流,若不清楚,请查看上一步推流操作

使用ffplay播放 rtmp流

使用ffplay播放 http-flv流

使用ffplay播放 hls流

使用NodePlayer.js 播放 ws-flv流

还记得我刚入行时,那时候3G还没普及,做视频只能做172×144,清晰点的320×240。取监控画面大多还是352×288,或者很高清的D1了。
在视频领域现如今,短短几年时间,网络带宽飞速提升,图像传感器的像素越来越大,人们对画质的追求也越来越高。1080只是起步,2K, 4K的应用也不在少数。

传统的H264算法在这时候捉襟见肘,更高级的编码规范应运而生。HEVC也就是H265,VP9,AV1,还有我国的视频标准AVS2就是它的继任者。谁能在这场较量中胜出呢。

高效率视频编码(High Efficiency Video Coding,简称HEVC),又称为H.265和MPEG-H第2部分,是一种视频压缩标准,被视为是ITU-T H.264/MPEG-4 AVC标准的继任者。

我接触到的业务很多和视频监控领域相关,近一两年来,越来越多的监控厂家新出厂的设备,默认采用H265视频编码了。当我们要部署这类视频应用时,客户端解码是个大问题。pc应用可以采用厂商提供的SDK,通用一点的办法是使用ffmpeg的HEVC解码器。而更多的企业应用更愿意部署在web平台,在浏览器中播放。

我们通过这个链接(1)可以查到,只有ie11,edge12-18具有硬件解码能力的才能支持。Apple系macOS在10.13 High Sierra,iOS在11以后可以原生支持。所有chrome系不支持。windows不提供软解解码h265的能力,只有显卡硬件支持才能支持,而且edge马上要更换到chrome平台了。毕竟H265授权费是很高的,像微软这种用户量级,那肯定是天价,干脆交给显卡厂商来处理。苹果本身是这个标准组织的成员,有大量这方面的专利,因此它很乐意推广这个标准。在WWDC17上,苹果就宣布HLS格式支持HEVC编码,(2) 需要使用fMP4进行切片。NMSv3.2开始,支持输出HEVC编码的HLS流。

那么要实现通用的跨平台,跨浏览器支持的解码器方案,现如今只有1个方法,WASM,NodePlayer.js便支持这种方式。我也曾在一款海康NVR上发现它的web控制器也采用了这种方式,数据通过websocket传输,但不是一种通用的标准。当然这种方式解码性能不足,面对高清画面解码时要求本地机器有很强的单核处理性能。海康便要求一次只能播放一个高清主码流。而NodePlayer.js v0.6版,采用webworker方式,将多路解码分散到多个进程中,提升了多路视频打开时的处理能力。并且传输协议也是目前最常见的http-flv,websocket-flv,支持包括nms,阿里云直播服务。也兼容阿里云H265 over http-flv。

后记:其实我们还是有很多其它选择,google系开放的VP9,和VP9的继任者AV1,至少在Apple系以外可以得到广泛的支持。国家的视频标准AVS2,目前很少有接触到软硬件的应用。后期我会在AV1和AVS2上做一些研究,风云变幻谁又能说的定呢。

模板说明

创建relay中继任务,实际上就是rtmp的play或publish操作。
当我们连接远端服务器时,对方可能开启了鉴权规则,那么我们的链接也必须要附带鉴权参数。
由于目前常用的鉴权方式是附带过期时间戳的,因此每次请求时都应该是不同的签名。
当然您也可以预生成一个过期时间特别久的比如1年以后过期。
使用nms的relay规则,可以在创建时填入签名参数的模板,在nms进行relay中继任务创建时根据模板生成新的签名参数。

模板例子

nms模板

讲解:
前面我们的鉴权算法中有说明到,生成签名前的字符串需要流信息+过期时间+密码后md5
上面的模板字符串可以分为3个部分

继续阅读

需求简介

目前使用监控摄像头可以做非常多的行业应用,我们的客户案例中,涵盖了幼儿园监控手机直播,远程课堂直播,重点监控单位中心监控与手机监控,抓娃娃机,宠物监控远程喂食,甚至还有远程投币祈福等等等等,没有做不到只有想不到。
而传统监控摄像头统一的协议标准是RTSP,而直播行业目前统一的标准是RTMP。要将两者结合起来最简单的方式,是通过ffmpeg命令输入rtsp,输出rtmp。将视频流分发到自建服务端或者直播云服务,再由各个客户端根据需求播放rtmp或在http-flv。
这种方式需要解决如下问题

  1. rtsp流地址生成与通道管理,各个厂商之间的流地址格式是不同的
  2. 进程调用的维护,错误处理与断线重连问题
  3. 原生rtmp协议不支持监控行业日益流行的H265视频
  4. 部分云服务和web客户端不支持监控设备常见的G.711音频

解决方案

  • NMS内置了一个Relay中继模块,可以通过web后台简单添加rtsp拉取任务,无需编写配置文件,无需重启服务。
  • 目前支持海康,大华,宇视直接配置参数创建拉取任务,后续会增加其他厂商的规则,如果您是监控厂商,想要在NMS中增加品牌RTSP规则,请直接与我们的商务服务联系。
  • 也支持自定义模式手动输入rtsp地址和rtmp地址。
  • 任务创建后,服务会立刻去执行,并且在web后台反馈状态信息。relay任务也会在输入或输出中一项断开后自动重连,并将relay任务写入本地数据库,在nms服务程序重启后继续执行,直到任务被删除。
  • relay模块支持H265编码推拉流,NMS也支持h265编码的RTMP协议

使用方法

继续阅读

NMS内建支持简单且非常安全的,基于密码和过期时间的鉴权模式。
与阿里云的直播鉴权模式比较类似。

开启方法

打开config.ini

鉴权密码

播放鉴权开关

0-关闭,1-打开

推流鉴权开关

0-关闭,1-打开

使用方法

继续阅读

功能简介

NMS支持在服务端收到流开始播放,结束播放,开始推流,结束推流时回调一个web服务接口。
可作为后台管理程序进行自定义鉴权,统计推流播放信息包括ip,开始结束时间,url参数,使用流量等。

开启方法

打开config.ini文件,取消notify_url前的注释,填上接收回调的web api地址。
如:

简单用例

我们使用nodejs创建一个简单的web api接口,并打印接收到的信息

继续阅读

nms直接运行后,可以看到控制台输出打印

可以看到 rtmp服务绑定1935端口,http和https端口分别是8000和8443

1935作为rtmp的默认端口,可以在使用时不填写,比如

8000端口作为http-flv和websocket-flv端口,需要跟上端口号和.flv后缀

API接口和管理后台复用8000和8443端口,浏览器直接访问web后台

http://server_ip:8000/