ffmpeg.js使用libopenh264解码性能低的原因

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

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

如何在iOS的浏览器环境内实现 “真·实时视频播放”

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的浏览器环境内实现 “真·实时视频播放””

How to debug node.js addons in xcode

I recently started programming native addons but couldn’t find how to debug them easily. After couple nights, I found very easy solution described below.

To debug native addons generate an xcode project file. From the root of your project (where binding.gyp lives) run:

This will create ./build/binding.xcodeproj folder, which you can open:

Once project is opened, make sure to configure the scheme. Open Product -> Scheme -> Edit Scheme, and then: 继续阅读“How to debug node.js addons in xcode”

海思 HiMPP-IPC 媒体处理平台开发参考阅读笔记 二

重采样

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以后,Flash无法再继续访问摄像头麦克风?

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

情况如图所示: 继续阅读“Chrome更新到60以后,Flash无法再继续访问摄像头麦克风?”

重写了Node.js版的Node-Media-Server

第一次尝试用Node.js实现RTMP服务器是在15年初的时候,那时候刚完成Android/iOS平台上rtmp播放发布SDK:NodeMediaClient的雏形.
那时候有个参考项目https://github.com/iizukanao/node-rtsp-rtmp-server,当时的完成度算是比较高的了(Node.js实现) ,不过作者很牛,是用coffee-script实现的,基本看不懂,转译后的js代码也比较难读.
另外这个项目最大的问题是RTMP协议包解析,性能非常低.如果你单推一个1080的视频,cpu直接起飞,还不说播放.
这倒不怪作者,Node.js这种异步回调的模式,处理RTMP这种复杂数据包非常不利.
而我使用的解决方法是用到ES6的Generators+stream,封装为一个bufferpool.
socket异步回调数据的时候,往bufferpool里填数据,解析线程(这里也可能应该叫协程)先尝试询问是否有足够的数据,不够就yield,将CPU让给其他处理,当异步回调继续push数据时,如果达到上次需求的数据量,cpu就跳到刚刚yield的协程处继续往下解析.
仍然是单线程事件驱动,但数据解析是同步的逻辑.

发送逻辑暂时是用emit事件去通知socket发送data,可能比直接发送要多费些cpu,后面的版本继续优化.

也不限制音频编码了,以前的版本只支持H.264/AAC这种组合,现在speex,nellymoser也支持.

直播中首屏启动速度也是非常重要的,以前都叫秒开,现在得叫毫秒开.其实很关键的技术就是除了第一帧的sps/pps,紧接着就得来一个视频关键帧.
播放时当然不是每次都遇到第一个视频关键帧,所以得把推流端最近的关键帧缓存起来,播放时先把缓存的关键帧推下去.
就是GOPchache啦,nginx-rtmp还没有这个功能,体验还比不上SRS.
Node-Media-Server当然也支持啦,缓存最近的一个GOP.而且在Nodejs中实现也是非常非常简单的,这里就不多讲了,看代码吧.
当然就有人说有GOP缓存,延迟就大了,这是对的.不过自己实现播放端的话,还是很容易通过播放队列的长度来进行快进播放或丢弃处理,这样首屏毫秒开,延迟也可以自由控制.NodeMediaClient里,NodePlayer播放类就有两个参数,bufferTime和maxBufferTime.既保证首屏好秒开,又保证视频延迟低.

另外这次重写也新学了ES6的一些新特性和规范,代码写起来也比较规范吧.

后面可能还会继续实现其他的一些功能像是http-flv,hls,录制,转推,多进程这些硬性要求
也可能会实现Server Application,RTMPE,WebSocket,ffmpeg转码等
也或者支持接入WebRTC流,RTMFP等

项目地址:https://github.com/illuspas/Node-Media-Server
国内镜像:https://gitee.com/illuspas/Node-Media-Server

使用MSYS2编译Windows平台FFmpeg问题集合

1.安装了speex但找不到

2.configure 配置完以后提示找不到cmp命令

……后续继续补充

适用于Raspberry Pi的RTMP直播推流器

很早前入了个Raspberry Pi 1代和一个摄像头模组,准备做直播推流设备.

尝试过第一个方案:
raspivid+ffmpeg串流rtmp直播,效果不太好.
ffmpeg对输入流分析太费时,影响直播的时效性.

第二个方案:
后来ffmpeg-3.1好像,更新了OMX实现的H.264编码器,Raspberry Pi通过插入bcm2835-v4l2内核模块,映射出/dev/video0设备,ffmpeg再使用V4L2接口直接进行取摄像头并硬件编码推流.
720分辨率也能行,30帧没有问题,CPU也占用很少,但缺点是分辨率增大后(1080),v4l2取摄像头数据的帧率实在太低,只有6帧左右.
并且不能像raspivid那样方便的设置摄像头参数,比如水平\垂直翻转,角度旋转,亮度,ISO,白平衡这些.
这个方案也被pass.

第三个方案:
参照raspivid,使用OpenMAX IL接口进行摄像头数据捕获->硬件编码->rtmp传输.这个需要进行一点编程开发,由于后来做NodeMediaClient项目,一直耽搁了.
继续阅读“适用于Raspberry Pi的RTMP直播推流器”