IntermediateUpdated Jan 27, 2026
Creating AI-Powered Marketing Videos at Scale
Learn how to generate professional marketing videos using AI, from product showcases to social media ads, with templates and batch processing.
ML
Marcus Lee
Developer Advocate
15 min read
Introduction
Video content drives engagement, but creating it at scale is expensive. In this tutorial, you'll build a system that generates marketing videos automatically using AI.
What You'll Build- Template-based video generation system
- Multi-platform output (Instagram, TikTok, YouTube)
- Batch processing for campaigns
- Brand consistency controls
Video Generation Basics
Understanding Video Models
| Model | Best For | Duration | Speed |
|---|---|---|---|
| MiniMax Video-01 | General purpose | 5s | Fast |
| Kling Standard | Realistic scenes | 5s | Medium |
| Runway Gen-3 | Creative effects | 4s | Medium |
Basic Video Generation
javascript
// lib/video-generator.js
const ABSTRAKT_API_URL = 'https://api.abstrakt.one/v1';
export async function generateVideo(prompt, options = {}) {
const {
model = 'minimax-video-01',
duration = 5,
aspectRatio = '16:9'
} = options;
const response = await fetch(`${ABSTRAKT_API_URL}/models/${model}/run`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ABSTRAKT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
input: {
prompt,
duration,
aspect_ratio: aspectRatio,
},
}),
});
return response.json();
}Template System
Define Video Templates
javascript
// templates/marketing-templates.js
export const TEMPLATES = {
productShowcase: {
name: 'Product Showcase',
promptTemplate: `Professional product video of {product},
rotating slowly on {background} background,
soft studio lighting, premium feel,
smooth camera movement, {style} aesthetic`,
defaults: {
background: 'clean white',
style: 'minimalist',
},
aspectRatio: '1:1',
duration: 5,
},
lifestyleAd: {
name: 'Lifestyle Advertisement',
promptTemplate: `{product} in use in a {setting},
{demographic} person enjoying the product,
warm natural lighting, aspirational feel,
cinematic camera movement`,
defaults: {
setting: 'modern home',
demographic: 'young professional',
},
aspectRatio: '9:16',
duration: 5,
},
socialTeaser: {
name: 'Social Media Teaser',
promptTemplate: `Dynamic fast-paced video featuring {product},
bold colors, energetic transitions,
eye-catching movement, {mood} vibe,
social media style`,
defaults: {
mood: 'exciting',
},
aspectRatio: '9:16',
duration: 3,
},
beforeAfter: {
name: 'Before/After Transformation',
promptTemplate: `Split screen transformation video,
left side: {before_state},
right side: {after_state} with {product},
smooth transition between states`,
defaults: {},
aspectRatio: '16:9',
duration: 5,
},
};
export function buildPromptFromTemplate(templateId, variables) {
const template = TEMPLATES[templateId];
if (!template) throw new Error(`Unknown template: ${templateId}`);
let prompt = template.promptTemplate;
const allVariables = { ...template.defaults, ...variables };
for (const [key, value] of Object.entries(allVariables)) {
prompt = prompt.replace(new RegExp(`{${key}}`, 'g'), value);
}
return {
prompt,
aspectRatio: template.aspectRatio,
duration: template.duration,
};
}Multi-Platform Output
Platform Specifications
javascript
// lib/platforms.js
export const PLATFORMS = {
instagram: {
feed: { aspectRatio: '1:1', maxDuration: 60 },
stories: { aspectRatio: '9:16', maxDuration: 15 },
reels: { aspectRatio: '9:16', maxDuration: 90 },
},
tiktok: {
standard: { aspectRatio: '9:16', maxDuration: 60 },
},
youtube: {
standard: { aspectRatio: '16:9', maxDuration: null },
shorts: { aspectRatio: '9:16', maxDuration: 60 },
},
linkedin: {
feed: { aspectRatio: '1:1', maxDuration: 10 },
},
};
export function getSpecsForPlatform(platform, format) {
return PLATFORMS[platform]?.[format];
}Generate for Multiple Platforms
javascript
// lib/multi-platform.js
import { generateVideo } from './video-generator.js';
import { PLATFORMS } from './platforms.js';
export async function generateForAllPlatforms(prompt, platforms) {
const results = {};
for (const [platform, formats] of Object.entries(platforms)) {
results[platform] = {};
for (const format of formats) {
const specs = PLATFORMS[platform][format];
console.log(`Generating for ${platform}/${format}...`);
const result = await generateVideo(prompt, {
aspectRatio: specs.aspectRatio,
duration: Math.min(5, specs.maxDuration || 5),
});
results[platform][format] = result;
}
}
return results;
}
// Usage
const videos = await generateForAllPlatforms(
'Sleek smartphone floating and rotating, tech product showcase',
{
instagram: ['feed', 'reels'],
tiktok: ['standard'],
youtube: ['shorts'],
}
);Campaign Generator
Batch Campaign Creation
javascript
// lib/campaign-generator.js
import { buildPromptFromTemplate } from './templates/marketing-templates.js';
import { generateVideo } from './video-generator.js';
export class CampaignGenerator {
constructor(options = {}) {
this.concurrency = options.concurrency || 3;
this.results = [];
}
async generateCampaign(config) {
const { product, templates, variations } = config;
const jobs = [];
// Create all job configurations
for (const templateId of templates) {
for (const variation of variations) {
jobs.push({
templateId,
variables: { product, ...variation },
});
}
}
console.log(`Generating ${jobs.length} videos...`);
// Process in batches
for (let i = 0; i < jobs.length; i += this.concurrency) {
const batch = jobs.slice(i, i + this.concurrency);
const batchResults = await Promise.all(
batch.map(job => this.generateSingle(job))
);
this.results.push(...batchResults);
console.log(`Progress: ${Math.min(i + this.concurrency, jobs.length)}/${jobs.length}`);
}
return this.results;
}
async generateSingle(job) {
const { prompt, aspectRatio, duration } = buildPromptFromTemplate(
job.templateId,
job.variables
);
try {
const result = await generateVideo(prompt, { aspectRatio, duration });
return { success: true, job, result };
} catch (error) {
return { success: false, job, error: error.message };
}
}
}
// Usage
const generator = new CampaignGenerator({ concurrency: 3 });
const campaign = await generator.generateCampaign({
product: 'Premium Wireless Headphones',
templates: ['productShowcase', 'lifestyleAd', 'socialTeaser'],
variations: [
{ background: 'white', style: 'minimalist' },
{ background: 'gradient blue', style: 'tech' },
{ background: 'lifestyle setting', style: 'warm' },
],
});
console.log(`Generated ${campaign.filter(r => r.success).length} videos`);Brand Consistency
Brand Configuration
javascript
// lib/brand-config.js
export const BRAND_CONFIG = {
styleKeywords: ['premium', 'minimalist', 'sophisticated'],
colorPalette: ['navy blue', 'gold accents', 'white'],
lighting: 'soft, warm studio lighting',
mood: 'aspirational yet approachable',
avoidKeywords: ['cheap', 'discount', 'basic'],
};
export function applyBrandStyle(basePrompt) {
const { styleKeywords, lighting, mood } = BRAND_CONFIG;
return `${basePrompt},
${styleKeywords.join(', ')} style,
${lighting},
${mood} feel,
brand-consistent aesthetic`;
}Webhook Integration
Async Processing with Webhooks
javascript
// lib/async-generator.js
export async function queueVideoGeneration(prompt, options, webhookUrl) {
const response = await fetch('https://api.abstrakt.one/v1/jobs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.ABSTRAKT_API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: options.model || 'minimax-video-01',
input: {
prompt,
duration: options.duration || 5,
aspect_ratio: options.aspectRatio || '16:9',
},
webhook: webhookUrl,
}),
});
return response.json(); // Returns { jobId: '...' }
}
// Webhook handler
app.post('/webhooks/video-complete', async (req, res) => {
const { job_id, status, result } = req.body;
if (status === 'completed') {
// Save video URL to database
await saveVideoResult(job_id, result.video_url);
// Notify team
await notifySlack(`Video ready: ${result.video_url}`);
}
res.status(200).send('OK');
});Cost Management
Video Generation Costs
| Model | Credits | Typical Cost |
|---|---|---|
| MiniMax | 15/video | ~$0.15 |
| Kling | 20/video | ~$0.20 |
| Runway | 25/video | ~$0.25 |
Optimization Strategies
javascript
// Generate preview first, full quality on approval
async function generateWithApproval(prompt) {
// Quick preview with shorter duration
const preview = await generateVideo(prompt, {
model: 'minimax-video-01',
duration: 2,
});
// Queue for review
const approval = await queueForApproval(preview);
if (approval.approved) {
// Full quality generation
return generateVideo(prompt, {
model: 'kling-standard',
duration: 5,
});
}
return null;
}Complete Example
javascript
// generate-campaign.js
import 'dotenv/config';
import { CampaignGenerator } from './lib/campaign-generator.js';
import { applyBrandStyle } from './lib/brand-config.js';
async function main() {
const generator = new CampaignGenerator({ concurrency: 2 });
const campaign = await generator.generateCampaign({
product: 'Eco-Friendly Water Bottle',
templates: ['productShowcase', 'lifestyleAd'],
variations: [
{ setting: 'outdoor hiking trail', demographic: 'active adventurer' },
{ setting: 'modern office desk', demographic: 'professional' },
{ setting: 'yoga studio', demographic: 'wellness enthusiast' },
],
});
// Report
const successful = campaign.filter(r => r.success);
console.log(`\n=== Campaign Complete ===`);
console.log(`Total: ${campaign.length}`);
console.log(`Successful: ${successful.length}`);
console.log(`Failed: ${campaign.length - successful.length}`);
// Output URLs
successful.forEach(r => {
console.log(`- ${r.job.templateId}: ${r.result.result?.video_url}`);
});
}
main().catch(console.error);Next Steps
- Add audio/music integration
- Implement A/B testing framework
- Create approval workflow UI
- Build analytics dashboard
#video-generation#marketing#automation#social-media#ads