Estrutura JSON e regras de campos

1. Estrutura de nível superior

A forma JSON completa no nível superior é:

{
  "meta": {},
  "assets": {},
  "tracks": []
}

Regras:

  • meta é obrigatório
  • tracks é obrigatório e deve conter pelo menos um track
  • assets é opcional

Não suportado:

  • video legado no nível superior
  • audio legado no nível superior

2. meta

interface Meta {
  version: string;
  title?: string;
  description?: string;
  author?: string;
  createdAt?: string;
  tags?: string[];
  width: number;
  height: number;
  fps: number;
  background?: string | "transparent" | Gradient;
}

version

  • Tipo: string
  • Obrigatório: sim
  • Finalidade: marcador de versão do esquema
  • Valor recomendado: "2.0.0"

title

  • Tipo: string
  • Obrigatório: não
  • Finalidade: metadados do título do vídeo

description

  • Tipo: string
  • Obrigatório: não
  • Finalidade: metadados de descrição do vídeo

author

  • Tipo: string
  • Obrigatório: não
  • Finalidade: metadados de autor

createdAt

  • Tipo: string
  • Obrigatório: não
  • Finalidade: metadados de data de criação

tags

  • Tipo: string[]
  • Obrigatório: não
  • Finalidade: metadados de marcação

width

  • Tipo: number
  • Obrigatório: sim
  • Restrição: inteiro positivo
  • Finalidade: largura do canvas

height

  • Tipo: number
  • Obrigatório: sim
  • Restrição: inteiro positivo
  • Finalidade: altura do canvas

fps

  • Tipo: number
  • Obrigatório: sim
  • Restrição: inteiro positivo
  • Finalidade: taxa de quadros

background

  • Tipo: string | "transparent" | Gradient
  • Obrigatório: não
  • Padrão: "#000000"
  • Finalidade: fundo global

Forma de Gradient:

interface Gradient {
  type: "linear" | "radial" | "conic";
  angle?: number;
  stops: Array<{
    offset: number;
    color: string;
  }>;
}

3. assets

interface Assets {
  fonts?: FontAsset[];
  images?: ImageAsset[];
  videos?: VideoAsset[];
  audios?: AudioAsset[];
  subtitles?: SubtitleAsset[];
}

fonts

interface FontAsset {
  id: string;
  src: string;
  family: string;
}

Status atual em runtime:

  • Pode aparecer no JSON
  • O runtime não baixa nem registra fontes automaticamente
  • Não trate isso como um sistema completo de carregamento de fontes

images

interface ImageAsset {
  id: string;
  src: string;
}

videos

interface VideoAsset {
  id: string;
  src: string;
}

audios

interface AudioAsset {
  id: string;
  src: string;
}

subtitles

interface SubtitleAsset {
  id: string;
  words: SubtitleWord[];
}

Uso de $ref

Pools de recursos que suportam $ref:

  • images
  • videos
  • audios
  • subtitles

Exemplo:

{
  "src": { "$ref": "video-hero" }
}

Ou:

{
  "words": { "$ref": "subtitle-main" }
}

4. tracks

interface Track {
  id?: string;
  clips: Clip[];
}

id

  • Tipo: string
  • Obrigatório: não
  • Finalidade: identificador do track

clips

  • Tipo: Clip[]
  • Obrigatório: sim
  • Restrição: pelo menos um clip

5. Forma compartilhada de Clip

interface BaseClip {
  id?: string;
  type: ClipType;
  start: number;
  duration: number;
  transform?: Transform;
  zIndex?: number;
  opacity?: number;
  style?: Style;
  animations?: Animation[];
  keyframes?: Keyframe[];
  transition?: Transition;
}

Campos centrais compartilhados:

id

  • Tipo: string
  • Obrigatório: não
  • Finalidade: identificador do clip

type

  • Tipo: ClipType
  • Obrigatório: sim

Atualmente suportado:

  • video
  • image
  • text
  • rect
  • circle
  • polygon
  • audio
  • subtitle
  • layout
  • template

start

  • Tipo: number
  • Obrigatório: sim
  • Unidade: segundos
  • Finalidade: tempo de início do clip

duration

  • Tipo: number
  • Obrigatório: sim
  • Unidade: segundos
  • Finalidade: duração do clip

transform

  • Tipo: Transform
  • Obrigatório: não

zIndex

  • Tipo: number
  • Obrigatório: não
  • Padrão: 0

opacity

  • Tipo: number
  • Obrigatório: não
  • Padrão: 1
  • Finalidade: atalho de opacidade para elementos visíveis
  • Regra de compatibilidade: style.opacity tem prioridade maior que opacity no nível superior

style

  • Tipo: Style
  • Obrigatório: não

animations

  • Tipo: Animation[]
  • Obrigatório: não

keyframes

  • Tipo: Keyframe[]
  • Obrigatório: não

transition

  • Tipo: Transition
  • Obrigatório: não

6. Regras de coordenadas e porcentagens

Coordenadas percentuais são baseadas no sistema de coordenadas centralizado do Revideo, e não em uma origem no canto superior esquerdo ao estilo DOM.

Exemplos:

  • x: "50%" significa centralizado horizontalmente
  • y: "50%" significa centralizado verticalmente
  • x: "0%" significa totalmente à esquerda
  • x: "100%" significa totalmente à direita
  • y: "0%" significa topo
  • y: "100%" significa base

7. JSON mínimo válido

{
  "meta": {
    "version": "2.0.0",
    "width": 1920,
    "height": 1080,
    "fps": 30,
    "background": "#000000"
  },
  "tracks": [
    {
      "clips": [
        {
          "type": "text",
          "start": 0,
          "duration": 3,
          "text": "Hello, world",
          "transform": {
            "x": "50%",
            "y": "50%"
          },
          "style": {
            "fontSize": 72,
            "fill": "#ffffff",
            "textAlign": "center"
          }
        }
      ]
    }
  ]
}

8. Observação para integrações públicas

Para integrações externas, use o fluxo documentado em API e uso:

  • Envie seu esquema por POST /api/preview
  • Envie o JSON completo do esquema como corpo da requisição
  • A ausência de meta ou tracks no nível superior ainda deve ser tratada como entrada inválida
  • Um nome de campo incorreto dentro de um clip nem sempre causará falha no momento da requisição
  • Alguns erros só podem se tornar visíveis durante preview, reprodução ou renderização