FFmpeg can achieve batch processing through scripts and tools, greatly improving work efficiency, suitable for processing large numbers of video files.
Basic Batch Processing
Batch Transcoding Using Shell Scripts
bash#!/bin/bash # Batch transcode MP4 files for file in *.mp4; do output="output_${file}" ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac -b:a 128k "$output" done # Batch convert formats for file in *.avi; do output="${file%.avi}.mp4" ffmpeg -i "$file" -c:v libx264 -crf 23 -c:a aac -b:a 128k "$output" done
Batch Processing Using find Command
bash# Recursively process all videos in directory find input_dir -name "*.mp4" -exec ffmpeg -i {} -c:v libx264 -crf 23 output_dir/{} \; # Batch extract audio find input_dir -name "*.mp4" -exec ffmpeg -i {} -vn -c:a copy output_dir/{/.}.aac \;
Parallel Processing
Using GNU Parallel
bash# Install GNU Parallel brew install parallel # macOS apt-get install parallel # Ubuntu/Debian # Process 4 files in parallel find input_dir -name "*.mp4" | parallel -j 4 ffmpeg -i {} -c:v libx264 -crf 23 output_dir/{/.}.mp4 # Show progress find input_dir -name "*.mp4" | parallel --bar -j 4 ffmpeg -i {} -c:v libx264 -crf 23 output_dir/{/.}.mp4
Parallel Processing Using xargs
bash# Process 4 files in parallel find input_dir -name "*.mp4" | xargs -P 4 -I {} ffmpeg -i {} -c:v libx264 -crf 23 output_dir/{/.}.mp4
Python Batch Processing
Using subprocess Module
pythonimport subprocess import os import glob # Batch transcode videos input_dir = "input" output_dir = "output" os.makedirs(output_dir, exist_ok=True) for input_file in glob.glob(f"{input_dir}/*.mp4"): filename = os.path.basename(input_file) output_file = os.path.join(output_dir, f"converted_{filename}") cmd = [ "ffmpeg", "-i", input_file, "-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-b:a", "128k", output_file ] subprocess.run(cmd, check=True) print(f"Processed: {filename}")
Parallel Processing Using multiprocessing
pythonimport subprocess import os import glob from multiprocessing import Pool def process_video(input_file): output_dir = "output" filename = os.path.basename(input_file) output_file = os.path.join(output_dir, f"converted_{filename}") cmd = [ "ffmpeg", "-i", input_file, "-c:v", "libx264", "-crf", "23", "-c:a", "aac", "-b:a", "128k", output_file ] subprocess.run(cmd, check=True) return filename # Parallel processing input_files = glob.glob("input/*.mp4") with Pool(processes=4) as pool: results = pool.map(process_video, input_files) for result in results: print(f"Processed: {result}")
PowerShell Batch Processing
Windows PowerShell Script
powershell# Batch transcode videos $inputDir = "input" $outputDir = "output" New-Item -ItemType Directory -Force -Path $outputDir Get-ChildItem -Path $inputDir -Filter "*.mp4" | ForEach-Object { $inputFile = $_.FullName $outputFile = Join-Path $outputDir "converted_$($_.Name)" ffmpeg -i $inputFile -c:v libx264 -crf 23 -c:a aac -b:a 128k $outputFile Write-Host "Processed: $($_.Name)" }
Advanced Batch Processing
Adjust Parameters Based on File Size
bash#!/bin/bash for file in *.mp4; do size=$(stat -f%z "$file" 2>/dev/null || stat -c%s "$file") size_mb=$((size / 1024 / 1024)) if [ $size_mb -gt 100 ]; then # Large files use higher compression ffmpeg -i "$file" -c:v libx264 -crf 28 -preset slow "compressed_$file" else # Small files use default parameters ffmpeg -i "$file" -c:v libx264 -crf 23 -preset medium "compressed_$file" fi done
Adjust Parameters Based on Resolution
bash#!/bin/bash for file in *.mp4; do # Get video resolution resolution=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$file") if [[ $resolution == "1920x1080" ]]; then # 1080p video downscale to 720p ffmpeg -i "$file" -vf scale=1280:720 -c:v libx264 -crf 23 "720p_$file" elif [[ $resolution == "3840x2160" ]]; then # 4K video downscale to 1080p ffmpeg -i "$file" -vf scale=1920:1080 -c:v libx264 -crf 23 "1080p_$file" else # Other resolutions remain unchanged ffmpeg -i "$file" -c:v libx264 -crf 23 "compressed_$file" fi done
Batch Generate Thumbnails
bash#!/bin/bash for file in *.mp4; do filename="${file%.*}" # Capture thumbnail at 10% ffmpeg -i "$file" -ss 00:00:05 -vframes 1 -vf scale=320:180 "${filename}_thumb.jpg" echo "Generated thumbnail for: $file" done
Error Handling and Logging
Batch Processing with Error Handling
bash#!/bin/bash log_file="processing.log" error_count=0 for file in *.mp4; do echo "Processing: $file" | tee -a "$log_file" if ffmpeg -i "$file" -c:v libx264 -crf 23 "output_$file" 2>> "$log_file"; then echo "Success: $file" | tee -a "$log_file" else echo "Error: $file" | tee -a "$log_file" ((error_count++)) fi done echo "Total errors: $error_count" | tee -a "$log_file"
Python with Error Handling
pythonimport subprocess import os import glob import logging logging.basicConfig(filename='processing.log', level=logging.INFO) def process_video(input_file): try: output_file = f"output_{os.path.basename(input_file)}" cmd = ["ffmpeg", "-i", input_file, "-c:v", "libx264", "-crf", "23", output_file] subprocess.run(cmd, check=True, capture_output=True) logging.info(f"Success: {input_file}") return True except subprocess.CalledProcessError as e: logging.error(f"Error: {input_file} - {e.stderr.decode()}") return False # Batch processing input_files = glob.glob("*.mp4") success_count = sum(process_video(f) for f in input_files) error_count = len(input_files) - success_count logging.info(f"Total: {len(input_files)}, Success: {success_count}, Errors: {error_count}")
Automated Tasks
Scheduled Tasks (Cron)
bash# Add to crontab # Execute batch processing at 2 AM every day 0 2 * * * /path/to/batch_process.sh >> /var/log/ffmpeg_batch.log 2>&1
Monitor Directory for Automatic Processing
pythonimport time import os from watchdog.observers import Observer from watchdog.events import FileSystemEventHandler class VideoHandler(FileSystemEventHandler): def on_created(self, event): if event.src_path.endswith('.mp4'): print(f"New video detected: {event.src_path}") process_video(event.src_path) def process_video(input_file): output_file = f"output_{os.path.basename(input_file)}" cmd = ["ffmpeg", "-i", input_file, "-c:v", "libx264", "-crf", "23", output_file] subprocess.run(cmd) if __name__ == "__main__": event_handler = VideoHandler() observer = Observer() observer.schedule(event_handler, path='input_dir', recursive=False) observer.start() try: while True: time.sleep(1) except KeyboardInterrupt: observer.stop() observer.join()
Batch Processing Best Practices
- Use parallel processing: Fully utilize multi-core CPUs to improve processing speed
- Add error handling: Log errors for troubleshooting
- Monitor resource usage: Avoid processing too many files simultaneously to prevent system resource exhaustion
- Test small batches: Test small batches before large-scale processing
- Use progress display: Understand processing progress to estimate completion time
- Backup original files: Backup important files before processing
Batch processing can significantly improve work efficiency, but pay attention to system resource management and error handling.