最近因为项目需要一个摄像头在线预览功能,所以想到了一个小工具分享分享。项目在win上,合作者懂js。基于这种情况,我只选择了nodejs进行开发。与使用php无关。一开始对这个并不陌生,因为之前用过开源解码器FFmpeg,所以知道用它可以实现摄像头的rtsp推流到hls,只要转成hls就可以用了开源的video-js-control-hls播放m3u8文件,我司使用的是海康的软件产品,是开放接口,通过请求接口获取在线播放文件。思路很清晰,于是就有了这个想法,开始在npmjs.com上找wheels,经过一番寻找,终于选定了几个wheels。首先是fluent-ffmpeg,运行ffmpeg的中间件,然后是http服务hls-server,过滤掉所有不能和hls比的资源,只保留.m3u8和.ts资源。既然如此,轮子就摆在那里,接下来就是熟悉理论知识(音视频转码,ffmpeg等),浏览完大致的理论知识,接下来就是优化细节了。在做细节之前发了一个深思熟虑的问题(链接:做个海康摄像头到hls然后用h5玩细节)。郁闷的是平假名是别人看不出来的,知识就是力量,力量不够就是有问题,于是开始自己琢磨(基本琢磨了几个晚上)。琢磨了几天,找到几个重点:什么时候开始转码(服务启动时转码还是接口发送后收到转码通知时转码)当然是接口发送后收到转码通知时发送时无人看码,关闭转码服务,清除用户观看播放文件的时间为更新时间,并在服务端建立心跳检测。如果没有人看过该文件,则应关闭转码服务,并清空播放文件,记录该文件的观看时间。如果有人观看,时间将会更新。服务器将建立心跳检测。当时间超过设定的时间,就不会了从人的角度来说,就是管理ffmpeg进程,播放文件是否加入缓存。一开始并没有添加,每次请求都会生成一个新的播放文件。后来考虑到我们是在应用层开发,不是C++,所以还是加了缓存。当转码服务关闭时,当满足清理播放文件的条件时,缓存的url也会被清理。我做完这个版本后,发现还不够好,为什么还不够好,因为我开始转码生成播放文件,而且我在我的电脑和服务器上次测试的平均时间在11秒左右,最佳时间为3秒。在保证服务器配置的同时,还要思考是否有优化的空间。我的版本是api请求,然后使用fluent-ffmpeg方式创建ffmpeg进程,fluent-ffmpeg使用pipe向进程输入命令。然后我就想,我能不能预先生成ffmpeg进程,让它挂起来(就是把ffmpeg进程池做起来),然后api请求,我从进程池里取出一个,自动清理的时候,我将不再关闭它的进程,而是使用一个信号来暂停进程。我觉得这样应该可以加快生成播放文件的时间,减少api的等待时间。目前开始研究fluent-ffmpeg的源码,感觉没有从中找到方法,于是自己操作了一个例子。启动tcp后,我使用child_process.spawn创建ffmpeg进程。参考代码:server.on("listening",()=>{console.log('listening');constargs=['-i','pipe:0','-f','mp3','-ac','2','-ab','128k','-acodec','libmp3lame','pipe:1'];for(leti=0;i<10;i++){constffmpeg=spawn('ffmpeg',args);pools[i]=ffmpeg;}});理论上是可以的,这样创建的进程被挂起。后面我会在关键参数上加上pipeline,后面应该会实现。目前正在研究中,如果研究成功,我会发布第二个版本。最后附上一个git地址给大家,代码写得不是很好,我笑了:hk-hls
