Esistono diverse applicazioni su Linux per la conversione di file video: Handbrake, ad esempio, consente conversioni in diversi formati ed è altamente configurabile. Se però la macchina che è deputata alla conversione è una macchina headless, cioè senza ambiente grafico le cose si complicano un po’.
Ho scritto (grazie a Gemini) questo script bash ideato per lavorare su macchine Debian/Ubuntu oppure un piccolo ed economico RasperryPi
Punti di Forza dello Script: Automazione e Archiviazione Video
Questo strumento nasce per risolvere il caos tipico delle librerie video, automatizzando la conversione e la pulizia dei nomi dei file in un unico passaggio sicuro.
1. Opzioni di Transcodifica Versatili
Lo script offre tre profili di conversione predefiniti, ottimizzati per il miglior rapporto qualità/peso:
- 1080p HEVC (H.265): Massima qualità per sorgenti 4K.
- 720p HEVC (H.265): Il punto di equilibrio ideale per film e serie TV.
- 480p AVC (H.264): Massima compatibilità e risparmio estremo di spazio.
2. Pulizia Radicale della Nomenclatura
Elimina il disordine dai nomi dei file per una libreria esteticamente perfetta:
- Rimozione Parentesi: Cancella automaticamente
()e[]con tutto il loro contenuto. - Eliminazione Tag Ridondanti: Rileva e rimuove vecchi tag come
4K,1080p,x264,HEVC,10bito nomi dei gruppi di rilascio. - Standardizzazione: Restituisce un nome pulito, separato da punti, aggiungendo solo il nuovo tag tecnico (es.
Nome.Video.720p.x265.mkv).
3. Workflow Intelligente e Archiviazione Sicura
Non è solo un convertitore, ma un gestore di file:
- Metodo Archivio: Solo dopo una conversione riuscita, il file originale viene spostato nella cartella
original_sources. - Sicurezza dei Dati: Se FFmpeg rileva un errore, il file originale non viene toccato, evitando perdite di dati.
- Evita Duplicati: Grazie a
ffprobe, lo script analizza il file e salta automaticamente quelli che sono già alla risoluzione desiderata.
4. Ottimizzato per NAS e Condivisioni NFS
Progettato per funzionare senza errori su infrastrutture di rete:
- Gestione Latenza: Include comandi
syncesleepper prevenire i tipici errori di scrittura dei file system di rete. - Test di Scrittura: Verifica i permessi prima di iniziare, evitando di bloccare il processo a metà lavoro.
- Esecuzione Non-Interattiva: Il flag
-nostdinimpedisce allo script di bloccarsi in attesa di input accidentali dalla tastiera.
5. Potenza in Background con tmux
Supporta l’esecuzione tramite tmux (parametro -b):
- Puoi avviare la conversione, chiudere il terminale o disconnetterti dal server SSH; il lavoro continuerà senza interruzioni.
- È possibile riagganciarsi alla sessione in ogni momento per monitorare il progresso.
6. Minimo Impatto sulle Prestazioni
Grazie all’uso di nice -n 19, lo script utilizza solo la potenza della CPU non richiesta da altri processi. Questo permette di convertire intere librerie in sottofondo senza rallentare minimamente l’uso quotidiano del computer o del server.
Requisiti di Sistema e Installazione
Per utilizzare correttamente lo script, è necessario che sul sistema siano installati alcuni pacchetti. Ecco come procedere su sistemi basati su Debian/Ubuntu:
# Aggiorna i repository e installa le dipendenze
$ sudo apt update
$ sudo apt install ffmpeg tmux sed
Creazione del file
Andiamo a creare il file sul path /usr/local/bin/ in modo che sia “lanciabile” da qualsiasi location e da qualsiasi utente
$ sudo nano /usr/local/bin/converter.sh
Nel file andiamo a scrivere il contenuto dello script
#!/bin/bash
# --- CONFIGURATION ---
SESSION_NAME="ffmpeg_conv"
DIR_OUT="converted_files"
DIR_DONE="original_sources"
LOCKFILE="/tmp/ffmpeg_conversion.lock"
# --- HELP FUNCTION ---
show_help() {
echo "Usage: $0 [OPTIONS] [RESOLUTION]"
echo ""
echo "Mandatory arguments:"
echo " 1080 Convert to 1080p H.265 (HEVC)"
echo " 720 Convert to 720p H.265 (HEVC)"
echo " 480 Convert to 480p H.264 (AVC)"
echo ""
echo "Options:"
echo " -b Run in background (tmux)"
echo " -h Show this help message"
exit 0
}
# --- 1. ROBUST SOFTWARE CHECK ---
echo "Checking system requirements..."
for cmd in ffmpeg ffprobe tmux sed; do
if ! command -v $cmd &> /dev/null; then
echo "ERROR: Required software '$cmd' is NOT installed."
echo "Please install it (e.g., 'sudo apt install ffmpeg tmux') and try again."
exit 1
fi
done
# --- ARGUMENTS ---
if [ $# -eq 0 ]; then show_help; fi
MODE_BG=false
TARGET_RES=""
for arg in "$@"; do
case $arg in
-h|--help) show_help ;;
-b) MODE_BG=true ;;
1080) TARGET_RES="1080"; CODEC="libx265"; TAG="1080p.x265"; CRF=22 ;;
720) TARGET_RES="720"; CODEC="libx265"; TAG="720p.x265"; CRF=23 ;;
480) TARGET_RES="480"; CODEC="libx264"; TAG="480p.x264"; CRF=20 ;;
*) echo "Error: Invalid argument '$arg'"; show_help ;;
esac
done
if [ -z "$TARGET_RES" ]; then echo "Error: Resolution required."; exit 1; fi
# --- CONCURRENCY ---
if [ -f "$LOCKFILE" ]; then
PID=$(cat "$LOCKFILE")
ps -p "$PID" > /dev/null && { echo "Process already running."; exit 1; } || rm "$LOCKFILE"
fi
echo $$ > "$LOCKFILE"; trap 'rm -f "$LOCKFILE"' EXIT
# --- BACKGROUND MODE ---
if [ "$MODE_BG" = true ] && [ -z "$TMUX" ]; then
tmux has-session -t "$SESSION_NAME" 2>/dev/null || {
tmux new-session -d -s "$SESSION_NAME" "$0 $TARGET_RES"
exit 0
}
fi
# --- 2. NFS & DIRECTORY SETUP WITH WRITABILITY TEST ---
echo "Verifying NFS directories and permissions..."
DIR_CREATED=false
for dir in "$DIR_OUT" "$DIR_DONE"; do
if [ ! -d "$dir" ]; then
mkdir -p "$dir" || { echo "ERROR: Failed to create $dir. Check NFS mount permissions."; exit 1; }
chmod 775 "$dir"
DIR_CREATED=true
fi
# Writability test (Fixes the "Strange" NFS bug)
touch "$dir/.write_test" && rm "$dir/.write_test" || {
echo "ERROR: Directory $dir is not writable. NFS permission issue?"
exit 1
}
done
if [ "$DIR_CREATED" = true ]; then
echo "New folders detected. Syncing NFS cache..."
sync && sleep 15
fi
echo "Task started: ${TARGET_RES}p [$(date)]"
# --- MAIN LOOP ---
for f in *.mp4 *.avi *.mkv *.mov *.wmv; do
[ -e "$f" ] || continue
HEIGHT=$(ffprobe -v error -select_streams v:0 -show_entries stream=height -of csv=p=0 "$f")
if [ -z "$HEIGHT" ] || [ "$HEIGHT" -le "$TARGET_RES" ]; then
echo "Skipping '$f': Resolution $HEIGHT px is already <= ${TARGET_RES}p."
continue
fi
# --- NAME CLEANING ---
base_name="${f%.*}"
clean_name=$(echo "$base_name" | sed -E 's/\[[^]]*\]//g; s/\([^)]*\)//g')
clean_name=$(echo "$clean_name" | sed -E 's/\.(4k|2160p|1080p|1080P|720p|720P|576p|480p|480P|SD|x264|x265|h264|h265|HEVC|hevc|AVC|10bit|10BIT|HDR|WEB-DL|BluRay|BDRip|AAC|DTS|AC3)//gI')
clean_name=$(echo "$clean_name" | sed -E 's/[[:space:]\._-]+/./g; s/^\.+//; s/\.+$//')
[ -z "$clean_name" ] && clean_name="video_output"
OUT_FILE="$DIR_OUT/${clean_name}.${TAG}.mkv"
echo "-------------------------------------------------------"
echo "Processing: $f"
# FFmpeg Execution
nice -n 19 ffmpeg -y -nostdin -i "$f" \
-map 0 -c:v "$CODEC" -crf "$CRF" -preset medium \
-vf "scale=-2:${TARGET_RES}" -c:a copy -c:s copy \
"$OUT_FILE"
if [ $? -eq 0 ]; then
echo "SUCCESS: Moving source to $DIR_DONE"
mv "$f" "$DIR_DONE/"
else
echo "FAILURE: FFmpeg error for $f"
fi
done
echo "-------------------------------------------------------"
echo "All tasks finished successfully."
Salvato il file andiamo a dargli i permessi di esecuzione:
$ sudo chmod +x /usr/local/bin/converter.sh
Utilizzo
lo script si può lanciare in qualsiasi folder contente file video. lanciando il comando indicando sempre la risoluzione. (480, 720 o 1080).
$ convert.sh 480
N.B. Aggiungendo l’opzione -b lo script effettuerà la converisone in backup tramite tmux. Questa funzione è molto comoda perché vi consente di terminare la vostra sessione sulla macchina e tornare più tardi quando la conversione sarà terminata.

No responses yet