Files

Upload video, image, and caption files for use in compositions and renders.

Files are uploaded in two steps: first register the file to get an ID, then stream the bytes using the SDK's chunked uploader.

Upload a file

Use the @editframe/api SDK to handle both steps:

import { createFile, uploadFile } from "@editframe/api";
import { createReadStream, statSync } from "node:fs";

const filePath = "clip.mp4";
const byteSize = statSync(filePath).size;

// Step 1: Register the file and get an ID
const file = await createFile(client, {
  filename: "clip.mp4",
  type: "video",
  byte_size: byteSize,
  mime_type: "video/mp4",
});

// Step 2: Stream the bytes with chunked upload
for await (const event of uploadFile(
  client,
  { id: file.id, byte_size: byteSize, type: file.type },
  createReadStream(filePath),
)) {
  if (event.type === "progress") {
    console.log(`Uploading: ${Math.round(event.progress * 100)}%`);
  }
}

console.log(file.id); // stable UUID — use this everywhere

Uploads are resumable. If the connection drops, re-running uploadFile with the same id resumes from where it left off.

Node.js shorthand

For simple cases, the upload helper does everything in one call:

import { upload } from "@editframe/api/node";

const { file, uploadIterator } = await upload(client, "clip.mp4");

for await (const event of uploadIterator) {
  if (event.type === "progress") {
    console.log(`Uploading: ${Math.round(event.progress * 100)}%`);
  }
}

This auto-detects the file type from the extension and handles chunked transfer automatically.

Wait for processing

Video files are transcoded after upload. Poll getFileDetail until status is "ready":

import { getFileDetail } from "@editframe/api";

async function waitForFile(client, id) {
  while (true) {
    const detail = await getFileDetail(client, id);

    if (detail.status === "ready") return detail;
    if (detail.status === "failed") throw new Error(`Processing failed: ${id}`);

    await new Promise((r) => setTimeout(r, 1000));
  }
}

const ready = await waitForFile(client, file.id);

Image and caption files skip transcoding and are "ready" immediately after upload completes.

File status values

StatusDescription
createdFile registered, awaiting upload
uploadingUpload in progress
processingUpload complete, video being transcoded
readyFile available for use in compositions
failedProcessing failed

Using a file in a composition

Reference an uploaded file using its id with the file-id attribute:

<ef-configuration api-host="https://editframe.com">
  <ef-timegroup mode="contain" class="w-[1920px] h-[1080px]">
    <ef-video file-id="your-file-id"></ef-video>
  </ef-timegroup>
</ef-configuration>

The file-id is the UUID returned by createFile. It stays the same throughout upload, processing, and playback.