Batch Video Format Conversion Using FFmpeg

Batch video format conversion is a common task in multimedia processing. When dealing with large numbers of video files, manual operations are inefficient and error-prone. As developers or media engineers, implementing automated conversion using FFmpeg is crucial for building efficient processing pipelines.

This article demonstrates how to perform batch video format conversion with FFmpeg, providing complete script examples for Windows and macOS/Linux to help you establish professional, reusable video processing workflows.

If you're new to FFmpeg basics, please first read FFmpeg Overview.

1. Quick Start: Single File Conversion Basics

Before batch processing, master FFmpeg's basic usage:

ffmpeg -i input_file [conversion_parameters] output_file

Example: Convert .avi to .mp4:

ffmpeg -i input.avi output.mp4

FFmpeg automatically selects appropriate video/audio codecs. Advanced parameters will be detailed later.

2. Batch Conversion Scripts

⚠️ filethings.net Warning Always backup original files before batch processing. While FFmpeg is stable, unexpected issues may occur. Test scripts with sample files first.

2.1 Windows Batch Script (.bat)

Create batch_convert.bat:

@echo off
setlocal enabledelayedexpansion
:: FFmpeg Batch Conversion Script - Windows
:: Usage: batch_convert.bat [directory] [input_format] [output_format]

set "video_dir=%~1"
set "input_ext=%~2"
set "output_ext=%~3"

if "%video_dir%"=="" set "video_dir=%cd%"
if "%input_ext%"=="" set "input_ext=avi"
if "%output_ext%"=="" set "output_ext=mp4"

echo 🚀 Starting batch conversion
echo 📁 Directory: %video_dir%
echo 📝 Formats: %input_ext% → %output_ext%
echo.

set "success_count=0"
set "fail_count=0"
set "total_count=0"

for %%i in ("%video_dir%\*.%input_ext%") do (
    set /a total_count+=1
)

if %total_count%==0 (
    echo ❌ No .%input_ext% files found
    pause
    exit /b 1
)

for %%i in ("%video_dir%\*.%input_ext%") do (
    echo 🔄 Processing: %%~nxi
    ffmpeg -hide_banner -loglevel error -i "%%i" -c:v libx264 -preset medium -crf 23 -c:a aac "%%~dpni.%output_ext%"
    if !ERRORLEVEL! EQU 0 (
        echo ✅ Success: %%~ni.%output_ext%
        set /a success_count+=1
    ) else (
        echo ❌ Failed: %%~nxi
        set /a fail_count+=1
    )
)

echo.
echo 📊 Conversion Results:
echo    ✅ Success: %success_count%
echo    ❌ Failed: %fail_count%
if %fail_count% GTR 0 (
    echo ⚠️  Check failed files
)
pause

2.2 macOS/Linux Shell Script (.sh)

Create batch_convert.sh:

#!/bin/bash
# FFmpeg Batch Conversion Script - macOS/Linux

set -euo pipefail

VIDEO_DIR="${1:-$(pwd)}"
INPUT_EXT="${2:-avi}"
OUTPUT_EXT="${3:-mp4}"

RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; BLUE='\033[0;34m'; NC='\033[0m'

echo -e "${BLUE}🚀 Starting batch conversion${NC}"
echo -e "📁 Directory: $VIDEO_DIR"
echo -e "📝 Formats: $INPUT_EXT$OUTPUT_EXT"
echo

if [ ! -d "$VIDEO_DIR" ]( ! -d "$VIDEO_DIR" ); then
    echo -e "${RED}❌ Directory not found: $VIDEO_DIR${NC}"
    exit 1
fi

mapfile -t FILES < <(find "$VIDEO_DIR" -name "*.${INPUT_EXT}" -type f)
TOTAL=${#FILES[@]}

if [ $TOTAL -eq 0 ]( $TOTAL -eq 0 ); then
    echo -e "${RED}❌ No .${INPUT_EXT} files found${NC}"
    exit 1
fi

SUCCESS=0; FAILED=0; SKIPPED=0

for FILE in "${FILES[@]}"; do
    OUTPUT="${FILE%.*}.${OUTPUT_EXT}"
    BASENAME=$(basename "$FILE")
    
    if [ -f "$OUTPUT" ]( -f "$OUTPUT" ); then
        echo -e "${YELLOW}⏭️  Skipping existing: $BASENAME${NC}"
        ((SKIPPED++))
        continue
    fi

    echo -e "${YELLOW}🔄 Processing: $BASENAME${NC}"
    if ffmpeg -hide_banner -loglevel error -i "$FILE" -c:v libx264 -preset medium -crf 23 -c:a aac "$OUTPUT"; then
        echo -e "${GREEN}   ✅ Success: $(basename "$OUTPUT")${NC}"
        ((SUCCESS++))
    else
        echo -e "${RED}   ❌ Failed: $BASENAME${NC}"
        ((FAILED++))
    fi
done

echo
echo -e "${BLUE}📊 Conversion Statistics${NC}"
echo -e "   ${GREEN}✅ Success: $SUCCESS${NC}"
echo -e "   ${RED}❌ Failed: $FAILED${NC}"
echo -e "   ${YELLOW}⏭️  Skipped: $SKIPPED${NC}"

[ $FAILED -gt 0 ]( $FAILED -gt 0 ) && echo -e "${RED}⚠️  Check failed files${NC}"
echo -e "${GREEN}🎉 All tasks completed${NC}"

3. Parameter Configuration & Quality Control

3.1 Video Quality & File Size

Use -crf for quality control (0-51, lower means better quality):

ScenarioExampleDescription
High-crf 18Near-lossless, large
Balanced-crf 23Default recommended
Low-crf 28Web optimization

3.2 Audio Settings Reference

ParameterFunction
-arSampling rate (Hz)
-b:aAudio bitrate (e.g. 128k)
# Standard configuration (CD quality)
ffmpeg -i input.avi -c:v libx264 -crf 23 -ar 44100 -b:a 128k output.mp4

4. Common Format Conversion Examples

SourceTargetCommand Example
MP4 → FLVffmpeg -i input.mp4 -c:v libx264 -crf 23 output.flv
MOV → MP4ffmpeg -i input.mov -c:v libx264 -c:a aac -crf 23 output.mp4
AVI → WebMffmpeg -i input.avi -c:v libvpx-vp9 -crf 30 -b:v 1M -c:a libopus output.webm

5. Automation Optimization

5.1 Performance Tips

5.2 Integration

6. Troubleshooting

IssueSolution
Slow conversionUse -preset fast
Audio sync issuesAdd -async 1
Invalid data foundAdd -fflags +genpts

7. Command Cheat Sheet

TaskCommand
AVI to MP4ffmpeg -i input.avi -c:v libx264 -c:a aac output.mp4
Check infoffprobe input.mp4
OverwriteAdd -y
Silent modeAdd -hide_banner -loglevel error

8. Conclusion: Build Your Pipeline

Mastering FFmpeg batch processing eliminates video conversion hassles. Whether personal media management or enterprise-grade systems, these tools provide reliable foundations for scalable workflows.