Skip to main content

Adding Captions to a Video

Choose your preferred language to add captions to videos using the ZapCap API

import axios, { isAxiosError } from "axios";
import { createReadStream, createWriteStream } from "fs";
import FormData from "form-data";

// Get this from https://platform.zapcap.ai/dashboard/api-key
const API_KEY = "YOUR_API_KEY";
// Get this from /templates endpoint or https://platform.zapcap.ai/dashboard/templates
const TEMPLATE_ID = "your_template_id";
const API_BASE = "https://api.zapcap.ai";
const VIDEO_PATH = "/path/to/your/video.mp4"

export async function addCaptions(videoPath) {
try {
// 1. Upload video
console.log("Uploading video...");
const form = new FormData();
form.append("file", createReadStream(videoPath));

const uploadResponse = await axios.post(`${API_BASE}/videos`, form, {
headers: {
"x-api-key": API_KEY,
},
});
const videoId = uploadResponse.data.id;
console.log("Video uploaded, Video ID:", videoId);

// 2. Create task
console.log("Creating captioning task...");
const taskResponse = await axios.post(
`${API_BASE}/videos/${videoId}/task`,
{
templateId: TEMPLATE_ID,
// Read about it here: https://platform.zapcap.ai/docs//docs/guides/tasks#-transcript-approval
autoApprove: true,
language: "en",
},
{
headers: {
"x-api-key": API_KEY,
"Content-Type": "application/json",
},
}
);
const taskId = taskResponse.data.taskId;
console.log("Task created, Task ID:", taskId);

// 3. Poll for completion
console.log("Processing video...");
let attempts = 0;
while (true) {
const statusResponse = await axios.get(
`${API_BASE}/videos/${videoId}/task/${taskId}`,
{
headers: { "x-api-key": API_KEY },
}
);

const { status, downloadUrl, error } = statusResponse.data;
console.log("Status:", status);

if (status === "completed") {
// Download the video
console.log("Downloading captioned video...");
const videoResponse = await axios.get(downloadUrl, {
responseType: "stream",
});

const outputPath = "./captioned_video.mp4";

await new Promise<void>((resolve, reject) => {
const writeStream = createWriteStream(outputPath);
videoResponse.data.pipe(writeStream);

writeStream.on("finish", () => {
console.log("Video saved to:", outputPath);
resolve();
});

writeStream.on("error", reject);
});

console.log("Video saved to:", outputPath);
break;
} else if (status === "failed") {
throw new Error(`Task failed: ${error}`);
}

const delay = 2000;
await new Promise((resolve) => setTimeout(resolve, delay));
attempts++;
}
} catch (error) {
if (isAxiosError(error)) {
console.log(error.response?.data);
}
console.error("Error:", error.message);
}
}

const main = async () => {
await addCaptions(VIDEO_PATH);
};
main().then(() => process.exit(0));