关于点播视频文件生成封面的实现方案设计思考

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

本文同时参与 「掘力星计划」  ,赢取创作大礼包,挑战创作激励金

  • 目录
  • 前言
  • 现状
  • 需求
  • 实现方案
  • 结论与思考

前言

对于多媒体存储服务,点播视频文件生成封面应该是非常基础的功能之一,目前自己正在开发的多媒体存储服务就面临这样的需求。因为这个多媒体存储服务是从零开始的,缺少部分基础功能的情况,各位大佬别见笑。

但是,正是因为从零开始开发,因此很多之前被忽略的问题也渐渐浮出水面,映入了我们的眼帘。这个经历过程是非常可贵的,自己从中也学到了很多东西。

现状

首先,我们来看一下当前多媒体存储服务的现状。

目前,多媒体存储服务已经具备了上传、下载、观看预览、转码、查询、删除等基础功能。

文件结构体定义如下:

type File struct {
	// DefaultModel adds _id, created_at and updated_at fields to the Model
	mgm.DefaultModel `bson:",inline"`
	Name             string  `json:"name" bson:"name"`
	Md5              string  `json:"md5" bson:"md5"`
	Type             string  `json:"type" bson:"type"`
	Url              string  `json:"url" bson:"url"`
	Path             string  `json:"path" bson:"path"`
	Duration         float64 `json:"duration" bson:"duration"`
	CloudUrl         string  `json:"cloudurl" bson:"cloudurl"`
	Filekey          string  `json:"filekey" bson:"filekey"`
	Size             int64   `json:"size" bson:"size"`
}

type FileArray []File
复制代码

上述所有功能都是基于该结构体进行展开的。

需求

现在出现了一个新需求,就是为视频文件生成封面。我们应该怎样设计实现方案呢?

其实,大体的方案可以分为两类。一种方案是在原有文件结构体的基础上扩展封面相关字段,另一种方案是将封面作为一个单独的文件进行管理并与原文件做关联处理。下面会详细分析二者的区别及优缺点。

实现方案

方案一、在原有文件结构体的基础上扩展封面相关字段

这种方案,是继续扩展当前已经定义好的文件结构体,增加封面的关联地址,因此增加一个CoverURL字段就搞定了。乍一看,感觉没有毛病,但是深入分析一下就会发现问题。如果后续我们需要删除该点播视频文件,理论上应该把对应的封面文件也删除。这个时候,你会发现如果只增加上面的一个字段是不够的,缺少了操作句柄。因此,我们还需要增加一个字段CoverKey

按照上述方案,修改后的文件结构体:

type File struct {
	// DefaultModel adds _id, created_at and updated_at fields to the Model
	mgm.DefaultModel `bson:",inline"`
	Name             string  `json:"name" bson:"name"`
	Md5              string  `json:"md5" bson:"md5"`
	Type             string  `json:"type" bson:"type"`
	Url              string  `json:"url" bson:"url"`
	Path             string  `json:"path" bson:"path"`
	Duration         float64 `json:"duration" bson:"duration"`
	CloudUrl         string  `json:"cloudurl" bson:"cloudurl"`
	Filekey          string  `json:"filekey" bson:"filekey"`
	Size             int64   `json:"size" bson:"size"`
        CoverURL         string  `json:"coverurl" bson:"coverurl"`  // 新增项
        CoverKey         string  `json:"coverkey" bson:"coverkey"`  // 新增项
        // 后续可能还要继续增加。。。
}

type FileArray []File
复制代码

目前,上述结构体就已经满足当前需求了。但是,我们难道就仅仅满足当前的单一需求吗?我们是不是应该思考的更加长远一些?是的,作为一名资深的研发工程师,除了需要设计出满足当前需求的最佳实现方案,还需要具备后期的高可扩展性。

那么问题来了,如果我们后期想要查询或者修改封面的名字和大小,我们是不是还要增加新的 CoverNameCoverSize 字段?如果想要下载封面,是不是还要增加新的 CoverDownloadURL 字段......这次时候,你就会发现我们其实是复制了一遍文件结构体的所有字段,这样显然是不合理的。

如果是这样,那么有没有更好的可扩展方案呢?答案是有的,请参看方案二。

方案二、将封面作为一个单独的文件进行管理并与原文件做关联

这种方案,将封面作为一个单独的文件进行管理并与原视频文件做关联,能够解决方案一遇到的各种问题,同时,具备一定能力的可扩展性。如果想要满足当前需求,我们仅需要增加一个Cover字段,存储封面文件的ID,用来关联该视频文件的封面文件。后期对视频文件封面的所有操作都可以通过转换成封面文件的操作,因此简化了对封面文件管理逻辑。还有很多别的优点,大家可以自己思考补充,欢迎在评论区留言。

按照上述方案,修改后的文件结构体:

type File struct {
	// DefaultModel adds _id, created_at and updated_at fields to the Model
	mgm.DefaultModel `bson:",inline"`
	Name             string  `json:"name" bson:"name"`
	Md5              string  `json:"md5" bson:"md5"`
	Type             string  `json:"type" bson:"type"`
	Url              string  `json:"url" bson:"url"`
	Path             string  `json:"path" bson:"path"`
	Duration         float64 `json:"duration" bson:"duration"`
	CloudUrl         string  `json:"cloudurl" bson:"cloudurl"`
	Filekey          string  `json:"filekey" bson:"filekey"`
	Size             int64   `json:"size" bson:"size"`
        Cover            string  `json:"cover" bson:"cover"`  // 新增项
}

type FileArray []File
复制代码

大家会发现,方案二对原有文件结构体的修改程度最小,保证了文件结构体的简洁性和抽象性。同时,还满足了当前需求,又具备了一定的可扩展能力。

结论与思考

其实,日常开发过程中,我们经常会遇到各种各样的需求,解决方案也各式各样,我们想要成为一名资深的研发工程师,就要在统筹全局的前提下,寻找更加符合我们系统架构的实现方案。因为每个系统架构和业务线的设计和需求都不一样,很难找到一个大一统的方案,因此,我坚持的原则就是“设计开发实现方案时,没有最好只有更好”。上面就是本人分享的关于一次点播视频文件生成封面的需求设计和开发的思考过程,欢迎大家评论留言交流经验。

猜你喜欢

转载自juejin.im/post/7017260035449307150