Upload/process Audio/Video files
Understanding Chunked Uploads
Before diving into the implementation, it's important to understand how file uploads work in Editframe. Files are uploaded in chunks (8MB pieces) rather than all at once. This approach offers several benefits:
- Reliability: If an upload fails, only the current chunk needs to be retried rather than the entire file
- Progress tracking: Chunked uploads allow for accurate progress reporting
- Infrastructure compatibility: Many cloud platforms and load balancers have request size limits that chunked uploads can work around
- Memory efficiency: Processing files in chunks requires less memory on both client and server
Upload Process Overview
The upload process consists of several steps. First, you create an unprocessed file record by sending metadata about your file (filename, size, md5) to Editframe. This returns a file ID and upload URLs. Then, you upload the actual file data in 8MB chunks, using the Content-Range header to specify which portion of the file each chunk represents. Finally, the file is processed to ensure proper metadata and codec compatibility.
Each chunk upload returns either a 202 status (chunk accepted, continue uploading) or 201 status (upload complete). This allows for precise progress tracking and graceful handling of network interruptions. If an upload is interrupted, you can resume from the last successfully uploaded chunk rather than starting over.
Supported File Types
Editframe accepts a wide variety of media formats for unprocessed files, including, but not limited to:
- Audio: MP3, WAV, AAC
- Video: MP4, MOV, AVI
Files encoded with widely supported codecs like H.264 (video) and AAC (audio) will process more quickly through the system. During processing, files are converted to ISOBMFF format (commonly known as MP4), which is an industry-standard container format that ensures broad compatibility and consistent behavior within our render pipeline.
Please reach out with any questions or concerns about how your file will be processed.
CLI
The editframe cli can be used to upload files for processing.
editframe process-file <path-to-file>
# editframe process-file path/to/file.mp4
API
Uploading and processing a file requires a few steps. The required operations are:
Create a client
Import required functions and set up your API client.
import {
Client,
createUnprocessedFileFromPath,
uploadUnprocessedFile,
processIsobmffFile,
getIsobmffProcessProgress,
getIsobmffProcessInfo
} from "@editframe/api/node";
const EF_TOKEN = "/* Load your API TOKEN */";
const client = new Client(EF_TOKEN);
Create an unprocessed file record
Sends necessary metadata to Editframe.
const filePath = "/* Path to file to process */";
const unprocessedFileRecord = await createUnprocessedFileFromPath(
client,
filePath,
);
Upload the file to Editframe
Uploads the file in 8MB chunks to Editframe.
const upload = await uploadUnprocessedFile(
client,
unprocessedFileRecord,
filePath
);
Track upload progress
Emits progress events as the file is uploaded.
for await (const event of upload) {
console.log(event);
// {
// type: "progress";
// progress: number; // Between 0 and 1
// }
}
// Alternatively, you can await a promise that resolves when the upload is complete
await upload.whenUploaded();
Initiate file processing
This will ensure the file has correct metadata and conformed to supported codecs.
For larger files using unsupported codecs, this will also transcode the file, which might take a while.
const processorRecord = await processIsobmffFile(client, unprocessedFile.id);
Track processing progress
Emits progress events as the file is processed.
const progress = await getIsobmffProcessProgress(client, processorRecord.id);
for await (const event of progress) {
console.log(event);
// Event will be either:
// { type: "progress"; data: { progress: number } }
// { type: "complete"; data: { } }
}
// Alternatively, as with uploads, you can await a promise that resolves when the processing is complete
await progress.whenComplete();
Retrieve the processed file information
Retrieves information about the processed file.
const info = await getIsobmffProcessInfo(client, processorRecord.id);
// Shape of info is:
// {
// id: string;
// created_at: string;
// completed_at: string | null;
// failed_at: string | null;
// isobmff_file_id: string | null; 👈 The ID of the processed file
// unprocessed_file_id: string;
// }