31 marzo 2021

Usare ffmpeg per tagliare e sfumare video in ambiente Linux

In questo articolo parleremo di come tagliare e sfumare un video.

Scarichiamo un video di Madonna

Per prima cosa scarichiamo un video di Madonna di esempio con youtube-dl
$ youtube-dl "https://www.youtube.com/watch?v=EDwb9jOVRtU”
[youtube] EDwb9jOVRtU: Downloading webpage
[youtube] EDwb9jOVRtU: Downloading player 38c5f870
[download] Destination: Madonna - Hung Up [Official HD Music Video]-EDwb9jOVRtU.f137.mp4
$

Tagliamo

Quindi diciamo che vogliamo tagliare il video con i soli primo 8 secondi.
Ma prima rinominiamo il file con qualcosa di più corto
$ mv Madonna\ -\ Hung\ Up\ \[Official\ HD\ Music\ Video\]-EDwb9jOVRtU.mp4 madonna.mp4

Poi tagliamo il video in modo da crearne uno che corrisponda ai primi 8 secondi
$ ffmpeg -i madonna.mp4 -t 00:00:08 -async 1 madonna_tagliato.mp4

Ora tagliamo gli ultimi 30 secondi, quindi da 00:05:00 in poi
$ ffmpeg -i madonna.mp4 -ss 00:05:00 -async 1 cut2.mp4

Possiamo anche tagliare un mezzo dal minuto 03:00 al minuto 04:00 così:
$ ffmpeg -i madonna.mp4 -ss 00:03:00 -t 00:01:00 -async 1 cut3.mp4

in pratica le opzioni -ss e -t indicano rispettivamente il timestamp di partenza e la sua durata. Quindi dal minuto 03 per 1 minuto.
È possibile indicare delle frazioni di secondi utilizzando il punto per indicare i millesimi di secondo. Per esempio in questo modo -t 21.750 per indicare una durata di 21 secondi e 750 millesimi di secondo.

Facciamo una funzione per bash

Possiamo crearci anche una semplice funzione da includere nel file .bash_funzioni. Per esempio:

ff_taglia(){
 if [[ $# < 4 ]]
 then
  echo
  echo "usage:"
  echo "ff_taglia input_file tempo_partenza durata output_file"
  echo
 else
  ffmpeg -i $1 -ss $2 -t $3 -async 1 $4
 fi
}

e quindi digitare semplicemente la nostra funzione con i soli argomenti:

$ ff_taglia madonna.mp4 00:01:00 00:00:08 test.mp4

Sfumiamo

Per sfurmare per prima cosa dobbiamo trovare la durata totale del video in questo modo:

$ ffprobe -select_streams v -show_streams madonna.mp4  | grep -i duration
duration_ts=4269568
duration=333.560000

Il secondo valore è quello che ci serve, quindi 333.560000

Sfumatura finale

Ora dobbiamo calcolare la durata del video che non deve essere sfumato, perché vogliamo sfumarlo alla fine. Quindi sottrarre la durata del video con il tempo di sfumare. In genere la sfumata puo' durare qualche secondo, in questo caso calcoliamo 3 secondi.

333.560000 - 3

lo possiamo fare anche da bash con il comando bc, per esempio:

$ echo "333.560000-3" | bc -l
330.560000

Adesso inseriamo i valori nella riga di comando. Il filtro usato fade e afade servono a sfumare il video (il primo) e l'audio (il secondo). Ecco il comando:

$ ffmpeg -y -i madonna.mp4 -vf fade=out:st=330.560000:d=3 -af afade=t=out:st=330.560000:d=3 -c:v libx264 -crf 22 -preset veryfast -strict -2 madonna_sfumata_fine.mp4

L'opzioni che ci interessano sono le seguenti:

fade=out:st=330.560000:d=3
afade=t=out:st=330.560000:d=3

in cui sono indicati la durata del video non sfumato (330 secondi) e la durata della sfumatura (3 secondi) 

Sfumatura iniziale

Adesso sfumiamo il video con la sfumatura finale aggiungendo la sfumatura iniziale

$ ffmpeg -i madona_sfumata_fine.mp4 -vf "fade=t=in:st=0:d=3" -c:a copy madonna_sfumata.mp4

Ok adesso abbiamo un video sfumato di 3 secondi sia all'anizio che alla fine, e sia audio che video.