Prerequisites and Environment Setup
Before automating the conversion process, ensure that ffmpeg is installed on your Linux system. Most modern distributions provide it via package managers like apt or yum. Verify the installation by running ffmpeg -version in your terminal. You will also need a directory structure where source MKV files reside and a separate destination folder for the converted MP4 outputs. It is crucial to have sufficient disk space, as video files are large, and you must decide whether to keep the original MKV files or delete them after successful conversion.
Constructing the Conversion Script
The core of this solution involves a Bash script that iterates through each subdirectory containing MKV files. Instead of processing all files in one go, which can overwhelm system resources, handling them folder by folder allows for better error isolation and progress tracking. The script uses a for loop to find every .mkv file within a specified base directory.
#!/bin/bash
SOURCE_DIR="/path/to/source/videos"
DEST_DIR="/path/to/output/videos"
# Create destination directory if it doesn't exist
mkdir -p "$DEST_DIR"
# Iterate through each subdirectory in the source
find "$SOURCE_DIR" -type d | while read -r subdir; do
# Get the relative path from the source root
rel_path="${subdir#$SOURCE_DIR}"
# Create corresponding directory in destination
mkdir -p "$DEST_DIR$rel_path"
# Process only .mkv files in the current directory
find "$subdir" -maxdepth 1 -name "*.mkv" -type f | while read -r mkv_file; do
filename=$(basename "$mkv_file" .mkv)
mp4_file="$DEST_DIR$rel_path/${filename}.mp4"
# Skip if already converted
[ -f "$mp4_file" ] && continue
echo "Converting: $mkv_file"
ffmpeg -i "$mkv_file" -c:v libx264 -crf 23 -preset medium -c:a aac -b:a 192k "$mp4_file"
if [ $? -eq 0 ]; then
echo "Success: $mp4_file"
else
echo "Failed: $mkv_file"
fi
done
done
This script first establishes the source and destination paths. It then uses the find command to locate all directories within the source tree. For each directory, it calculates the relative path to recreate the exact folder structure in the destination. Inside each folder, it targets .mkv files specifically. The ffmpeg command encodes the video using the H.264 codec (libx264) with a Constant Rate Factor (CRF) of 23, which offers a good balance between quality and file size. The audio is re-encoded to AAC at 192kbps, ensuring broad device compatibility. If you prefer a lossless copy similar to Batch Converting MKV to MP4 with ffmpeg, you might use -c copy instead, but note that some MKV containers hold codecs incompatible with standard MP4 wrappers.
Understanding FFmpeg Parameters
Choosing the right parameters is vital for maintaining quality while reducing file size. The -c:v libx264 flag specifies the video encoder. The -crf 23 setting controls visual quality; lower values mean higher quality and larger files. A CRF of 18-28 is generally considered visually lossless to transparent. The -preset medium option balances encoding speed with compression efficiency. Faster presets like fast produce larger files, while slower ones like slow take longer but compress better.
For audio, -c:a aac selects the Advanced Audio Coding format, which is universally supported by MP4 containers. The -b:a 192k sets the bitrate. If your source audio is already AAC or another compatible format, you could use -c:a copy to avoid re-encoding, saving significant time. However, always verify that the original stream type is compatible with the MP4 container. Errors often arise when trying to force incompatible codecs into an MP4 wrapper, a common issue discussed in Troubleshooting FFmpeg: Why isn't 'ffmpeg -i input.mkv -c:copy output.mp4' working?.
Executing and Managing Output
Save the script as convert.sh and make it executable with chmod +x convert.sh. Run it from the terminal. Monitor the output for any "Failed" messages. If a conversion fails, check the specific error log provided by FFmpeg. Common issues include corrupted source files or missing codecs. Once the script completes, verify the integrity of a few sample files in the destination folder. If satisfied, you may choose to delete the original MKV files to save space, though keeping backups is recommended until you are confident in the conversion quality.
Frequently Asked Questions
How do I keep the original folder structure in the destination?
The script uses relative path calculation to mirror the source directory hierarchy exactly. By stripping the source root from each found path and appending it to the destination root, the same nested folders are created automatically.
Can I skip re-encoding the audio stream?
Yes, if your MKV files contain AAC or AC3 audio, you can change -c:a aac -b:a 192k to -c:a copy. This moves the audio stream directly without re-encoding, speeding up the process significantly.
What should I do if FFmpeg reports a codec error?
If you encounter errors related to unsupported codecs in the MP4 container, try changing the video codec to H.264 (-c:v libx264). Some MKV files use VP9 or HEVC, which may require specific handling or newer FFmpeg versions for MP4 export.
Is it safe to delete the original MKV files immediately?
No, it is safer to wait until you have manually verified several converted files. Video corruption can occur during complex conversions, so keeping originals ensures you don't lose data if a file is unreadable.
How can I improve conversion speed?
You can increase the -preset value to fast or veryfast. This reduces CPU usage and speeds up encoding at the cost of slightly larger file sizes. For very large libraries, consider using parallel processing tools alongside this script.