DEV Community

hexfloor
hexfloor

Posted on • Edited on

More storage for media : organize files using ChatGPT : part 3, converting MOV to HEVC MPEG-4

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
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Checking:

ffmpeg -codecs | grep hevc
Enter fullscreen mode Exit fullscreen mode

Image description
Great!
Clean up:

cd ..
rm -rf ffmpeg
Enter fullscreen mode Exit fullscreen mode

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
Enter fullscreen mode Exit fullscreen mode

Image description
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 !

Image description

ffmpeg -i input.mp4 -c:v libx265 -preset medium -crf 28 -vf "scale=1280:720" -b:v 1500k output.mp4

Enter fullscreen mode Exit fullscreen mode

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."

Enter fullscreen mode Exit fullscreen mode

Top comments (0)