Main article
Think to do backups and to fix metadata before processing, see in part 1
Introduction
You might wish to know more about MOV, MPEG-4 and HEVC. You may prompt ChatGPT
on my choice of the end format, there are pros and cons, get to know about VVC.
Setup
Given my past experience I will build ffmpeg from sources with HEVC
support.
sudo apt update
sudo apt install -y build-essential pkg-config git yasm libx264-dev libx265-dev libnuma-dev libfdk-aac-dev libmp3lame-dev libopus-dev libvpx-dev
sudo apt install nasm
git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg
cd ffmpeg
My favorite part:
./configure --enable-gpl --enable-libx264 --enable-libx265 --enable-libfdk-aac --enable-libmp3lame --enable-libopus --enable-libvpx --enable-nonfree
make
sudo make install
Checking:
ffmpeg -codecs | grep hevc
cd ..
rm -rf ffmpeg
convert MOV to MPEG-4 HEVC using ffmpeg
The setup is a complicated part, all the rest is trivial.
ffmpeg -i input.mov -c:v libx265 -crf 23 -preset medium -c:a aac -b:a 192k output.mp4
Feel free to use the settings that reflect your need.
Bonus
This should be a good start for you:
Hi ChatGPT, I wish to compress some old videos of mine into the mp4 hevc with normal quality, possibly with some loss, and my best wish would be to reduce the file size as much as we can, however preserving the quality, could you please suggest me the resolution and the bitrate in one line, and the ffmpeg command in the second line ? Short answer, thank you !
ffmpeg -i input.mp4 -c:v libx265 -preset medium -crf 28 -vf "scale=1280:720" -b:v 1500k output.mp4
Well, crf should be enough and it's better to encode audio as well, at any point you should remember about the metadata.
Industrial version:
#!/bin/bash
# Hardcoded input directory and output directory
INPUT_DIR="./input" # Input directory set to ./input
OUTPUT_DIR="./output" # Output directory for converted MP4s
# Create the output directory if it doesn't exist
mkdir -p "$OUTPUT_DIR"
# Iterate through all MP4 files in the input directory and subdirectories
find "$INPUT_DIR" -type f -iname "*.mp4" | while read -r mp4_file; do
# Get the base name of the MP4 file without the extension
base_name=$(basename "$mp4_file" .mp4)
# Get video dimensions (width and height) using ffprobe
dimensions=$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 "$mp4_file")
width=$(echo "$dimensions" | cut -d 'x' -f 1)
height=$(echo "$dimensions" | cut -d 'x' -f 2)
# Debugging: Log the dimensions
echo "Dimensions of $mp4_file: Width=$width, Height=$height"
# Initialize the new filename variable
new_filename="${OUTPUT_DIR}/${base_name}_converted.mp4"
# Check if rescaling is needed and apply the appropriate scale
if [[ "$height" -ge "$width" && "$height" -gt 1280 ]]; then
# If height >= width and height > 1280, rescale to -2:1280
scale="-2:1280"
echo "Rescaling $mp4_file to $scale"
elif [[ "$width" -gt "$height" && "$width" -gt 1280 ]]; then
# If width > height and width > 1280, rescale to 1280:-2
scale="1280:-2"
echo "Rescaling $mp4_file to $scale"
else
# No scaling needed
scale=""
echo "No rescaling needed for $mp4_file"
fi
# Run ffmpeg with or without scaling, based on the conditions
ffmpeg -i "$mp4_file" \
-r 30 -c:v libx265 -crf 28 -preset medium \
-c:a aac -b:a 192k \
-metadata creation_time="$formatted_date" \
${scale:+-vf "scale=$scale"} \
"$new_filename"
done
echo "Processing complete."
Top comments (0)