File Management

Unlock FFmpeg’s full potential with proper file management. FFmpeg can process single files or work with multiple files using patterns (like creating videos from image sequences). Directories are essential for multi-file operations, enabling FFmpeg to reference and process collections of related files.

Why Directories Matter for FFmpeg

FFmpeg’s true power lies in its ability to work with file patterns and multiple inputs. Many advanced operations require directories:

Image Sequences

Create videos from frame001.jpg, frame002.jpg, etc. using patterns like frame%03d.jpg (Support for glob/image-sequence patterns like frame%03d.png is coming soon.)

Batch Processing

Apply the same transformations to multiple files at once, or combine several inputs into one output

Complex Workflows

Mix audio tracks, overlay multiple videos, or process related files together in a single operation

💡

Key insight: For single-file operations, directories are optional. For multi-file operations (sequences, batches, complex workflows), directories are essential.

Choose Your Workflow

🎬 Multi-File Processing

For image sequences, batch operations, and complex workflows

1
Create directory explicitly
2
Upload all related files
3
Use patterns like *.jpg or frame%03d.png (coming soon)
✓
Process collections with FFmpeg patterns

Examples: Video from 100 images, slideshow creation, audio mixing

⚡ Single-File Processing

For simple conversions and one-file operations

1
Register file (auto-creates directory)
2
Upload single file
3
Process immediately

Examples: MP4 to GIF, resize video, extract audio

Step 1: Create a Directory

For multi-file processing or organized workflows, create a directory first:

const response = await fetch("https://api.ffmpeg-api.com/directory", {
  method: "POST",
  headers: {
    Authorization: "Basic YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
})
 
const { directory } = await response.json()
console.log(`Created directory: ${directory.id}`)
// Output: Created directory: dir_abc123

Response:

{
  "ok": true,
  "directory": {
    "id": "dir_abc123",
    "ttl": 86400
  }
}
⏰

TTL (Time To Live): Directories auto-delete after 24 hours (86400 seconds) by default. All files inside are cleaned up automatically.

Step 2: Register Files & Get Upload URLs

With a specific directory:

const fileResponse = await fetch("https://api.ffmpeg-api.com/file", {
  method: "POST",
  headers: {
    Authorization: "Basic YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    file_name: "video.mp4",
    dir_id: "dir_abc123", // Use your directory ID
  }),
})

Without a directory (auto-create):

const fileResponse = await fetch("https://api.ffmpeg-api.com/file", {
  method: "POST",
  headers: {
    Authorization: "Basic YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    file_name: "video.mp4",
    // dir_id omitted - creates temporary directory
  }),
})

Response breakdown:

{
  "ok": true,
  "file": {
    "dir_id": "dir_abc123",
    "file_path": "dir_abc123/video.mp4",
    "file_name": "video.mp4",
    "added_on": "2024-01-01T00:00:00Z"
  },
  "upload": {
    "url": "https://presigned-upload-url...",
    "method": "PUT",
    "expiresInSeconds": 300,
    "headers": {
      "Content-Type": "video/mp4"
    }
  }
}

Response Fields Explained

file.file_path → Use this in processing requests

upload.url → Upload your file bytes to this URL

upload.headers → Use these exact headers when uploading (if present)

upload.expiresInSeconds

→ Upload URL expires in ~5 minutes

Step 3: Upload Your Files

Once you have the upload URL, send your file bytes directly to it:

// For Node.js with file system
const fs = require("fs")
const fileBuffer = fs.readFileSync("./video.mp4")
 
// Use the headers from the /file response (if provided)
const uploadHeaders = uploadData.headers || {}
 
await fetch(uploadUrl, {
  method: "PUT",
  body: fileBuffer,
  headers: uploadHeaders,
})
console.log("✅ Upload complete!")
 
// For browser with File input
const fileInput = document.getElementById("fileInput")
const file = fileInput.files[0]
 
await fetch(uploadUrl, {
  method: "PUT",
  body: file,
  headers: uploadData.headers || {},
})
⏰

Upload URLs expire in 5 minutes. If you get a 403 error, request a new upload URL from /file and try again.

📁

File Types & Limits: While any file type can be uploaded, only upload files relevant to your FFmpeg processing needs. Maximum file size is up to 5GB depending on your plan.

📋

Important: If the /file response includes a headers property, use only those headers when uploading. Do not add any additional headers beyond what’s provided.

Managing Your Files

List All Directories

See all your active directories:

const response = await fetch("https://api.ffmpeg-api.com/directory", {
  headers: { Authorization: "Basic YOUR_API_KEY" },
})
 
const { directories } = await response.json()
console.log("Your directories:", directories)

Response:

{
  "ok": true,
  "directories": [
    {
      "id": "dir_abc123",
      "ttl": 86400,
      "added_on": "2024-01-01T10:30:00Z"
    }
  ]
}

List Files in a Directory

See what files are stored in a specific directory:

const response = await fetch(
  "https://api.ffmpeg-api.com/directory/dir_abc123",
  {
    headers: { Authorization: "Basic YOUR_API_KEY" },
  }
)
 
const { files } = await response.json()
console.log("Files in directory:", files)

Response:

{
  "ok": true,
  "files": [
    {
      "file_name": "video.mp4",
      "added_on": "2024-01-01T10:35:00Z"
    },
    {
      "file_name": "audio.wav",
      "added_on": "2024-01-01T10:40:00Z"
    }
  ]
}

Get File Info (type, size)

Check the stored file’s MIME type and size for any file you’ve uploaded:

const response = await fetch(
  `https://api.ffmpeg-api.com/file/dir_abc123/video.mp4`,
  { headers: { Authorization: 'Basic YOUR_API_KEY' } }
)
const { file_info } = await response.json()
console.log(file_info.file_type, file_info.file_size)

Pro Tips & Best Practices

📁 Directory Organization

  • • One directory per project - Keep related files together
  • • Descriptive file names - Use clear, consistent naming
  • • Group by workflow - Inputs and outputs in same directory
  • • Clean as you go - Let TTL handle automatic cleanup

⚡ Performance Tips

  • • Upload immediately - Don’t delay after getting URL
  • • Reuse files - Same file, multiple processing tasks
  • • Batch uploads - Register multiple files at once
  • • Upload relevant files only - Only media files you’ll process
  • • Check file sizes - Max 5GB per file (plan dependent)

Multi-File FFmpeg Examples

Here are real-world scenarios where directories enable powerful FFmpeg operations:

Image Sequence to Video

Create smooth video from numbered image files:

# FFmpeg pattern for files: frame001.jpg, frame002.jpg, frame003.jpg...
ffmpeg -i frame%03d.jpg -c:v libx264 -pix_fmt yuv420p output.mp4

Setup with FFmpeg API:

  1. Create directory and upload: frame001.jpg, frame002.jpg, frame003.jpg…
  2. Process with input pattern: {"task":{"inputs": [{"file_path": "dir_123/frame%03d.jpg"}]}}
🛠️

Support for glob/image-sequence patterns like frame%03d.png is coming soon.

Batch Audio Processing

Apply the same transformation to multiple audio files:

# Process all WAV files in a directory
for file in *.wav; do
  ffmpeg -i "$file" -c:a libmp3lame "processed_$file.mp3"
done

Setup with FFmpeg API:

  1. Upload multiple WAV files to same directory
  2. Use wildcard processing: {"task":{"inputs": [{"file_path": "dir_123/*.wav"}]}}

Multi-Track Audio Mixing

Combine multiple audio sources:

# Mix background music with narration
ffmpeg -i music.mp3 -i narration.wav -filter_complex amix=inputs=2 final.mp3

Setup with FFmpeg API:

  1. Upload all audio files to same directory
  2. Reference multiple inputs: {"task":{"inputs": [{"file_path": "dir_123/music.mp3"}, {"file_path": "dir_123/narration.wav"}]}}
🎯

Pro tip: Directories aren’t just containers—they enable FFmpeg to use wildcards (*.jpg), patterns (frame%03d.png), and reference multiple related files efficiently.

Support for glob/image-sequence patterns is coming soon.

Common File Management Patterns

Single File Processing

For quick, one-off conversions:

// 1. Register file (auto-creates directory)
const { file, upload } = await registerFile("input.gif")
 
// 2. Upload immediately
await uploadFile(upload.url, "./input.gif")
 
// 3. Process right away
const result = await processFile(file.file_path, "output.mp4")

Batch File Processing

For multiple related files:

// 1. Create organized directory
const { directory } = await createDirectory()
 
// 2. Register all files
const files = await Promise.all([
  registerFile("video1.mp4", directory.id),
  registerFile("video2.mp4", directory.id),
  registerFile("audio.wav", directory.id),
])
 
// 3. Upload all files
for (const fileData of files) {
  const fileBuffer = fs.readFileSync(`./${fileData.file.file_name}`)
  await fetch(fileData.upload.url, {
    method: "PUT",
    body: fileBuffer,
  })
}
 
// 4. Process with multiple inputs
const processResponse = await fetch(
  "https://api.ffmpeg-api.com/ffmpeg/process",
  {
    method: "POST",
    headers: {
      Authorization: "Basic YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      task: {
        inputs: files.map((f) => ({ file_path: f.file.file_path })),
        outputs: [{ file: "combined_output.mp4" }],
      },
    }),
  }
)

Long-term Project Management

For ongoing projects with file reuse:

// Create project directory
const projectResponse = await fetch("https://api.ffmpeg-api.com/directory", {
  method: "POST",
  headers: {
    Authorization: "Basic YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({}),
})
const { directory } = await projectResponse.json()
console.log(`Project directory: ${directory.id}`)
 
// Upload source materials once (conceptual - implement upload logic for each file)
const sourceFiles = {
  footage: `${directory.id}/raw-footage.mp4`,
  music: `${directory.id}/background-music.mp3`,
  logo: `${directory.id}/logo.png`,
}
 
// Process multiple variations using same source files
const webVersion = await fetch("https://api.ffmpeg-api.com/ffmpeg/process", {
  method: "POST",
  headers: {
    Authorization: "Basic YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    task: {
      inputs: [{ file_path: sourceFiles.footage }],
      outputs: [
        {
          file: "web-version.mp4",
          options: ["-vf", "scale=1280:720", "-crf", "23"],
        },
      ],
    },
  }),
})
 
const mobileVersion = await fetch("https://api.ffmpeg-api.com/ffmpeg/process", {
  method: "POST",
  headers: {
    Authorization: "Basic YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    task: {
      inputs: [{ file_path: sourceFiles.footage }],
      outputs: [
        {
          file: "mobile-version.mp4",
          options: ["-vf", "scale=640:360", "-crf", "28"],
        },
      ],
    },
  }),
})

File Upload Troubleshooting

❌ Upload fails with 403 Forbidden

Upload URL has expired (5-minute limit). Solutions:

  • Get a fresh upload URL by calling /file again
  • Upload immediately after getting the URL
  • Don’t store upload URLs for later use
  • Implement retry logic with new URL generation

❌ “File name already exists” error

File names must be unique within a directory. Options:

  • Use different file names (add timestamps, versions, etc.)
  • Create separate directories for different versions
  • Check existing files with GET /directory/{id}

  • Use descriptive naming patterns: project-v1-final.mp4

❌ Large file upload times out

For large files, optimize your approach (max file size: 5GB depending on plan):

  • Compress files before uploading when possible
  • Use appropriate HTTP client timeout settings
  • Consider breaking large operations into smaller parts
  • Monitor network stability during uploads
  • Check your plan’s file size limits in the dashboard

Understanding Directories: The Key to FFmpeg’s Power

🔑 Key Takeaway

Directories aren’t just for organization—they’re the foundation that enables FFmpeg’s most powerful features:

🎬 Multi-File Magic

  • • Image sequences → videos
  • • Batch processing workflows
  • • Pattern-based file selection

🔧 FFmpeg Patterns

  • • *.jpg wildcards

  • • frame%03d.png sequences

  • • Multiple input references

What’s Next?

Need help with file organization? The patterns above work for most use cases, but every project is different. Check our Examples for more specific implementations.