短视频MV实现方案

在录制短视频的过程中,为了使你的短视频更有特色和看点,往往需要加入其他的素材、比如贴纸、美颜、背景音、MV等,本文介绍在短视频录制过程中添加MV的实现方案。

1. 功能介绍

短视频中添加MV,即在原视频的基础上添加、视频、音频、滤镜等组合因素,从而生成类似歌曲MV唱片的效果。
以下效果视频是通过金山云短视频生成的:

短视频MV实现方案_第1张图片
图1. MV视频效果

市面上大部分短视频的MV功能包含以下两个基本点:

  1. 有自己独立的资源包,资源包中包含添加的音视频元素及配置文本;
  2. 用户通过修改配置文件来调出不同效果的MV

金山云短视频提供在录制过程中添加MV的功能,我们致力于可以让用户方便快捷的自定义MV效果,并快速添加到正在录制的视频中。
金山云短视频MV可实现的功能有:

  • 支持录制任意时间段添加和删除MV,且支持在不同MV效果之间无缝切换;
  • 支持配置用户自定义滤镜及短视频中提供的所有内置滤镜,并且可以灵活配置滤镜参数;
  • 支持叠加音频;
  • 支持叠加视频;
  • 支持自定义MV时长。

2. 功能关键点方案介绍

2.1 MV资源文件的构成

如下图所示,一个基本MV资源需要至少一个config配置文件。
我们使用json文件来作为配置文件格式,方便配置和解析,并且可以做到平台无关性。

短视频MV实现方案_第2张图片
图2. MV json结构说明

下表为一个基本的MV资源包内容

文件名称 用途 备注
config.json 资源文件配置信息 必需包含配置文件
music.mp3 MV主音频文件 可以不包含
movie.mp4 MV主视频文件 可以不包含

2.2 用户如何配置MV

一个合格的配置文件,既要包含基本的信息配置,又需要配置的灵活性,在此之上最关键的点是如何把配置的学习成本降到最低。

短视频SDK设计的一个原则就是开发者可以快速理解配置,不需要在理解如何配置上耗费太多时间。
configroot结构中除了基本信息的配置外,我们设计了两个灵活的关键信息:

  • animations frame信息,包含某个时间点时MV具体作用效果,比如MV开始后何时滤镜开始,何时滤镜结束,用该信息来驱动MV的效果作用。开发者只需要学习配置animations 信息即可灵活变更同一主题的MV效果。
  • filters,滤镜信息,包含可以作用到MV上的所有滤镜信息。

下表为congfig中几个基本字段

key 类型 含义 用途
movie String 主视频路径 MV素材的主视频文件路径
music String 主音频路径 MV素材的主音频文件路径
duration long MV时长 单位:ms

用户在做MV配置时,可以提供movie或者music,但并不是必需的。
在设计上需要考虑用户配置的不同,我们采取依赖优先级:movie>music>duration的方案来做适配,即当存在movie时,MVmovie的时长为主时长,依次类推。

2.3 MV音视频数据的同步

MV携带的视频和音频如何同步到正在录制的文件中呢?
以下图为例:
为了使MV的配置更灵活,我们不依赖MV资源包中的主视频文件(movie.mp4)或者主音频文件(music.mp3)的pts变更来触发frame的作用效果,而是模拟了一条MV的timeline,该timeline以MV的开始时间为基准时间,duration为循环时间,心跳间隔为30ms(33帧/s),在每个心跳中,触发当前最近的frame中滤镜效果。

  • texture0pcm0分别代表采集的音视频信息
  • texture1pcm1分别代表MV的主视频和主音频信息,也就是资源包中的movie.mp4music.mp4
    ** textureFilter1textureFilter2分别代表对应frame*作用滤镜信息
  • MIX的含义是对音视频做混合
  • frame的触发条件:
//心跳触发事件
public void run() {
    ......
    //每个心跳中以当前系统时间作为MV的PTS
    long mv_pts = System.nanoTime() / 1000 / 1000;
    //frame的触发相对时间
    //frame.t即config中animations frame中的t,即frame的触发时间,该时间以MV的时长为参考时间
    //比如:duration为5000ms的MV,当设置t为200ms时,即在MV开始后的200ms触发该frame效果
    long current_frame_pts = frame.t + start_pts  
   if (current_frame_pts <= mv_pts) {
                 .....enable/disable effect
   }
}
短视频MV实现方案_第3张图片
图3. MV时间轴

建议提前使用animations frame中所有frame创建一个针对timeline的触发器,参考结构如下

TreeMap>
// Key为frame的t,不重复,value为这个t上面需要发生的所有的frame
// 建议使用有序的TreeMap结构

3. MV功能模块设计方案

我们在设计某一个功能模块时,有几点设计因素需要优先考虑进去:

  • 模块功能单一性:要把模块作为一个独立的单元设计;
  • 模块的复用性:从需求的扩展性考虑,该模块可以用于短视频录制,也可能用于短视频编辑,因此要考虑到模块的复用性。

基于以上因素,我们设计了一套独立MVC结构的的MV单元,使用者可以通过传入MV资源文件路径或配置json字符串方便的构造MV资源数据信息,并提供给SDK内部,SDK内部各个功能模块可以复用该单元。

短视频MV实现方案_第4张图片
图4. MV的设计

4. MV资源存储设计方案

建议将MV资源的zip包存储在server端,使用时动态下载MV资源到本地目录,有以下几点建议:

  • 对于资源zip做更新检查,可以比较zip包的md5信息,以避免不必要的下载和copy;
  • zip的包名和MV本地名称一致,方便识别mv;
    短视频MV实现方案_第5张图片
    图5. MV资源压缩

5. MV视频与主视频的透明重叠方案

H.264编码的视频是不支持alpha通道的,想要多个有叠加效果,就需要对叠加视频的alpha作处理。

5.1 方案一

提供movie_alpha.mp4,用movie_alpha.mp4视频中的灰度信息代表叠加视频music.mp4alpha值,该方案要求alpha视频帧数至少要大于等于原视频帧数。

  • 优点:准确的转换alpha信息;
  • 缺点:解析两个视频和计算所带来的性能损耗。
短视频MV实现方案_第6张图片
图6. 带*alpha*的视频重叠

如上图所示,解析movie.mp4的同时需要解析movie_alpha.mp4,帧对帧的将movie_alpha.mp4 gray信息赋值给movie.mp4alpha值,然后生成texture1
最终主视频信息(texture0)和采集视频信息(texture1)做混合。

// 从 RGB 到 YUV 空间的 Y 转换公式为:
Y = R*0.299 + G*0.587 + B*0.114
// 建议:为优化运算速度可转为整数移位算法
Y= (R*19595 + G*38469 + B*7472) >> 16

5.2 方案二

以黑色作为透明信息的参考值,将视频中纯黑色部分透明处理,非纯黑部分再和原视频做混合。

  • 优点:不用解析额外的视频;
  • 缺点:提供的MV视频不能存在有效的黑色或者接近于黑色的信息,否则会被过滤掉。
    短视频MV实现方案_第7张图片
    图7. 黑色信息作为alpha信息

    如上图所示,把movie.mp4的视频信息和采集的视频信息做一个混合计算最终生成texture即可。
//混合计算公式:
R = 1-(1-screen.R)*(1-video.R)
G = 1-(1-screen.G)*(1-video.G)
B = 1-(1-screen.B)*(1-video.B)
A = 1-(1-screen.A)*(1-video.A)

5.3 重叠方案的总结

目前方案二可以满足大部分的的MV场景,并且在性能和复杂度上要优于方案一,因此最终我们采用的是方案二。

6. 总结

在完成MV的过程中,遇到一些问题:

  • 使用MediaPlayer+SurfaceTexure的方式获取movie.mp4的视频textureMV切换时建议重复利用MediaPlayer+SurfaceTexure,不要反复创建SurfaceTexure,使用不当容易造成SurfaceTexture状态异常,抛出IllegalStateException
  • SurfaceTexureonFrameAvailable回调中建议配对调用updateTexImage,否则容易造成后续onFrameAvailable的事件不被触发;
  • 在有些机型上 调用SurfaceTexureupdateTexImage()时,有时会抛出IllegalStateException,不影响数据正确性的前提下可加try catch忽略。

金山云多媒体SDK团队在很用心地开发短视频SDK,欢迎试用和提issue:
https://github.com/ksvc/KSYMediaEditorKit_Android

转载请注明:
作者金山视频云,首发 Jianshu.com


金山云多媒体SDK仓库地址:
https://github.com/ksvc

金山云SDK相关的QQ交流群:

  • 视频云技术交流群:574179720
  • 视频云Android技术交流:6200036233

你可能感兴趣的:(短视频MV实现方案)