6月1日 23:56
How to use FFmpeg for batch processing and automation tasks?
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.