Core-SDK 
Core-SDK 是画布渲染部分的 SDK,传入工程数据(JSON)可以将数据绘制到 Canvas 上。可基于该 SDK 进行二次开发,开发视频相关的小程序,H5,PC视频编辑器等基于 web 的在线工具。
使用方法如下:
import { VideoCoreSDK } from "@h5/videoCoreSDK";
const vc = new VideoCoreSDK({
  data: MovieData, // 必填,工程数据
  movieId: "movieID", // 实例内部唯一标识,多个实例不能相同
  env: "preview", // 必填,渲染模式:editor(编辑模式,可拖动编辑); preview(预览模式,只能预览,内存消耗更小)
  registerId: "", // 必填,注册ID,和域名进行绑定的
  EModuleEffectSourcePath: '/assets/effectcanvas/', // 特效资源模块加载路径
  workerPath: "assets", // 选填,decode.worker.js的引用目录,默认是assets
  stopControl: true, // 停止使用控制器,默认是启用了控制器
  scale: 1, // 选填,画布缩放比例,默认是1
  currentTime: 0, // 选填,默认开始时间是0
  plugins: [], // 选填,扩展插件
});
const core = await vc.init();
/**
 * 假设工程数据是movieData,修改数据->更新视图
 */
// 1、获取工程数据中第一个元素
const [element] = movieData.elements;
// 2、修改第一个元素的坐标为[100, 200]
element.style.x = 100;
element.style.y = 200;
// 3、更新视图
core.update();可以通过new VideoCore(...)获取到vc实例,再通过vc.init()获取到core,core实例中包含了很多属性和方法,下面就挨个介绍这些属性和方法以及使用技巧。
属性说明 
下面只列出了实例core的属性,:后面的表示属性的数据类型,私有属性都是_开头的
.movieId: string 
实例的唯一标识,可以是一个随机字符串,默认是'movieId'
.workerPath: string 
worker 的地址,默认是/assets/worker/decode.worker.js,导出视频的时候需要使用这个 worker 去解码视频帧
.currentTime: number 
当前显示的时间
.times: [number, number] | null 
导出的时候可以传入 times 表示导出指定某一段时间的视频,单位是秒
.controlModeType: 'editElement' | 'editMask' 
控制器的模式,分为元素编辑模式和遮罩编辑模式,在遮罩编辑模式下只可以编辑遮罩
.bodyContainer: PIXI.Container 
body 容器,用于存放 PIXI 元素
.captionContainer: PIXI.Container 
字幕容器,用于存放字幕元素
.data: types.MovieData 
动画 JSON 数据
.events: events.EventsName 
事件名称的实例,事件可以通过触发事件名称进行调用
// 更新视图
pubsub.publish(core.events.UPDATE_STAGE);
// 事件名称和说明:
events.UPDATE_STAGE; // 更新视图
events.VISIBLE_CONTROL; // 控制器显示隐藏
events.STOP_GROUP_DRAG; // 禁用组的框选
events.SORT_CONTAINER; // 重新排序container
events.UPDATE_CONTROL_TARGET; // target尺寸变化后更新控制器
events.UPDATE_CONTROL_LIST; // 控制器更新list
events.TRIGGER_CONTROL; // 触发控制器选中元素
events.TRIGGER_CONTROL_NO_CALLBACK; // 只触发控制器,不调用onSelected回调
events.UPDATE_MOVIE; // 更新Movie.tsx
events.CONTROL_CHANGE_END; // 控制器结束
events.CONTROL_CHANGE_START; // 控制器开始.record: RecordObject 
历史记录方法集合,env 为 editor 才会有此参数
export interface RecordItem {
  desc: string; // 描述信息
}
export interface RecordObject {
  add: (item: RecordItem) => void; // 添加历史记录
  debounceAdd: (item: RecordItem) => void; // 使用防抖函数添加历史记录
  redo: () => void;
  undo: () => void;
  manager: RecordManager; // 历史记录的数据管理
}.resourceManage: ResourceManage 
资源管理器实例,请参考类:packages\video-core\src\react-pixi\manage\resourceManage.ts
.movieSize: { width: number; height: number } 
视频尺寸
.app: Application | undefined 
pixijs 实例
.playing: boolean 
是否在播放模式下,默认未在播放
.env: 'editor' | 'preview' | 'export' 
当前的运行环境,editor 表示编辑器模式下,preview 表示预览模式下,export 表示导出模式下
.groups: types.BaseElement[][] 
根据 trackIndex 对数据进行分组后的数据
.zIndexObjects: Record<string, number> 
记录元素的 zIndex 数据,方便控制器元素使用
.cacheControlElementIds: string[] 
控制器记录元素 ID 的数组
.usedMediaInfo: Record<string, types.UsedMediaItem> 
缓存全部的媒体资源视频&音频,用于合成音频使用
.elementReadyMark: Record<string, 'start' | 'success' | 'error'> 
记录图层准备成功,此处为了处理 react 中的异步问题,tring 可以是 elementId,或者其他参数
.renderAsyncMark: Record<string, 'start' | 'success' | 'error'>  
参考格式:{elementId_time: 'start' | 'success' | 'error'}
绘制的过程是异步的,用于检测是否绘制成功了,绘制之前把元素的 id 和时间放入对象中,绘制成功后时间是 null,如果都绘制完成了标 记应该是{},1 秒都还没绘制出来就不做处理了,所以为了确保性能问题,每个画面的绘制时间必须要控制在 1 秒内
.controlElements: ControlChangeValues[] 
记录控制器变化后的数据
export interface ControlChangeValues {
  elementId: string; // 目标元素到ID
  x: number;
  y: number;
  alpha?: number;
  width: number;
  height: number;
  rotation: number;
}方法说明 
get hideLockData(): number 
隐藏和锁定是针对整个轨道而言,返回锁定,隐藏显示元素记录,在计算 group 的时候就要设置该参数
return Record<number, { hide: boolean; lock: boolean }>;getPixiContainerById(ids: string[]): PIXI.Container[] 
通过 ids 获取 pixi container 对象
pixiContainerToImageById(id: string): Promise<HTMLImageElement> 
通过 id 找到 pixi 的 container,然后再导出成图片
initHideLock(hideLock: Record<number, { hide: boolean; lock: boolean }>) 
时间轴中的轨道的隐藏,锁定信息会记录到 movieData._hideLock ={} 中,需要对其进行初始化,_hideLock 中的 key 是 trackIndex
getHideLock(trackIndex: number): { hide: boolean;lock: boolean;} 
获取轨道的 hide,lock 参数
setHideLock(params: { trackIndex: number; hide?: boolean; lock?: boolean }, updateMovie?: boolean) 
设置指定轨道(trackIndex)的隐藏,锁定,第二个参数表示是否要更新 movie
changeControlMode(modeType: 'editElement' | 'editMask', id: string) 
切换编辑模式,分别是元素编辑 和 遮罩编辑。
getFrameItem(elementData: types.BaseElement): types.FrameItem | null 
获取当前帧数据,如果当前时间节点有数据将返回对应的帧数据(误差 0.1 秒)
asyncFrameAnimateStatus(elementData: types.BaseElement, status: types.FrameItem | null) 
将帧动画的数据和元素的状态进行同步,可以理解为通过帧数据更新元素的显示状态
getFrameStatusByCurrentTime(elementData: types.BaseElement, currentTime?: number): types.FrameItem | null 
获取指定时间位置的帧状态,如果第二个参数不传默认使用游标位置的时间
getFrameStatus(elementData: types.BaseElement, relativeTime: number | null): types.FrameItem | null 
获取指定时间位置的帧状态
removeTrackMedias(trackIndex: number, resourceId: string) 
移除媒体数据,删除元素的时候调用
checkSupportTransition(elementId: string): boolean 
判断元素后是否支持插入转场数据,只有相邻的两个视频,图片元素之间才可以插入转场
removeInvalidTransition() 
去掉无效的转场动画
play() 
播放视频
pause() 
暂停视频
sortZIndexNewData() 
保存的时候重置 zindex,返回新的数据,之所以会重置 zindex 参数是因为插入新轨道的时候下标可能出现小数,重置会重新更新为整数
step(time: number) 
设置视频时间
runAnimate() 
执行 play 操作,fps 默认是 32 帧,requestAnimationFrame 的频率可能会在 60fps,这里需要通过 FPS 来播放,之所以不使用 setTimeout 来操 作,是因为 setTimeout 会导致误差很大而且没法纠正时间
updateControl(type: 'updateTarget' | 'updateList' | 'trigger' | 'triggerNoCallback' | 'visible' | 'stopGroupDrag', doms?: HTMLElement[] | SVGElement[] | string[] | { visible: boolean; elementId: string } | boolean) 
更新控制器的方法
updateTarget: target 尺寸变化后更新控制器
updateList: targets 列表变化后更新控制器
trigger: 触发元素被选中
triggerNoCallback: 只触发控制器,不调用 onSelected 回调
visible: 显示隐藏控制器 { visible, elementId }
stopGroupDrag: 禁用&启用组的框选
// 触发控制器选中 elementId1
movie.updateControl("trigger", ["elementId1"]);updateSortTracks() 
轨道排序更新,需要重新调用此方法去更新 pixi 中 z-index 的问题
getTotalTime() 
获取视频的总时长
getElementDataByIds(ids: string[]) 
通过 ids 获取元素
getElementDataByTypes(types: types.ElementType[], data?: types.MovieData): types.BaseElement[] 
通过类型获取元素
getCloneData() 
获取 data 的 clone 数据,会重新计算 trackIndex,使其变成整数,从 1 开始
addResource(url: string, styleSize?: types.StyleSize): Promise<types.Resource> 
添加资源,资源会同步添加到 resourceManage 缓存起来
export interface StyleSize {
  width: number;
  height: number;
}addElementByResource(resource: types.Resource, params: { elementType: types.ElementType; time: number; trackIndex?: number; duration?: number }) 
通过资源数据添加元素
core.addElementByResource(resource, {
  elementType: "image", // 插入图片
  time: 10, // 从10秒开始
  trackIndex: 2, // 插入到第二个轨道
  duration: 5, // 持续显示5秒
});addElementNoSource( info: Record<string | 'attrs', any>, params: { elementType: types.ElementType; time: number; trackIndex?: number; duration?: number }) 
添加那种没有 resource 的资源的元素,比如:text, effect, cutScene 等
update(time?: number) 
更新 Movie 组件,比如修改了某个元素的_dirty 参数,可以调用此函数,修改了数据结构也可以调用此方法,export 环境中,使用 update 更新组件,因为在导出过程中,绘制是一个异步的过程,这里需要判断是否绘制成功
capture(): string 
截取当前视图的画面,返回 base64 图片
controlChangeStart(elementIds: string[]) 
控制器选中的时候会触发该方法,不需要单独调用
controlChangeEnd(elementIds: string[]) 
控制器结束的回调函数,不需要单独调用
destroy() 
销毁实例,内存回收
事件相关 
onControlChangeEnd: ((elementIds: string[]) => void) 
绑定控制器变化结束的事件
onControlChangeStart: ((elementIds: string[]) => void) 
绑定控制器开始的事件
onEachSourceProgress: (n: { src: string; p: number; total: number }) => void 
每个资源加载进度都会触发该事件
triggerCurrentTime: (t: number) => void 
触发 currentTime 变化的事件
triggerRecordSelectElements: (ids: string[]) => void 
触发元素选中
