最近正在开发的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,openvz的,无法安装bbr。最便宜的那种,一年才十来刀。在服务器上部署NMS v3.2.5, 使用ffmpeg循环推流一个1.2M码率的720p视频。大部分时候,国内rtmp协议访问很卡顿,大概有200ms的延迟,30%以上的丢包率。而使用kmp协议访问的话,基本上是流畅的。

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

如果kmp访问也卡,可能是测试的老哥较多,总带宽只有那么点,等一会儿再来试试。也可能是vps确实太卡了,测试时请结合ping一起观看。不管使用 TCP 还是 KCP,你都不可能超越信道限制的发送数据。

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

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

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

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

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

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 基于可靠UDP传输的KMP视频直播协议

还记得我刚入行时,那时候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上做一些研究,风云变幻谁又能说的定呢。

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 浏览器播放H265/HEVC视频的可行性分析

今天接到一个客户的需求,在不改变原有fms服务架构的条件下,对接到Node-Media-Server,提供HLS,RTMP,Http-FLV音频转码服务。

客户以往的架构是Flash在web推流,h.264+Nellymoser编码格式,这个用flash播放是没有问题的

但flash基本上已经被各大浏览器列为默认关闭了,Android,iOS等更是不会支持的。

现在的解决方案,基本上是往HLS,http-flv上靠。HLS提供了最好的兼容性,http-flv提供了最低的延迟性,各有优劣吧。

关键的问题在于,Nellymoser编码并非互联网上广泛支持的格式,就算服务端支持,客户端也基本(有h5客户端支持,后话)上无法实现。

因此,还需要使用ffmpeg进行音频转码。

架构如下:
fms端使用服务端编程,监听 onPublish 和 onUnpublish事件,将参数通过http传参调用。

nms增加api接口收到开始和结束的事件,调起ffmpeg从fms拉流,copy视频,aac编码音频后推到Node-Media-Server。

Node-Media-Server则提供出hls,rtmp,http-flv流。

注:NodePlayer.js 支持web浏览器解码播放Nellymoser,并且兼容各大pc,安卓,iPhone。
需要了解方案详情欢迎与我联系

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 记一次FMS对接Node-Media-Server转码服务

前期曾发布过一款windows平台RTMP推送摄像头画面的浏览器插件,近期对这款产品进行了升级,现已支持捕获桌面画面进行推流。

桌面推流当然首选OBS,专业性毋庸置疑。本人开发的这款产品定位为简单业务需求,只需引导客户安装5M左右大小的插件程序,无需任何配置,即可在web网页中进行摄像头或桌面画面的捕获推流。

在本次更新中,加入了H.265编码器的支持,视频码率更低。同时,在SSE指令集加速的软编码基础上,增加了AMD/NVIDIA/INTEL独显核显硬件加速编码,CPU消耗更低。

本插件同时也加入了直播播放器的支持,可以播放rtmp,rtsp,http协议的直播流,并支持硬件加速解码,首屏秒开与延迟消除技术。继续阅读

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: Windows平台浏览器内捕获桌面画面并RTMP推流

这是困扰N年的问题了,Adobe似要放弃但又不舍的flash,一直在更新,但大家呼唤已久的aac编码始终不肯加入。
于是基本上需要做高级点Web页直播的,不是让主播用第三方工具,就是在服务端实时转码,挺费劲的。
简单点的基本上全站flash的也有,flash仅做推流播放的也很多。

WebRTC在大家的期盼下也慢慢得到了大部分浏览器的支持,但结果一看这丫也不用aac,而是用的Opus,似乎是个版权问题?
Opus在语音与音乐等编码场景都能应对,但rtmp不支持呀,还是需要转码。协议接入也是一个麻烦点。

既然Adobe能开发flash插件,大家为啥不直接开发插件呢?

这个说起来似乎更痛苦,ie要开发ActiveX,win10 更新到Edge了,又不知道是支持哪种(有了解的朋友请告知我一下)?早先的chrome和firefox要开发NPAPI,现在不兼任了,又要开发PPAPI。
似乎只有大公司能折腾这些事吧。腾讯云好像有一款ActiveX的推流插件,但没仔细看。尽管可以兼容ie,做点行业应用,但你现在让前端做ie兼容的娱乐向页面,他分分钟摔键盘。

最近有一点研究时间了,回看了一下之前了解过的FireBreath,说是可以一次开发多个平台的浏览器插件,我觉得可以利用它来实现我一直想要实现的功能。
1.x版本可以支持ActiveX和NPAPI的插件,2.x说是准备兼容PPAPI,但似乎有点麻烦,这方面资料也不多,而且项目也已经很长时间未更新了。
似乎又陷入绝境。
继续阅读

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 如何在浏览器里面推送H.264+AAC的RTMP直播

最近在研究用Emscripten开发JavaScript的直播播放器,使用ffmpeg内置的h264解码速度还是可以接受的,本想使用openh264的解码进行比较,但发现非常慢,无法达到640×480@30帧的解码速度。

本来以前也有过用openh264的项目,直接使用libopenh264进行解码速度还是很快的。但编译进ffmpeg里使用就特别慢,于是-g重新编译NodePlayer.js并开始Chrome Performance录制。
继续阅读

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: ffmpeg.js使用libopenh264解码性能低的原因

iOS的浏览器环境,当然就包括微信,QQ内打开。目前实现直播的协议一般都是HLS, 延迟大可想而知,“真·实时” 当然指的是2秒以内的延迟。

浏览器环境下支持常见的低延迟直播,首选的是flv.js。它支持多种数据获取方式(fetch,websocket,xhr),兼容性很好。解析flv流后再封装为mp4数据,使用Media Source Extensions 特性,将数据投喂给播放器以实现实时的解码播放。按浏览器支持情况,具有硬件加速的性能。

而iOS是目前无法实现的平台,https://caniuse.com/#search=mediasource 可以看到,到目前为止系统11.2仍然不支持该特性。

但通过websocket+WebAssembly技术,可以曲线救国。我已经实现了一个初版https://github.com/illuspas/NodePlayer.js
继续阅读

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 如何在iOS的浏览器环境内实现 “真·实时视频播放”

重采样

Hi35xx 的音频输入和音频输出模块支持对音频数据实施重采样。如果启用 AI 重采样功 能,则在 HI_MPI_AI_GetFrame 获取数据返回前,内部将会先执行重采样处理,再返 回处理后的数据。如果启用了 AO 重采样功能,则音频数据在发送给 AO 之前,内部 先执行重采样处理,处理完成后再发送给 AO 通道进行播放。

音频重采样支持任意两种不同采样率之间的重采样。重采样支持的输入输出采样率 为:8kHz,11.025kHz,12kHz,16kHz,22.05kHz,24kHz,32kHz,44.1kHz, 48kHz。

  • 当 AI-AENC 或 AI-AO 的数据传输方式为系统绑定方式时,AI 或 AO 的重采样无效
  • 非系统绑定方式下,用户可以通过 HI_MPI_AI_GetFrame 接口获取重采样处理后的 AI 音频帧,并发送给 AENC/AO,以建立 AI-AENC 或 AI-AO 的数据传输,此时 AI 或 AO 的重采样有效。
  • ADEC-AO的数据传输方式无上述限制,当为系统绑定方式时,AO的重采样仍有 效。

当你使用hi35xxx_enc.cpp提供的方法来开发时,实际上重采样功能是无法实现的,因为在StartAenc方法里,AI->AENC是通过系统绑定的方式(HI3516A_COMM_AUDIO_AencBindAi)关联的,如果需要重采样功能,这个地方应该使用(HI3516A_COMM_AUDIO_CreatTrdAiAenc).
这个函数创建了一个线程,先从AI(HI_MPI_AI_GetFrame)里获取数据,再发送给AENC(HI_MPI_AENC_SendFrame),然后释放(HI_MPI_AI_ReleaseFrame),这时从AENC里取回(HI_MPI_AENC_GetStream)的数据,才是重采样后的数据. 当然,这一切的前提是需要HI_MPI_AI_EnableReSmp,并正确传入输入与输出采样.

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 海思 HiMPP-IPC 媒体处理平台开发参考阅读笔记 二

海思媒体处理平台架构

  • 视频输入 VI
  • 视频处理 VPSS
  • 视频编码 VENC
  • 视频解码 VDEC
  • 视频输出 VO
  • 视频侦测分析 VDA
  • 音频输入 AI
  • 音频输出 AO
  • 音频编码 AENC
  • 音频解码 ADEC
  • 区域管理 REGION

海思媒体处理平台内部处理流程图

继续阅读

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: 海思 HiMPP-IPC 媒体处理平台开发参考阅读笔记 一

前段时间Chrome自动升级到60.0.3112.90后,突然发现Flash无法访问摄像头麦克风了,不管是曾经设为信任的域名还是新域名,Chrome都不再弹出是否允许访问摄像头麦克风的提示框,这在59版本上都不存在的问题。

情况如图所示:继续阅读

原创文章,转载请注明: 转载自贝壳博客

本文链接地址: Chrome更新到60以后,Flash无法再继续访问摄像头麦克风?