Table des matières

Script Bash pour réduire des vidéos avec FFMPEG

Introduction

J'ai mis au point ce petit script que j'utilise pour réduire la taille de vidéos. Les options permettent de choisir :

C'est volontairement limité mais j'utilise ça tous les jours et ça me suffit. C'est probablement du code dégueulasse, mais je ne suis pas informaticien.

Ça ajoute -resized au nom du fichier original pour le fichier de sortie, qui n'est pas effacé.

Exemples d'utilisation

Convertir video.mp4

video_converter.sh video.mp4 resolution fps sound mp4 265 veryfast 35

Convertir video.mp4

video_converter.sh video.mp4 1280:720 30 nosound mkv 264 slow 20

Code

#!/bin/bash
 
if [ -z "$1" ]; then
    echo "--------------------------------"
    echo "| Video converter using FFMPEG |"
    echo "--------------------------------"
    echo "Usage:"
    echo "1st argument is filename"
    echo "2nd argument is desired resolution (format: '1280:720' or '-1:720' or '1280:-1'). To keep the original resolution, enter the word 'resolution'"
    echo "3rd argument is if you want to keep the current framerate (enter 'fps') or change it, in which case enter a numeric value"
    echo "4th argument is if to keep sound or remove it ('sound', 'nosound')"
    echo "5th argument is the container : 'mp4' or 'mkv'"
    echo "6th argument is codec ('264' or '265')"
    echo "7th argument is the preset : 'ultrafast', 'superfast', 'veryfast', 'faster', 'fast', 'medium', or 'slow'"
    echo "8th argument is crf value (51-0). Optional. If not set, will use the default value for the chosen codec: 23 for x.264 and 28 for x.265 - The lower the value, the better the quality."
    exit 1
  else
    filename=$1
fi
 
if [ -z "$2" ];	then
	echo "Please enter either the word 'resolution' to keep it as it is, or the desired resolution in the following format (1280:720 or -1:720 or 1280:-1)"
	exit 1
elif [ $2 == 'resolution' ]; then
	resolution=""
else
	resolution="-vf scale=$2"
fi
 
if [ -z "$3" ]; then
    echo "You must tell if you want to keep the current framerate or if you want to convert it ('fps' or an integer)"
    exit 1
  elif [ $3 == 'fps'  ]; then
    fps=""
  else
    fps="-r $3"
fi
 
if [ -z "$4" ]; then
    echo "You must tell if you want to keep or remove sound from the video with either the 'sound' or 'nosound' flag."
    exit 1
  elif [ $4 == 'nosound' ]; then
    remove_or_copy_sound="-an"
  elif [ $4 == 'sound'  ]; then
    remove_or_copy_sound="-c:a copy"
  else
    echo "Third argument is invalid."
    echo "You must tell if you want to keep or remove sound from the video with either the 'sound' or 'nosound' flag."
    exit 1
fi
 
if [ -z "$5" ]; then
    echo "You must specify the container, either 'mp4' or 'mkv'."
    exit 1
  elif [ $5 == 'mp4'  ]; then
    container=".mp4"
  elif [ $5 == 'mkv'  ]; then
    container=".mkv"
  else
    echo "Fifth argument is invalid."
    echo "You must specify the container, either 'mp4' or 'mkv'."
    exit 1
fi
 
 
if [ -z "$6" ]; then
    echo "You must supply the desired output codec ('264' or '265')"
    exit 1
  elif [ $6 == '264' ]; then
      codec='libx264'
      crf='23'
  elif [ $6 == '265' ]; then
      codec='libx265'
      crf='28'
  else
    echo "Sixth argument is invalid"
    echo "You must supply the desired output codec ('264' or '265')"
    exit 1
fi
 
case $7 in
		"ultrafast"|"superfast"|"veryfast"|"faster"|"fast"|"medium"|"slow")
		preset=$7
		;;
	*)
		echo "Seventh argument: you must supply the preset ('ultrafast', 'superfast', 'veryfast', 'faster', 'fast', 'medium', or 'slow')"
		exit 1
		;;
esac
 
 
if [ "$8" ]
  then
    crf=$8
fi
 
 
ffmpeg -i "$filename" $resolution $fps -c:v $codec -crf $crf -preset $preset $remove_or_copy_sound "${filename%.*}-resized${container}"

Bonus : convertir tous les fichiers d'un répertoire

Pour ligne de commande Linux et MacOS.

Utiliser une simple boucle for avec substitution de paramètre.

Exemple :

for i in *.mp4; do video_converter.sh "$i" resolution fps sound mp4 265 veryfast 35; done