HTML5技术

记录服务上线一年来的点点滴滴 - myd620

字号+ 作者:H5之家 来源:H5之家 2016-12-23 13:01 我要评论( )

2015年12月,也就是在一年前,开发了半年的云存储服务上线。这对于付出了半年努力的我们来说,是一件鼓舞人心的事件。因为这个服务在我们手上经历了从0到1的过程。这是我们自己的一小步,却是整个云存储服务的一大步。 我们开发的是一款视频监控类的软件,分

2015年12月,也就是在一年前,开发了半年的云存储服务上线。这对于付出了半年努力的我们来说,是一件鼓舞人心的事件。因为这个服务在我们手上经历了从0到1的过程。这是我们自己的一小步,却是整个云存储服务的一大步。

我们开发的是一款视频监控类的软件,分为视频采集端跟观看端。采集端可以是专业摄像头,手机,无人机等各类智能设备,观看端一般是手机或者电脑。最基础的功能,就是视频观看,采集端实时采集图像,编码,传输,观看端进行点播服务。同时采集端可以监测视频画面的运动幅度,然后触发报警,并且会录制报警视频。我们的云存储服务就是将录制的报警视频上传到云端,并且在观看端提供查看功能 

2.0 石器时代

第一个版本叫2.0,至于为什么叫2.0,或许这只是一个代号而已。

整个系统的框架如下:

 

整个系统由客户端, web服务器, 数据库, 文件存储服务器构成。文件服务器使用的是亚马逊的S3,对于小公司来说,选择亚马逊比自建存储的成本要低得多。

我们要求系统要尽可能及时的上传报警视频。一个报警视频大概录制30s,及时意味着报警一旦触发就要开始上传,而不是等报警视频录制结束了再上传录制下来的报警文件。而且在有些设备上,如摄像头,是可以没有存储卡的,但是也得能上传,所以选择上传报警视频文件的方式就不可取了。而在s3服务使用的是http协议上传文件,必须在上传文件之前告诉服务器文件的大小,即http头里面的content-length信息。为了解决这个问题,我们使用了分片上传的方式。就是首先根据视频的分辨率大小,计算出一个文件size,这个大约能存储10s左右的视频。在上传过程中,计算已经上传的数据量大小,当一个分片存储满之后,再开始另一个分片。在最后一个分片时,可能报警视频已经录制结束了,但是分片还没存满,这时候就用空数据填充。当然空数据的位置也得记录下来,这样观看端在播放时,就不至于把空数据当作正常数据,导致播放失败。除了正常的视频数据,在每段报警视频的最后还得记录视频中的I帧位置信息,主要是用于在播放时拖动,寻找位置信息。这一点是参考mp4文件的录制方式,由于我们使用的并不是标准的mp4格式,所以在上传视频的过程中,得将I帧的位置信息记录下来,待整个视频上传结束后,将位置信息存储在视频的尾部,最后不足一个分片的部分,再用空数据填上。

整个采集端来说,上传文件到亚马逊S3的过程就是如此,那么跟web服务器又是怎么交互的呢?

第一步,采集端在触发了一个报警时,要向web服务器申请一个EVENTID,作为这个报警事件的唯一标识,在之后上传文件都跟这个EVENTID绑定。观看端在播放时,根据这个EVENTID查到它对应的视频文件,然后去亚马逊S3上下载播放。

第二步,当采集端向亚马逊上传一个分片文件时,需要生成一个uri,然后才能向这个uri PUT数据。uri的生成,采集端可以直接向亚马逊申请,但是考虑到申请uri需要携带亚马逊的账户秘钥,放在客户端做不安全,所以申请uri还是放在web服务器上。当采集端需要上传文件,向web服务器去申请。每次采集端申请uri时,带上EVENTID,以及一个分片index,即告诉web服务器你要申请的是哪个eventid的第一个分片。生成的uri格式如下

。前面的xxxx表示你在 s3上面创建的存储桶,index即是第几个文件, avi是文件的后缀名(这里是一个假设,叫什么都可以)。每开始一个新的分片,index自动加1,这样在只需要记录一个最终的index即可。下载时,根据最终的index大小,就可以把所有的文件都下载下来。当申请到uri之后,采集端就可以通过http协议向这个uri上传数据了。

第三步,在每个uri上传结束之后,向web服务器report一次 event信息。这个event信息,即是第一步开始时申请的eventid。汇报的信息,包括这个event 的触发时间,类型,视频时长,视频分辨率,音频的采样率,以及index。可以看到,每个uri上传结束都汇报一次的信息,其实也只有index的值不同,其他的值都一样。本来是可以等到在一个视频完全上传结束之后,一次性汇报一次event信息就OK了。但是考虑到,当一个视频正在上传的过程中,采集端软件crash了,或者小偷进来后里面将监控设备砸了,所以要每上传一个分片都要汇报一次。这样,观看端查看时,就可以看到一个未完成的视频了。除了这点外,也要注意到可能一个分片都没上传上去,就发生意外,所以我们在每次报警一触发,就立即抓一幅图片,上传到S3上。

上面基本就是整个系统上传部分的流程。web服务器负责生成eventid, 申请uri,以及写数据库。数据库只要存储一张event表项就可以了,表项里面记录了这个event 的详细信息。

在2.0版本中,虽然使用了redis缓存,用来降低mysql的访问压力,但是缓存的使用很简单,仅仅存储了一个采集端每天的event个数。这样观看端查询时,可以一次性获取到最近30天,每天的event个数。因为我们只给用户保留最近30天的数据,在redis上做了个数统计,就不用再去数据库读表统计了。

接下来再说说观看端的查询流程

首先,就是去查询采集端最近一个月每天的event个数。

然后,再具体查看某一天的报警时,带上日期,起 始时间段,去服务器查询event列表。在返回结果之后,将event信息作本地缓存。如果下次再查询,先查看本地缓存中是否存在,如果有就直接返回。

最后,根据web服务器返回的event信息,包括了这个event对应着亚马逊服务器上的uri,通过uri下载视频数据播放。同时也将视频数据缓存到本地文件中,供下次查看时使用。

 

3.0 青铜时代

2.0版本完成了0到1 的跨越,但是整个系统与服务还处于初级阶段。在刚上线之后,就开始了3.0的开发工作。

3.0版本的主要目的是完成视频数据与事件的分离。在2.0 版本中,我们以事件为单位,向AWS 上传文件,这种业务模型有着一定局限性,文件数据强依赖事件。理想的状态应该是,文件数据应该是一个整体,而不应该按照事件来划分。事件只需要记录,其对应的文件数据即可。对于一个事件,我们只需要在数据库保存它的一些基本信息(比如时间,类型等等),然后记录下这个事件对应的数据在云端的位置。这样做有两个好处:

1 数据与事件解耦,云端存储的只是一堆文件,易于维护

2 数据可以复用,比如两个事件发生的时间有重叠,在2.0版本,重叠的数据就要上传两次,浪费了存储空间

 

 

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • WebStorage记录滚动条位置 - 南山北缘

    WebStorage记录滚动条位置 - 南山北缘

    2016-12-23 11:05

  • Bootstrap 我的学习记录4 轮播图的使用和理解 - 浪迹灬天涯

    Bootstrap 我的学习记录4 轮播图的使用和理解 - 浪迹灬天涯

    2016-12-17 10:01

  • Bootstrap 我的学习记录3 导航条理解 - 浪迹灬天涯

    Bootstrap 我的学习记录3 导航条理解 - 浪迹灬天涯

    2016-12-17 10:00

  • Bootstrap 我的学习记录2 栅格系统初识 - 浪迹灬天涯

    Bootstrap 我的学习记录2 栅格系统初识 - 浪迹灬天涯

    2016-12-14 12:01

网友点评
c