万码皆空的博客
Published on

监控辅助工具的实现过程(一)

Authors
  • avatar
    Name
    万码皆空
    Twitter

上次提到的监控工具的开发过程非常有意思,我打算把他整理一下贴出来供大家参考。一方面供有相似需求的人参考,另一方面提醒一下做开发的同学要把系统做完善,防止被别人利用漏洞。

起因

幼儿园提供的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_id001camera_id002camera_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下都可以使用。

发现问题

可是使用一段时间之后就发现了很多问题:

  1. 获取session离不开电脑,有点事情就耽搁了。
  2. 加载缓慢,大概输入命令后需要等5分钟左右。
  3. 网络不稳定会导致断开,如果session已过期,又需要重新获取。
  4. 意外断开会导致记录的视频不可用。
  5. 不可用的视频可以通过工具(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

总结

到目前为止,早期版本的监控查看/记录问题就算是不完美解决了。后来通过添加参数做了一些优化,基本上能凑合着用。这个阶段就这样吧,偶尔断开连接的问题,留给以后。

通过对对方系统的测试分析,有几个问题在做开发时要注意一下:

  1. 一些敏感数据不要用序号的方式标识,容易被利用。如过使用uuid做为摄像头的id,那即使有合法session也很难发现其他摄像头的地址。
  2. 权限控制要完善,client端做限制很容易被绕过,必要的服务端限制不能少。

好了,今天就先说到这里吧,上个图看一下目前为止的效果。

监控