Skip to content

工程数据

什么是工程数据?

视频在编辑过程中,会有一个JSON数据用于记录当前编辑的视频的所有信息。这个JSON数据就是所谓的工程数据。每次创建新的视频都会创建一个新的工程数据。

为了方便大家开发和阅读,我们使用JSON来记录工程数据。

工程数据说明

使用Typescript语法来表述数据结构

1、工程数据 MovieData
ts
/**
 * 工程数据
 */
interface MovieData {
  title: string; // 名称
  version: string; // 数据版本
  ratio?: string; // 16:9
  createTime: number; // 创建时间(时间戳)
  updateTime: number; // 更新时间(时间戳)
  poster: string; // 封面图片
  width: number; // 原始尺寸
  height: number;
  background: Background; // 背景
  transitions: TransitionItem[]; // 转场动画
  captions: CaptionElement[]; // 字幕
  elements: BaseElement[]; // 元素:图片、文本、特效、贴纸、视频、音频元素
  resouces: Resource[]; // 资源文件
  // 记录编辑器中的配置
  _hideLock?: Record<number, { hide: boolean; lock: boolean }>;
}
2、背景 Background
ts
interface Background {
  disable?: boolean; // 启用禁用
  color?: string; // 背景色
  cropper?: {
    // 是否裁剪背景图片
    width: number;
    height: number;
    x: number;
    y: number;
    rotation?: number; // 旋转角度
  };
  resourceId?: string; // 背景图片的素材ID,和MovieData.resources中的素材ID对应
  backgroundRepeat?: "no-repeat" | "repeat-x" | "repeat-y" | "repeat"; // 背景图平铺方式
  backgroundSize?: "auto" | "contain" | "cover"; // 默认是'auto'
}
3、转场动画 TransitionItem

转场动画只能在两个相邻的图片,视频元素之间

ts
interface TransitionItem {
  id: string; // 唯一标识
  _dirty: string; // 用于控制元素内部更新,如果变化了,会触发组件更新
  _lock?: boolean; // 用户操作的锁定
  _hidden?: boolean; // 用户操作的元素是否可见
  name: string; // 图层名称
  duration: number; // 持续时间,实际时间 = duration * speed;
  startElementId: string; // 开始执行动画的元素ID
  transitionName?: string; // 动画名称,如果存在就使用系统预设
  glslCoding?: string; // glsl动画代码
  paramsTypes?: Record<string, any>;
  defaultParams?: Record<string, any>;
  extend?: any; // 扩展字段
}
4、元素基础类 BaseElement

其他元素类都继承 BaseElement,其他元素类目前有:CaptionElement,TextElement,ImageElement,StickerElement,FilterElement,EffectElement,VideoElement,GroupElement,MaskElement,AudioElement,LottieElement。

ts
// 下划线参数只在编辑的时候有用
interface BaseElement {
  id: string; // 唯一标识
  _dirty: string; // 用于控制元素内部更新,如果变化了,会触发组件更新
  _animationDirty?: string; // 用于重置动画的
  _frameDirty?: string; // 用于帧动画重置
  _noControl?: boolean; // 无控制器
  _filtersDirty?: string; // 用于触发filters更新的
  _ratio?: number; // 记录宽高比,编辑器中用到的参数
  scale?: number; // 缩放比例,默认是1
  templateEnable?: boolean; // 模版模式下可修改(替换)的元素
  filters?: {
    name: string; // 滤镜类名
    enabled: boolean;
    params: Record<string, any>; // 自定义参数
  }[]; // 滤镜 不显示的元素是没有filters的
  frames?: FrameItem[]; // 帧动画参数
  controlUnKeepRatio?: boolean; // 控制器不保持等比缩放
  name: string; // 图层名称
  duration: number; // 持续时间,实际时间 = duration * speed;
  startTime: number; // 开始播放时间
  type: string; // 类型
  trackIndex: number; // 层级,可以是小数 比如 trackIndex 如果需要在 0 和 1插入新的轨道,新的轨道trackIndex可以是 0.5,所以trackIndex不可以是0,如果trackIndex是-1表示主轨道
  extend?: any; // 扩展字段
}

// 帧动画
interface FrameItem {
  id: string;
  startTime: number;
  // 帧数据
  x?: number;
  y?: number;
  width?: number;
  height?: number;
  alpha?: number;
  rotation?: number;
  // 遮罩动画
  maskX?: number;
  maskY?: number;
  maskWidth?: number;
  maskHeight?: number;
  maskBlur?: number;
  maskRotation?: number;
  maskAlpha?: number;
  // 强度参数
  intensity?: number;
  // 音量
  volume?: number;
  // 文字
  textScale?: number;
  textColor?: string | string[];
  textBgColor?: string;
  textBorderColor?: string;
  textGradientStops?: number[];
}

0// 元素样式
interface ElementStyle {
  width?: number;
  height?: number;
  rotation?: number;
  alpha: number;
  x: number;
  y: number;
}

// 滤镜参数
interface Filter {
  name: string; // 滤镜类名
  enabled: boolean;
  params: Record<string, any>; // 自定义参数
}

// 2D帧动画
interface AnimationFrame {
  id: string; // 唯一表示
  progress: number; // 进度
  transform: Transform; // transform变化
  alpha?: number; // 透明度变化
  width?: number; // 宽
  height?: number; // 高
  _dirty: string; // 待定字段
}

// transform参数
interface Transform {
  translateX?: number;
  translateY?: number;
  rotation?: number;
  scaleX?: number;
  scaleY?: number;
  skewX?: number;
  skewY?: number;
}

// 动画元素
interface AnimationItem {
  id: string;
  oid: string; // 原始数据ID
  type: AnimationType;
  name: string;
  ename: string; // 英文
  start: number; // 动画开始时间
  duration: number; // 动画总时间
  frames: AnimationFrame[]; // 帧数据
  _dirty?: string;
}

/**
 * 动画类型
 * enter 表示进入动画
 * emphasize 表示强调动画,介于进入和离开之间的动画
 * leave 表示离开动画
 */
type AnimationType = "enter" | "emphasize" | "leave";

// 裁剪
interface CropSize {
  x: number;
  y: number;
  width: number;
  height: number;
}

// 元素蒙版本质上是一张黑色背景白色元素的图片
interface ElementMask extends ElementStyle {
  resourceId: string;
  name: string;
  blur: number; // 羽化半径
}
5、资源 Resource

资源数据存放在movieData.resouces数组中,元素数据使用资源的方式是使用id,比如图片数据中的数据是resourceId

ts
interface Resource {
  id: string;
  name: string; // 名称
  type: string; // 资源类型
  url: string; // 资源地址
  reverse?: boolean; // 是否倒放视频?
  originId?: string; // 原始资源文件的id
  thumb?: string; // 缩图
  wave?: string; // 音波json
  frames?: string; // 帧图
  noAudioTracks?: boolean; // 无音轨
  styleSize?: {
    width: number;
    height: number;
  }; // 尺寸,视频和图片都有尺寸
  fileSize?: number; // 文件大小
  mustFetch: boolean; // 渲染之前是否必须要fetch文件
  fileType: string; // 文件支持类型
  from: "user" | "system" | "other"; // 资源来源
  duration?: number; // 持续时间,视频和音频文件才有
  extend?: any; // 扩展字段
  attrs?: Record<string, any>; // 扩展字段
}
6、文字元素 TextElement

文字样式textStyle参考:https://pixijs.io/pixi-text-style/#

ts
interface TextElement extends BaseElement {
  textScale?: number; // 文字缩放大小
  text: string; // 字内容
  textStyle: Record<string, any>;
  textEnterAnimate?: AnimationItem; // 文字逐字动画
  style: ElementStyle;
  flipx: boolean; // 是否镜像翻转
  filters?: Filter[]; // 滤镜 滤镜元素是没有filters的
}
7、字幕元素 CaptionElement

字幕元素继承TextElement

ts
// 字幕
interface CaptionElement extends TextElement {
  id: string;
  type: "caption";
}
8、图片元素 ImageElement

图片支持的格式有png,jpg,jpeg,gif

ts
// 字幕
interface interface ImageElement extends BaseElement {
  resourceId: string;
  blendMode: PIXI.BLEND_MODES; // 混合模式
  style: ElementStyle;
  flipx: boolean; // 是否镜像翻转
  fps?: number; // gif图会有fps参数
  filters?: Array<Filter>; // 滤镜 滤镜元素是没有filters的
  animates?: AnimationItem[];
  isGif?: boolean;
  mask?: ElementMask; // 蒙版
  cropSize?: CropSize; // 裁剪
  matting: {
    // 抠像
    enabled: boolean; // 是否启用
    color: string; // 扣掉的颜色
    filterType: number; // 滤镜类型(0~6)默认是0
    lightLevel: number; // 修改明暗 默认:0.2 可选 0.1 - 0.7;
    gridSize: number; // 修改噪点数,默认是0.8  可选 0.2 - 1.5;
    emergence: number; // 羽化强度
  };
}
9、贴纸元素 StickerElement

sticker 贴纸 和 image 本质上没什么区别,预留了一个类型,方便后续进行业务扩展

ts
interface StickerElement extends ImageElement {}
10、滤镜元素 FilterElement

滤镜是叠加到整个画面的特殊效果,滤镜采用GLSL语法写的,滤镜效果参考:https://pixijs.io/filters/examples

ts
interface FilterElement extends BaseElement {
  resourceId: string; // 滤镜图片URL
  intensity: number; // 强度
}
11、特效元素 EffectElement

特效是滤镜的参数动态变化后的效果

ts
interface EffectElement extends BaseElement {
  effects: {
    id: string;
    name: string;
    frames: {
      id: string;
      progress: number;
      params: Record<string, any>;
    }[];
  }[];
}
12、视频元素 VideoElement

视频格式目前只支持mp4其他格式的视频上传到服务器会先进行转码,转码成mp4再导入到视频编辑器中进行编辑。

ts
interface VideoElement extends BaseElement {
  resourceId: string;
  volume: number;
  muted: boolean;
  speed: number; // 默认是1
  clipTime: number; // 截取开始时间,默认是0
  style: ElementStyle;
  blendMode: PIXI.BLEND_MODES; // 混合模式
  cropSize?: CropSize; // 裁剪
  matting: {
    // 抠像
    enabled: boolean; // 是否启用
    color?: string; // 扣掉的颜色
    filterType?: number; // 滤镜类型(0~6)默认是0
    lightLevel?: number; // 修改明暗 默认:0.2 可选 0.1 - 0.7;
    gridSize?: number; // 修改噪点数,默认是0.8  可选 0.2 - 1.5;
    emergence?: number; // 羽化强度
  };
  separate: 0 | 1; // 音视频分离,默认是0未分离,1表示分离
  fadeInTime: number; // 淡入n秒
  fadeOutTime: number; // 淡出n秒
  flipx: boolean; // 是否镜像翻转
  animates?: AnimationItem[];
  mask?: ElementMask; // 蒙版
}
13、组元素 GroupElement

预留的元素参数,方便后续扩展

ts
interface GroupElement extends BaseElement {
  style: ElementStyle;
  animates?: AnimationItem[];
  children: BaseElement[]; // 子元素
  flipx: boolean; // 是否镜像翻转
  mask?: ElementMask; // 蒙版
}
14、遮罩元素 MaskElement

遮罩元素主要在遮罩动画中有被使用

ts
interface MaskElement extends BaseElement {
  resourceId: string;
  style: ElementStyle;
  animates?: AnimationItem[];
  mask?: ElementMask; // 蒙版
}
15、音频元素 AudioElement

音频元素支持的格式AACmp3格式,其他格式需要在服务端进行转码后使用。

ts
interface AudioElement extends BaseElement {
  resourceId: string;
  volume: number; // 音量
  muted: boolean; // 是否静音
  speed: number; // 默认是1
  clipTime: number; // 截取开始时间,默认是0
  fadeInTime: number; // 淡入n秒
  fadeOutTime: number; // 淡出n秒
}
16、Lottie 动画元素 LottieElement

lottie动画可以参考网站:https://lottiefiles.com

后台管理系统可以上传lottie动画,支持格式.lottie

ts
interface LottieElement extends BaseElement {
  resourceId: string; // 资源id
  blendMode: PIXI.BLEND_MODES; // 混合模式
  style: ElementStyle;
  flipx: boolean; // 是否镜像翻转
  filters?: Array<Filter>; // 滤镜 滤镜元素是没有filters的
  animates?: AnimationItem[];
  mask?: ElementMask; // 蒙版
  cropSize?: CropSize; // 裁剪,相对于原始尺寸进行裁剪
  initStartFrame: number; // 初始化开始帧
  lottieSpeed: number; // 播放速度
  // replaceText:
}

工程数据示例

下面是一个完整的初始化工程数据示例

javascript
// 工程数据demo
const projectData = {
  title: "未命名", // 项目标题
  createTime: 0, // 创建时间
  updateTime: 0, // 更新时间
  poster: "", // 封面
  width: 1920, // 尺寸
  height: 1080,
  background: {
    color: "#677C8A", // 背景
  },
  transitions: [], // 转场
  captions: [], // 字幕内容信息,
  elements: [], // 元素数据
  resouces: [], // 资源文件数据,资源文件的ID会和元素数据的resourceId进行绑定
  _hideLock: {}, // 轨道的锁定,隐藏操作数据
};

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