API DocsExamples

Code Examples

Production-ready implementations for common media processing workflows. Each example includes proper error handling and follows best practices for the FFmpeg API.

Ready to Run

All examples are complete, tested implementations you can copy into your projects. Just add your API key and run!

Choose Your Use Case

🔄 Format Conversion

Convert between video/audio formats

GIF → MP4, MOV → WebM, WAV → MP3

📁 Batch Processing

Process multiple files efficiently

Thumbnails, compression, watermarks

🎥 Video Editing

Complex video manipulations

Overlays, transitions, multi-input

🔄 Live Workflows

Real-time processing pipelines

User uploads, webhook processing

Basic Examples

Simple, reusable functions for video processing:

import fs from 'fs'
import fetch from 'node-fetch'
 
// Upload a file to FFmpeg API
async function uploadFile(apiKey, filePath) {
  const response = await fetch('https://api.ffmpeg-api.com/file', {
    method: 'POST',
    headers: {
      'Authorization': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      file_name: filePath.split('/').pop()
    })
  })
 
  const { file, upload } = await response.json()
 
  // Upload file bytes
  const fileBuffer = fs.readFileSync(filePath)
  await fetch(upload.url, {
    method: 'PUT',
    body: fileBuffer
  })
 
  return file.file_path
}
 
// Process video with FFmpeg
async function processVideo(apiKey, inputFilePath, outputFileName, options = ['-crf', '23']) {
  const response = await fetch('https://api.ffmpeg-api.com/ffmpeg/process', {
    method: 'POST',
    headers: {
      'Authorization': apiKey,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      task: {
        inputs: [{ file_path: inputFilePath }],
        outputs: [{ file: outputFileName, options }]
      }
    })
  })
 
  const result = await response.json()
 
  if (!result.ok) {
    throw new Error(result.error)
  }
 
  return result
}
 
// Download processed file
async function downloadFile(downloadUrl, outputPath) {
  const response = await fetch(downloadUrl)
  const buffer = Buffer.from(await response.arrayBuffer())
  fs.writeFileSync(outputPath, buffer)
}
 
// Get stored file info (type and size)
async function getFileInfo(apiKey, dirId, fileName) {
  const response = await fetch(`https://api.ffmpeg-api.com/file/${dirId}/${fileName}`, {
    headers: { 'Authorization': apiKey }
  })
  const data = await response.json()
  if (!data.ok) throw new Error(data.error)
  return data.file_info // { file_path, file_type, file_size }
}
 
// Complete conversion workflow
async function convertVideo(apiKey, inputPath, outputPath, options = ['-crf', '23']) {
  try {
    // 1. Upload
    const filePath = await uploadFile(apiKey, inputPath)
 
    // 2. Process
    const result = await processVideo(apiKey, filePath, outputPath.split('/').pop(), options)
 
    // 3. Download
    await downloadFile(result.result[0].download_url, outputPath)
 
    console.log(`✅ Converted ${inputPath} → ${outputPath}`)
    console.log(`📊 Usage: ${result.usage.gb_sec} GB-seconds`)
 
    return result
  } catch (error) {
    console.error('❌ Conversion failed:', error.message)
    throw error
  }
}
 
// Usage examples
const apiKey = process.env.FFMPEG_API_KEY
 
// Convert GIF to MP4
await convertVideo(apiKey, './animation.gif', './output.mp4')
 
// Compress video
await convertVideo(apiKey, './large.mp4', './compressed.mp4', ['-crf', '28'])
 
// Extract audio
await convertVideo(apiKey, './video.mp4', './audio.mp3', ['-vn', '-acodec', 'mp3'])

Batch Processing

Process multiple files efficiently with built-in error handling:

import fs from 'fs/promises'
import path from 'path'
 
// Process multiple files in directory with batching
async function processDirectory(apiKey, inputDir, outputDir, options = {}) {
  const files = await fs.readdir(inputDir)
  const videoFiles = files.filter(f => /\.(mp4|mov|avi|gif)$/i.test(f))
 
  console.log(`📁 Processing ${videoFiles.length} files...`)
 
  // Process in batches of 3 to avoid rate limiting
  const batchSize = 3
  const results = []
 
  for (let i = 0; i < videoFiles.length; i += batchSize) {
    const batch = videoFiles.slice(i, i + batchSize)
 
    const batchPromises = batch.map(async (file) => {
      const inputPath = path.join(inputDir, file)
      const outputPath = path.join(outputDir, file.replace(/\.[^.]+$/, '.mp4'))
 
      try {
        return await convertVideo(apiKey, inputPath, outputPath,
          options.ffmpegOptions || ['-crf', '25'])
      } catch (error) {
        console.error(`Failed ${file}: ${error.message}`)
        return { error: error.message, file }
      }
    })
 
    const batchResults = await Promise.all(batchPromises)
    results.push(...batchResults)
 
    console.log(`✅ Batch ${Math.floor(i/batchSize) + 1} complete`)
  }
 
  return results
}
 
// Process files with different quality versions
async function processMultipleVersions(apiKey, inputPath, outputDir, versions) {
  const results = await Promise.all(
    versions.map(async (version) => {
      const outputPath = path.join(outputDir, `${path.parse(inputPath).name}_${version.name}.mp4`)
      try {
        return await convertVideo(apiKey, inputPath, outputPath, version.options)
      } catch (error) {
        return { error: error.message, version: version.name }
      }
    })
  )
  return results
}
 
// Usage
const apiKey = process.env.FFMPEG_API_KEY
 
// Batch process directory
const results = await processDirectory(apiKey, './input', './output')
console.log(`✅ Processed ${results.length} files`)
 
// Create multiple versions
const versions = [
  { name: 'hd', options: ['-vf', 'scale=1280:720', '-crf', '23'] },
  { name: 'sd', options: ['-vf', 'scale=854:480', '-crf', '25'] },
  { name: 'mobile', options: ['-vf', 'scale=640:360', '-crf', '28'] }
]
const versionResults = await processMultipleVersions(apiKey, './input.mp4', './output', versions)
console.log(`✅ Created ${versionResults.length} versions`)

Real-World Use Cases

Social Media Automation

Create content optimized for different platforms:

// Generate social media variants automatically
async function createSocialVariants(apiKey, inputPath) {
  const formats = {
    instagram_square: ['-vf', 'scale=1080:1080:force_original_aspect_ratio=increase,crop=1080:1080'],
    instagram_story: ['-vf', 'scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920'],
    youtube_short: ['-vf', 'scale=1080:1920', '-t', '60'],
    twitter: ['-vf', 'scale=1280:720', '-b:v', '1M']
  }
 
  const results = {}
  for (const [platform, options] of Object.entries(formats)) {
    try {
      const outputPath = `${inputPath.split('.')[0]}_${platform}.mp4`
      results[platform] = await convertVideo(apiKey, inputPath, outputPath, options)
      console.log(`✅ Created ${platform} version`)
    } catch (error) {
      console.error(`❌ Failed ${platform}:`, error.message)
      results[platform] = { error: error.message }
    }
  }
 
  return results
}
 
// Usage
const apiKey = process.env.FFMPEG_API_KEY
const results = await createSocialVariants(apiKey, './content.mp4')
console.log('Generated formats:', Object.keys(results))

E-Learning Content

Process educational videos with multiple outputs:

# Simple e-learning video processor
def process_lecture(api_key, video_path):
    """Create HD, SD, and audio-only versions"""
    formats = {
        'hd': ['-vf', 'scale=1280:720', '-crf', '23'],
        'sd': ['-vf', 'scale=854:480', '-crf', '25'],
        'audio': ['-vn', '-acodec', 'mp3', '-ab', '128k']
    }
 
    results = {}
    for format_name, options in formats.items():
        output_path = f"lecture_{format_name}.{'mp3' if format_name == 'audio' else 'mp4'}"
 
        try:
            result = convert_video(api_key, video_path, output_path, options)
            results[format_name] = result
            print(f"✅ Created {format_name} version")
        except Exception as e:
            print(f"❌ Failed {format_name}: {e}")
            results[format_name] = {'error': str(e)}
 
    return results
 
# Usage
api_key = os.environ['FFMPEG_API_KEY']
results = process_lecture(api_key, './lecture.mp4')
print(f"Generated {len(results)} versions")

Error Handling & Best Practices

⚠️

Production Tip: Always implement retry logic for transient failures, especially for upload URL expiration (403 errors).

Retry Logic for Uploads

async function uploadWithRetry(apiKey, filePath, maxRetries = 3) {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    try {
      return await uploadFile(apiKey, filePath)
    } catch (error) {
      if (error.message.includes('403') && attempt < maxRetries) {
        console.log(`Upload attempt ${attempt} failed, retrying...`)
        await new Promise(resolve => setTimeout(resolve, 1000))
        continue
      }
      throw error
    }
  }
}

Common Error Patterns

  • 403 Upload Error: Upload URL expired, retry upload registration
  • 422 Processing Error: Invalid FFmpeg options, check command syntax
  • 429 Rate Limit: Too many requests, implement backoff strategy
  • Network Timeouts: Large files, consider chunked uploads for 500MB+ files

Need more examples? Check out our Processing Guide for advanced FFmpeg operations, or see the API Reference for complete endpoint documentation.