zkk / ffmpeg - Resize, crop e concat videos



Il tutorial parte da un DVD da cui ho estratto n. 13 capitoli (files denominati /cap-01.mp4/, /cap-02.mp4/ fino a /cap-13-mp4/) e che, siccome tutti questi capitoli hanno dimensioni diverse (width:height), non riesco a concatenarli tramite Avidemux.

Seguono i passaggi effettuati per ottenere un file /dvd.mp4/ che sia l’unione di tutti i capitoli con univoca dimensione (width:height).

Estrazione valori dai capitoli

Comandi ffprobe

Mostra altezza (height)

ffprobe -v error -show_streams <cap-##.mp4> | grep height

Mostra larghezza (width)

ffprobe -v error -show_streams <cap-##.mp4> | grep width

Mostra larghezza x altezza

ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=s=x:p=0 <cap-##.mp4>
ffprobe -i <cap-##.mp4> -show_entries format=duration -v quiet -of csv="p=0"
ffprobe -i <cap-##.mp4> -show_entries format=duration -v quiet -of csv="p=0" -sexagesimal

Mostra durata

ffprobe -v error -show_streams <cap-##.mp4> | grep duration=

Il valore duration è la durata del video espressa in secondi.

Valori riscontrati

#widthheightduratasecondistart
0670056423:49.081429.081429.08
0770056624:11.241451.242880.32
0870056624:11.001451.004331.32
0970056623:04.841384.845716.16
1070056623:38.601418.607134.79

Resize

Parifico tutti i files dei capitoli alla maggiore larghezza rilevata, ovvero il valore (720). Per completezza inserisco anche il comando che, viceversa, parifica tutti i video alla maggiore altezza riscontrata (576). Il nome del file risultante lo chiamo /res-01.mp4/, /res-02.mp4/ fino a /res-13.mp4/.

Comandi ffmpeg

Resize fixed width (720) and height keepping aspect ratio

ffmpeg -i <cap-##.mp4> -filter:v scale="720:trunc(ow/a/2)*2" -c:a copy <res-##.mp4>

Resize fixed height (576) and width keepping aspect ratio

ffmpeg -i <cap-##.mp4> -filter:v scale="trunc(oh*a/2)*2:576" -c:a copy <res-##.mp4>

Valori (height:width) risultanti

#widthheightdurata
017203464:26
027203744:48
037203569:20
047203546:26
057203588:10
0672038211:45
077203847:22
087205761:00
097203706:26
107203705:38
117203702:37
127203702:11
137203700:50

Crop

A questo punto taglio tutti i video all’altezza minima pari a 346, il seguente passaggio va effettuato per tutti i capitoli, anche per quelli che hanno già le misure corrette in quanto è necessaria uniformità nella codifica per poter effettuare correttamente il passaggio finale di Merge. Il nome del file risultante lo chiamo /crop-01.mp4/, /crop-02.mp4/ fino a /crop-13.mp4/.

Comandi ffmpeg

Crop fixed height (346)

Il seguente comando esegue il crop al valore indicato (346) partendo dal centro del video posto che tutti i video hanno medesima larghezza impostata al passaggio precedente (720):

ffmpeg -i <res-##.mp4> -vf "crop=720:346" <crop-##.mp4>

Valori finali

#widthheightdurata
017203464:26
027203464:48
037203469:20
047203466:26
057203468:10
0672034611:45
077203467:22
087203461:00
097203466:26
107203465:38
117203462:37
127203462:11
137203460:50

Merge

A questo punto eseguo la concatenazione di tutti i segmenti. Ipotizzando che i segmenti di video da unire siano nella directory corrente e si chiamino /crop-01.mp4/, /crop-02.mp4/ fino a /crop-13.mp4/ come indicato nei passaggi precedenti, avremo:

rm list.txt
for i in crop-??.mp4; do echo "file '$i'" >> list.txt; done
ffmpeg -safe 0 -f concat -i list.txt -c copy dvd.mp4

Ottenendo in tal modo il file /dvd.mp4/ come la concatenazione di tutti i capitoli con medesima dimensione (width:height) pari a 720:346.

Capitoli

ffmpeg -i INPUT.mp4 -f ffmetadata FFMETADATAFILE.txt
ffmpeg -i INPUT.mp4 -i FFMETADATAFILE.txt -map_metadata 1 -codec copy OUTPUT.mp4
[CHAPTER]
TIMEBASE=1/1000
START=7292521
END=10593062
title=A Christmassy Ted