008 Ritagliare la parte di un video visualizzata in una data area del video stesso

27 Agosto, 2022 (15:34) | ffmpeg, Fotografia digitale, Linux, Video | By: sargonsei

008 Ritagliare la parte di un video visualizzata in una data area del video stesso.
Per poter creare un video contenente ciò che appare in un’area rettangolare dello schermo larga 640 pixels ed alta 360 pixels il cui angolo superiore sinistro si discosta dall’angolo superiore sinistro dello schermo di 320 pixels in orizzontale, e 120 pixels in verticale, occorre far precedere il nome del file multimesiale di destinazione dall’opzione
-vf "crop=640:360:320:120"quindi l’istruzione completa, nella sua forma più semplice, diventa:ffmpeg -i videoIN.mp4 -vf "crop=640:360:320:120" vOUTcrop.mp4 # Ritaglia, da videoIN.mp4, un video largo 640 pixels ed alto 360 pixels di cui il pixel in alto a sinistra dista 320 pixels dal bordo sinistro e 120 pixels dal bordo superiore del video in ingresso; i parametri non specificati sono dedotti da FFmpeg in base all'estensione del video finaleAffinché l’istruzione venga eseguita senza intoppi, è essenziale che la larghezza del file multimediale iniziale, espressa in pixels, sia maggiore o uguale alla larghezza dell’area dello schermo ritagliato più lo scostamento orizzontale, e l’altezza del file multimediale iniziale, espressa in pixels, sia maggiore o uguale all’altezza dell’area dello schermo ritagliato più lo scostamento verticale; di conseguenza, l’opzione suddetta funziona solo se il video da modificare è largo non meno di (640+320)=960 pixels, ed alto non meno di (360+120)=480 pixels.

Il nome del video in ingresso e del video in uscita, possono essere contenuti in una variabile.
In tal caso, il comando suddetto diventa:
IN="videoIN.mp4"; OUT="vOUTcrop.mp4"; ffmpeg -i $IN -vf "crop=640:360:320:120" $OUT # Ritaglia, dal file multimediale in ingresso, un video largo 640 pixels ed alto 360 pixels di cui il pixel in alto a sinistra dista 320 pixels dal bordo sinistro e 120 pixels dal bordo superiore del video in ingresso; i parametri non specificati sono dedotti da FFmpeg in base all'estensione del video finale.

Per far sì che il file multimediale in uscita abbia il medesimo nome del file multimediale in ingresso più un prefisso o un suffisso, la riga di comando precedente diventa
IN='videoIN.mp4'; OUT='prefisso-'${IN::-4}'-suffisso'${IN:(-4)}; ffmpeg -i $IN -vf "crop=640:360:320:120" $OUT # Ritaglia, dal file multimediale in ingresso, un video largo 640 pixels ed alto 360 pixels di cui il pixel in alto a sinistra dista 320 pixels dal bordo sinistro e 120 pixels dal bordo superiore del video in ingresso; i parametri non specificati sono dedotti da FFmpeg in base all'estensione del video finale.

Volendo calcolare la larghezza del video in uscita in funzione della sua altezza, è possibile inserire le misure in pixels all’interno di apposite variabili; per esempio: nel caso in cui si desideri che la larghezza del ritaglio sia 3/2 della sua altezza, aprire un terminale nella cartella in cui si trova il file multimediale da elaborare ed impartire il comando
IN='video.mp4'; OUT=${IN::-4}'-crop'${IN:(-4)}; Y=$((360+120));X=$((Y*3/2)); XY="crop="$X":"$Y":300:100"; ffmpeg -i $IN -vf $XY -acodec copy $OUT # Ritaglia, dal file multimediale in ingresso, un video alto Y pixels e largo (Y*3/2) pixels, di cui il pixel in alto a sinistra dista 320 pixels dal bordo sinistro e 120 pixels dal bordo superiore del video in ingresso; i parametri non specificati sono dedotti da FFmpeg in base all'estensione del video finale.

Spieghiamo come fare eseguire le istruzioni ad un o script bash, cosa molto utile quando i files multimediali sono più di uno.
1) Assicurarsi che i files multimediali che si vuol elaborare siano tutti presenti nella cartella di lavoro.
2) Creare un file di testo chiamato lista.txt contenente unicamente i nomi dei files multimediali che si vuole elaborare, completi di estensione; i nomi devono essere messi uno per riga, senza lasciare righe vuote, e nell’ordine in cui si vuole che vengano elaborati.
3) Creare, nella cartella di lavoro, il file di testo [elaboraLista.txt] col contenuto seguente:

#!/bin/bash
# ./elaboraLista.txt # Comando da impartire per avviare lo script da terminale
echo "#!/bin/bash"  > ESEGUE.txt # Sostituisce il contenuto dello script ESEGUE.txt
while read IN; do
    OUT='elaborato-'${IN::-4}'-crop'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0))         # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2))         # Imposta la larghezza del file audiovisivo elaborato
    X1=300            # Imposta la distanza dal lato sinistro
    Y1=100            # Imposta la distanza dal lato superiore
    COMANDO='ffmpeg -i '$IN' -vf crop='$X':'$Y':'$X1':'$X2' -acodec copy '$OUT # Costruisce il comando
    echo $COMANDO  >> ESEGUE.txt     # Inserisce una nuova riga di comando nello script ESEGUE.txt
    # $COMANDO                         # ??? Questo comando, se eseguito, termina il ciclo while
done < lista.txt
chmod u+x ESEGUE.txt               # Rende eseguibile lo script ESEGUE.txt
./ESEGUE.txt                       # Esegue lo script ESEGUE.txt
rm ESEGUE.txt                      # Cancella lo script ESEGUE.txt

4) Rendere eseguibile il suddetto script [elaboraLista.txt]
5) Eseguire il suddetto script [elaboraLista.txt]

Il medesimo risultato può essere ottenuto con uno script che usa un ciclo for per elaborare dei files multimediali elencati all'interno dello script stesso, e senza creare ulteriori script intermedi; segue un esempio del testo dello script.

#!/bin/bash
# ./elaboraElenco.txt # Comando da impartire per avviare lo script da terminale
for IN in 20231005_224603.mp4 20231012_223758.mp4 20231019_230246.mp4 # Lista files multimediali da elaborare
do
    OUT='prefisso-'${IN::-4}'-suffisso'${IN:(-4)} # Imposta nome ed estensione del file audiovisivo elaborato
    Y=$((480+0))        # Imposta l'altezza del file audiovisivo elaborato
    X=$((Y*3/2))        # Imposta la larghezza del file audiovisivo elaborato
    X1=300            # Imposta la distanza dal lato sinistro
    Y1=100            # Imposta la distanza dal lato superiore
    COMANDO='ffmpeg -i '$IN' -vf crop='$X':'$Y':'$X1':'$X2' -acodec copy '$OUT # Costruisce il comando
    $COMANDO          # Impartisce il comando
done