- Published on
监控辅助工具的实现过程(一)
- Authors
- Name
- 万码皆空
上次提到的监控工具的开发过程非常有意思,我打算把他整理一下贴出来供大家参考。一方面供有相似需求的人参考,另一方面提醒一下做开发的同学要把系统做完善,防止被别人利用漏洞。
起因
幼儿园提供的app限制太多,非常难用。作为一个程序员,第一想法就是能不能改变一下状况。
试验和测试
通过各种方法,终于拿到了直播地址,基于rtmp协议,结构如下:rtmp://xxxx.xxx/camera_id001?session=xxxxxxxxxxxx
。
使用工具播放和记录
我们可以使用ffmpeg来测试,既可以播放也可以记录,命令如下:
# ffplay播放
ffplay rtmp://xxxx.xxx/camera_id002?session=xxxxxxxxxxxx
# ffmpeg存储
ffmpeg -i rtmp://xxxx.xxx/camera_id002?session=xxxxxxxxxxxx -c copy path/to/save.mp4
尝试修改摄像头id
尝试更改camera_id001
为camera_id002
、camera_id003
来实现切换摄像头的目的,发现是可以的,而且不限于幼儿园开放给我的几个摄像头,还包括其他班级、教室、操场等的摄像头。
session的特点
经过对session的多番测试,得出以下结论:
session
需要在幼儿园开放摄像头权限的时间段内(08:30 - 16:30)才能拿到地址。session
控制的访问权限非常粗糙,只要合法就可以访问任意摄像头。session
有时效性 ,大概30分钟,在这段时间内,可以无限次访问。- 直播过程中没有合法性检查,即使
session
过期也可以继续播放,即使超过了幼儿园设置的关闭时间(16:30)只要不断开连接一直都能播放。 - 观看/录制过程如果因为意外断开链接,并且
session
已超时,就需要重新获取session
,但是在幼儿园设置的开放时间(08:30 - 16:30)之外是无法拿到的。
推测
这里有几点推测:
- 业务逻辑和直播系统分离。
- 业务逻辑服务测做了合法时间段检测,不在有效时间段访问不分配
session
。 - 播放时的有效时间段检测是在
client
端做的,超出有效时间直接在client
端断开连接。直播服务没有检测合法时间段并主动断开连接的功能。 - 直播服务一天会有两次重启,没错,是重启。一次是在13:30-14:00之间,一次是06:30左右。因为我会同时打开班级全部三个摄像头,他们总是在同一时间断开连接,并且总是在固定的时间段内,所以排除了我家里网络不好的可能。
初部解决方案
开始设想的很简单,每天早上手动获取session,使用ffmpeg和ffplay记录并播放,这样就解决了以下问题:
- 可以访问任意摄像头。
- 可以存储。
- 可以同时打开任意多个摄像头。
- 可以在幼儿园限制时间之外继续查看。
- mac/win/linux下都可以使用。
发现问题
可是使用一段时间之后就发现了很多问题:
- 获取session离不开电脑,有点事情就耽搁了。
- 加载缓慢,大概输入命令后需要等5分钟左右。
- 网络不稳定会导致断开,如果session已过期,又需要重新获取。
- 意外断开会导致记录的视频不可用。
- 不可用的视频可以通过工具(Wondershare Repairit)修复,可是修复后视频占用空间变得非常大。
解决加载慢的问题
通过查资料了解到ffmpeg需要先加载一定量的数据分析视频格式,修改设置一些参数能缩短加载时间。
# ffplay播放
ffplay rtmp://xxxx.xxx/camera_id002?session=xxxxxxxxxxxx -analyzeduration 500
# ffmpeg存储
ffmpeg -rw_timeout 10000000 -probesize 102400 -i rtmp://xxxx.xxx/camera_id002?session=xxxxxxxxxxxx -c copy path/to/save.mp4
经过添加以上参数,执行命令几秒钟内就可以播放/存储了。具体意义ffmpeg文档里有,就不多说了。
改善视频修复后空间大的问题
每个摄像头我保存的是一个文件,如果能分段存储,这样修复的时候就能轻松很多,查了查文档,又增加了以下参数实现以时间命名,每隔5分钟一段,每段都重置时间戳,存储的功能:
ffmpeg -rw_timeout 10000000 -probesize 102400 -i rtmp://xxxx.xxx/camera_id002?session=xxxxxxxxxxxx -c copy -f segment -reset_timestamps 1 -strftime 1 -segment_time 300 path/to/%H-%M-%S.mp4
总结
到目前为止,早期版本的监控查看/记录问题就算是不完美解决了。后来通过添加参数做了一些优化,基本上能凑合着用。这个阶段就这样吧,偶尔断开连接的问题,留给以后。
通过对对方系统的测试分析,有几个问题在做开发时要注意一下:
- 一些敏感数据不要用序号的方式标识,容易被利用。如过使用
uuid
做为摄像头的id,那即使有合法session
也很难发现其他摄像头的地址。 - 权限控制要完善,
client
端做限制很容易被绕过,必要的服务端限制不能少。
好了,今天就先说到这里吧,上个图看一下目前为止的效果。