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";
const API_BASE = "https://api.zapcap.ai";
const VIDEO_PATH = "/path/to/your/video.mp4";

export async function addCaptions(videoPath) {
try {
// 1. Get available templates
console.log("Fetching templates...");
const templatesResponse = await axios.get(`${API_BASE}/templates`, {
headers: { "x-api-key": API_KEY },
});
const templateId = templatesResponse.data[0].id;
console.log("Using template:", templateId);

// 2. 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);

// 3. Create task
console.log("Creating captioning task...");
const taskResponse = await axios.post(
`${API_BASE}/videos/${videoId}/task`,
{
templateId,
// Read about it here: https://platform.zapcap.ai/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);

// 4. 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));