Skip to content

Core-SDK

Core-SDK 是画布渲染部分的 SDK,传入工程数据(JSON)可以将数据绘制到 Canvas 上。可基于该 SDK 进行二次开发,开发视频相关的小程序H5PC视频编辑器等基于 web 的在线工具。

使用方法如下:

js
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()获取到corecore实例中包含了很多属性方法,下面就挨个介绍这些属性和方法以及使用技巧。

属性说明

下面只列出了实例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

事件名称的实例,事件可以通过触发事件名称进行调用

ts
// 更新视图
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 才会有此参数

ts
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[]

记录控制器变化后的数据

ts
export interface ControlChangeValues {
  elementId: string; // 目标元素到ID
  x: number;
  y: number;
  alpha?: number;
  width: number;
  height: number;
  rotation: number;
}

方法说明

get hideLockData(): number

隐藏和锁定是针对整个轨道而言,返回锁定,隐藏显示元素记录,在计算 group 的时候就要设置该参数

ts
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: 禁用&启用组的框选

ts
// 触发控制器选中 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 缓存起来

ts
export interface StyleSize {
  width: number;
  height: number;
}

addElementByResource(resource: types.Resource, params: { elementType: types.ElementType; time: number; trackIndex?: number; duration?: number })

通过资源数据添加元素

ts
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

触发元素选中

Powered by 四川爱趣五科技有限公司.蜀ICP备18034069号.