为了方便视频编辑功能的高度定制和功能拓展,微剪提供了以轨道为核心的数据驱动机制。
升级后的数据流转以 Clip 为播放单元,以视频轨道为单位的数据结构作为管理单元。一组完整的视频编辑数据是以轨道为单位的数组,每个轨道内存储了对应类型的 Clip 片段。
词汇 | 含义 |
Track | Track 即轨道,播放器支持多种轨道,如:媒体(视频 或者 图片)、音乐、特效、滤镜、文字等。 每一种类型的轨道对应不同类型的 Track。 |
Clip | Clip 即轨道中的素材片段。例如: 需要编辑三段视频,那么需要将三个视频片段加入媒体轨道中,那么这里的每个视频片段就对应不同的 Clip,每个 Clip 的属性会不相同,如视频时长、开始结束时间等。 |
引用微剪的数据结构
微剪小程序提供了封装好的数据类型,引用方法如下:
1. 在小程序的
app.json
中配置插件的引入:{"plugins": {"myPlugin": {"version": "1.2.2","provider": "wx76f1d77827f78beb"}},}
2. 在小程序的
app.js
中requirePlugin
取到插件的 js 接口:var myPluginInterface = requirePlugin('myPlugin');App({onLaunch: function () {let types = myPluginInterface.typesglobal['wj-types'] = types}})
3. 为了方便全局调用,可以将
types
存储到global
下。types 提供的数据如下:{Track, // Track类型封装,见 类型详解-TrackClip, // Clip类型封装,见 类型详解-ClipClipSection, // ClipSection 类型封装,详见 ClipSection 类DesignSize, // DesignSize 类型封装,详见 DesignSize 类TRACK_TYPES: {MEDIA: 'media',AUDIO: 'audio',EFFECT: 'effect',FILTER: 'filter',TEXT: 'text',MUSIC: 'music',STICKER: 'sticker',TEMPLATE: 'template'}CLIP_TYPES: {VIDEO: 'video',IMAGE: 'image',AUDIO: 'audio',MUSIC: 'music',EFFECT: 'effect',FILTER: 'filter',TEXT: 'text',STICKER: 'sticker',TRANSITION: 'transition',TEMPLATE: 'template'}TEXT_TYPES: {NORMAL: 'normal',BACKGROUND: 'background'}}
类型详解-Track
Track(轨道)是时间轴上所有声音、影像以及各种效果控制等元素的数据载体,每条轨道随着时间的推移而作出相应响应。
微剪提供的 Track 类型数据,针对某个特定的 Track 存储一组同类型、时间不重叠的 Clip。
类型枚举
微剪目前提供的轨道类型如下:
轨道类型 | 枚举值 | 备注 |
主轨道(视频/图片) | media | 视频和图片都存储在 media 类型的轨道中,一组 Track 数据中至少有一个 media 轨道,media 轨道中的媒体必须首尾相接 |
画中画(视频) | video | 插入视频实现画中画功能 |
画中画(图片) | image | 插入图片实现画中画功能 |
原声 | audio | 原声轨道,需要分离视频画面和原声的场景中可以使用原声轨道对音频进行管理 微剪提供的 wj-player 播放器提供自动分离原声轨道的功能 |
音乐 | music | 背景音乐轨道 |
文字 | text | 文字轨道 |
特效 | effect | 特效轨道,目前一组有效的视频信息只有一个特效轨道 |
滤镜 | filter | 滤镜 |
贴纸 | sticker | 贴纸 |
模板 | template | 模板 |
初始化
1. 初始化一个空轨道:
let myTrack = new global['wj-types'].Track({type: "media"})
说明
初始化时可不传
id
,Track类会自动随机一个id
。2. 自定义
id
初始化一个空轨道:let id = 'my-track'let myTrack = new global['wj-types'].Track({type: "media",id})
3. 使用轨道数据初始化一个轨道:
let trackJson = {id: 1,type: 'media',zindex: '1',clips: [{xxx: xxx}]}let myTrack = new global['wj-types'].Track(trackJson)
修改字段
let myTrack = new global['wj-types'].Track({type: "media"})myTrack.zindex = 99
注意
请不要随意修改 Track 的 type 字段,Track 的 type 和 Clip 的 type 不符时可能导致渲染失败。
toJSON
let json = myTrack.toJSON()
字段详解
class Track{id // 轨道id,唯一标识,一组数据中出现重复id可能导致渲染错误type // 轨道类型clips = [] // 轨道内存储的Clip数组zindex = 0 // 展示层级}
类型详解-Clip
Clip 是微剪播放的原子数据,可以进行编辑操作,包含可编辑 Clip 的所有信息,存储在 Track 的 clips 字段中。
类型枚举
目前支持的类型如下:
Clip 类型 | 枚举值 | 备注 |
视频 | video | video 和 image 类型的 Clip 合并存放在 media 类型的轨道中 |
图片 | image | 图片类型 |
音频 | audio | 音频类型 |
音乐 | music | 音乐类型 |
特效 | effect | 特效 |
文字 | text | 文字 |
滤镜 | filter | 滤镜 |
贴纸 | sticker | 贴纸 |
转场 | transition | 转场 |
模板 | template | 模板 |
初始化
1. 初始化一个 Clip:
let myClip = new global['wj-types'].Clip({type: 'video',info: {tempFilePath: 'wxfile:xxxx',width: '',height: '',duration: 5},section: new global['wj-types'].ClipSection({start: 1,end: 3}),startAt: 0})
说明
ClipSection
是用于标记Clip
播放区间的类。示例中的传参表示轮到该视频播放时从该视频的 1s 处开始播放,到 3s 结束(总共播放2s),然后播放下一个Clip
。2. 从 JSON 初始化(JSON 详细格式请参见 字段详解):
let json = {...}let myClip = new global['wj-types'].Clip(json)
修改字段
myClip.startAt = 3.5
toJSON
let json = myClip.toJSON()
字段详解
DesignSize 类
DesignSize
标记Clip
在播放器上显示的尺寸和位置。class DesignSize{width = 100height = 100xPercent // 播放器回传数值,等于x/视频宽度,用于适配不同导出分辨率yPercent // 播放器回传数值,等于x/视频宽度,用于适配不同导出分辨率anchor // 'left' | 'top' | 'left' | 'right' 锚点位置rotate // 旋转角度(单位弧度)scale // 缩放}
ClipSection 类
ClipSection
存储Clip
的播放区间数据。class ClipSection{startend}
Clip 类
class Clip{id, // Clip的id,Clip的唯一标识(不传则默认随机id)trackId, // 轨道id(非必传)key, // 素材key,特效、滤镜、贴纸均必传type, // 类型(必传)startAt, // Clip在时间轴上开始播放的时间点(必传)visible, // 是否显示(非必传)designSize, // 尺寸和位置,DesignSize实例(非必传)section, // 播放区间,ClipSection实例(必传)editable, // Boolean值,标记素材是否可在播放器中进行缩放、旋转等编辑selected, // Boolean值,传true可以屏蔽播放器的选择控制,强制选中某个展示元素info:{ // Clip原始信息(需要加载文件的类型必传)width: Number, // 原始宽度height: Number, // 原始高度duration: Number, // 原始时长tempFilePath: 'wxfile://xxxxxx', // 路径(视频、音频等需要加载的资源必传)},content:{// 文字内容,文字必传style: {type: 'normal | background', // 文字样式, 播放器目前仅内置两种,可以直接wj-textEditor进行文字输入color: String, // 文字颜色fontfamily: String, // v1.4.0新增字体支持fonturl: String, // v1.4.0新增字体支持fontloaded: Boolean, // v1.4.0新增,由于小程序loadFontFace的设计缺陷,使用此字段标记是否已经预加载字体,防止多次重复加载同个字体浪费流量// 1.8.0 新增文字特性alpha: Number, // 文字整体透明度backgroundColor: String, // 背景色backgroundColorAlpha: Number, // 背景透明度(0-1)template: String // 文字样式模板keyfontsize: Number, // 文字大小,默认36align: String, // 对齐方式dropShadowColor: String, // 文字阴影颜色dropShadowBlur: Number, // 文字阴影模糊dropShadowAngle: Numebr, // 文字阴影角度,单位为弧度dropShadowAlpha: Number, // 文字阴影透明度dropShadowDistance: Number, // 文字阴影距离stroke: String, // 文字描边颜色strokeThickness: Number, // 文字描边粗细fill: Array, // 文字渐变的色值数组fillGradientType: Number, // 文字渐变方向(0垂直,1水平)},position: { // 位置,v1.4.0开始废弃,统一使用designSize标记位置x: 0,y: 0},background: { // v2.1.0支持添加背景type: 'pure|image|blur',url: '' // type为image时必传,color: '0x112223' // type为pure时必传mode: 'fill | aspectFit | aspectFill' // 图片相对于width和height的适配模式,默认aspectFill},operations: [{// 动效类型key: "Blur", // key为效果的唯一标识type: "default", // 标记操作类型id: "my-motion-operation", // idparams: { // 参数}},{// 滤镜类型key: "baixi", // key为效果的唯一标识type: "filter", // 标记操作类型id: "my-filter-operation", // id},{// 蒙版类型, v2.1.0新增key: "mirror", // key为效果的唯一标识type: "mask", // 标记操作类型id: "my-mask-operation", // id}]}}
注意
Track 和 Clip 的结合使用
步骤1:创建一个轨道
let mediaTrack = new global['wj-types'].Track({type: "media" // 可以是支持的任何类型})
步骤2:向轨道加入 Clip
let exampleClip1 = new global['wj-types'].Clip({trackId: mediaTrack.id,type: 'video',info: {tempFilePath: 'wxfile://xxxx',width: '',height: '',duration: 5},section: new global['wj-types'].ClipSection({start: 0,end: 3}),startAt: 0})let exampleClip2 = new global['wj-types'].Clip({trackId: mediaTrack.id,type: 'video',info: {tempFilePath: 'wxfile://xxxx',width: '',height: '',duration: 5},section: new global['wj-types'].ClipSection({start: 2,end: 4}),startAt: 3})// 设置轨道的clips为exampleClip1和exampleClip2mediaTrack.clips = [exampleClip1, exampleClip2]
此时如果有一个需要播放的
exampleClip3
的startAt
为0,则exampleClip3
和exampleClip1
的播放时间必然出现重叠。上文提到同一个 Track 中的 Clip 时间是不允许出现重叠的,则此时需要创建一个新的轨道来存储它。let mediaTrack2 = new global['wj-types'].Track({type: "media"})exampleClip3.trackId = mediaTrack2.idmediaTrack.clips = [exampleClip3]