1.视频播放存在的问题
前提介绍:首先是需要是需要把摄像机的视频接到我们的平台上,目前存在两种方式,一种是需要客户端去实现,一种是在服务器端实现,都是基于ffmpeg去做的
客户端实现,由于客户端有无数个,每一个客户端都去看同一个摄像机视频的时候,摄像机的压力是很大的
1.客户端实现方式,是使用代码调用nodeJS,搭建起来一个本地的容器,当界面打开视频播放查看摄像机实时视频的时候,客户端起一个websocket服务使用ffmpeg去切视频的截图,发送给前端,让前端是渲染,推送频率大致是1s/15次,这个时候用户看起来也是一个流畅的视频,当前方案存在的问题:当同时播放少量摄像机视频的时候浏览器渲染是没有问题的,但是当同时查看9路摄像机的时候,浏览器渲染会出现性能问题,出现视频卡顿的场景
2.客户端推送视频片段,常用的方案是生成m3u8的视频描述文件和ts视频片段.当前方案存在的问题在点击播放视频的时候,m3u8文件是在第一个视频切片生成之后才有的,比如规定视频切片的时间为10s/1次,因此在刚打开视频到打开后10s的时间段内视频是无法播放的
服务器端实现,每一个摄像机只会去拉取一次,摄像机压力比较小,存在的问题,在项目去做分布式或容灾的时候,这部分功能会出现问题
该方案是笔者最终采用的方案,因此会详细介绍
首先该方案的实现方式是编写脚本,在后台去拉每一个摄像机的视频,然后只存储每个摄像机最新100s的视频,在用户去查看摄像机视频的时候,用nginx去映射切出来的视频文件,
第一步:和前台规定在获取视频静态资源的时候使用带有固定标识的url,笔者规定使用的是ip/hls/摄像机id.m3u8
第二步: nginx配置
nginx.conf
mime.types
第三步:脚本编写(红色部分请填写摄像机的标准rtsp流信息,真实设备,因此划掉)
在启动该脚本的时候:nohup sh cameraStart.sh > /dev/null 2>&1 请不要输出日志文件,因为该进程在后台不停的跑日志文件在不停的增大
存在的问题:前台使用src打开m3u8文件,视频播放过之后不会主动清理历史的ts文件,在视频播放2h的时候,浏览器会挂掉,重新刷新之后则恢复正常,待优化
备注:曾经的实现想法是在用户想要看的时候再去切2s的视频,前台延迟两秒之后在去访问资源文件,在后台记录查看每一个用户的信息,当没有用户看的时候再去关闭掉该进程
1.在java代码执行ffmpeg命令的时候 返回Proress对象是不支持序列化的,因此只能保存到类的成员变量中,当服务器重启的时候,成员变量没了,但是进程还在,重启操作太过于麻烦(本来计划是保存在redis中)
2.当使用java代码去执行的ffmpeg命令的时候,视频播放几分钟之后就停止了,定位发现后台ffmpeg进程不再切实时视频了
定位结果(个人分析,带有自己猜测的东西,可能会存在问题)由于java的System是单例的,在执行commend之后,该进程就结束了,但是使用java代码启动的进程还会去上报信息(手动执行脚本,打印在控制台的文本信息),保存到Process的缓冲区中,当缓冲区满了,ffmpeg的进程也就不在切视频了
表现的现象为:m3u8文件中EXT-X-MEDIA-SEQUENCE字段不再增加