Obiettivi della lezione
Adesso le clip sono sul computer. Questa lezione le trasforma in un video solo, e lo fa con ffmpeg, che è il programma che sta sotto a quasi tutto quello che tocca un file video, compresi i montatori con i pulsanti.
La parte importante però non sono i comandi: sono i tre modi in cui questa catena si rompe. Li ho incontrati tutti e tre costruendola, e hanno una cosa in comune che li rende cattivi: nessuno dei tre dà un messaggio di errore. Il file esce, si apre, dura il tempo giusto. È sbagliato dentro.
Alla fine della lezione riesci a:
- Leggere che cosa c'è dentro a una clip prima di toccarla;
- Portare clip diverse allo stesso formato, che è il passo su cui sta in piedi tutto il resto;
- Unire, tagliare, mettere la musica e imprimere i sottotitoli;
- Accorgerti di un video sbagliato che non ha dato nessun errore.
Guardare dentro prima di toccare
Una clip non è un file, sono due tracce in una scatola: il video e l'audio. E ognuno ha delle proprietà che il telefono decide da solo, senza dirtelo. Il comando che le legge si chiama ffprobe, e viene installato insieme a ffmpeg.
ffprobe -v error -show_entries \
stream=codec_type,width,height,avg_frame_rate,duration \
-of default=nw=1 clip-01.mp4
Su tre clip girate nello stesso pomeriggio può venire fuori una cosa così:
| Clip | Misure | Fotogrammi al secondo | Audio |
|---|---|---|---|
| clip-01 | 1920 × 1080 | 30 | sì |
| clip-02 | 1080 × 1920 | 24 | sì |
| clip-03 | 1280 × 720 | 60 | no |
Tre clip, tre misure diverse, tre velocità diverse, e una senza traccia audio perché l'hai girata in un posto rumoroso col microfono spento. È la situazione normale, non un caso strano. Tenetela a mente, perché il paragrafo che viene è esattamente questo caso.
La rotazione è scritta a parte
Il telefono gira quasi sempre il sensore in orizzontale e scrive in un campo a parte quanto va ruotata l'immagine. Un programma che non guarda quel campo monta un video coricato. È il primo controllo da fare quando un video esce storto senza motivo apparente.
Il guasto che non dà errore
Il comando per incollare due video in ffmpeg si chiama concat. Si scrive un elenco e si lancia:
printf "file '%s'\n" clip-01.mp4 clip-02.mp4 clip-03.mp4 > lista.txt
ffmpeg -f concat -safe 0 -i lista.txt -c copy insieme.mp4
Ho lanciato esattamente questo sulle tre clip della tabella. Il file esce. Dura 15,02 secondi, che è la somma giusta di 6 + 5 + 4. Se lo apri e guardi i primi secondi, sembra a posto.
Poi si misura, e viene fuori questo:
Tre cose rotte, zero messaggi di errore
- L'intestazione mente sulle misure. Il file dichiara 1920 × 1080. Ma al secondo 8 i fotogrammi sono 1080 × 1920, e al secondo 12 sono 1280 × 720. Un lettore che crede all'intestazione stira tutto quello che viene dopo il primo pezzo.
- L'audio finisce prima del video. La traccia video dura 15,00 secondi, quella audio 11,02. Gli ultimi quattro secondi sono muti, perché la terza clip non aveva la traccia. Misurato con
volumedetectal secondo 12: non restituisce niente, la traccia è proprio finita. - I tempi si accavallano. Ai due punti di giunzione ffmpeg sputa centinaia di righe
non monotonically increasing dts: sono i fotogrammi che arrivano con un orario che è già passato.
Questo è il guasto peggiore che ci sia, perché assomiglia a un successo. Il motivo è semplice e vale la pena scriverlo per esteso: concat -c copy incolla tracce senza ricomprimerle, e pretende che siano già identici. Stessa misura, stessa velocità, stessi pixel, stesso codec audio. E l'audio ci deve essere: se una clip non ce l'ha, tutte quelle dopo di lei perdono il suono.
Normalizzare, il passo che regge tutto
La soluzione è un passo in più prima di incollare: si porta ogni clip allo stesso formato, una per una. Si chiama normalizzare, ed è il novanta per cento di questa lezione.
ffmpeg -y -i clip-02.mp4 \
-vf "scale=1080:1920:force_original_aspect_ratio=increase,
crop=1080:1920,setsar=1,fps=30" \
-c:v libx264 -crf 20 -preset veryfast -pix_fmt yuv420p \
-c:a aac -b:a 192k -ar 48000 -ac 2 \
-video_track_timescale 90000 -movflags +faststart \
pronte/02.mp4
Riga per riga, quello che conta:
scale=...:increaseseguito dacropingrandisce finché la cornice è piena e taglia quello che avanza. Il soggetto resta grande, e i bordi si perdono. È quello che vuoi per un reel girato in orizzontale.setsar=1dice che i pixel sono quadrati. Senza, certe clip escono schiacciate anche se le misure tornano.fps=30mette tutti alla stessa velocità: chi va a 24 guadagna fotogrammi ripetuti, chi va a 60 ne perde.-ar 48000 -ac 2uniforma l'audio a 48 kHz stereo. Due clip con frequenze diverse fanno andare fuori sincrono il suono a metà del video.+faststartsposta l'indice all'inizio del file, così il video comincia a vedersi prima di essere scaricato tutto.
La clip senza audio riceve del silenzio vero
Questa è la riga che quasi tutte le guide dimenticano. A una clip muta non basta «lasciarla com'è»: le si aggiunge una traccia di silenzio, sennò il flusso audio del video finale finisce prima del video.
ffmpeg -y -i clip-03.mp4 \
-f lavfi -t 4.0 -i anullsrc=channel_layout=stereo:sample_rate=48000 \
-map 0:v:0 -map 1:a:0 \
-vf "scale=1080:1920:force_original_aspect_ratio=increase,crop=1080:1920,setsar=1,fps=30" \
-c:v libx264 -crf 20 -preset veryfast -c:a aac -b:a 192k -ar 48000 -ac 2 \
pronte/03.mp4
anullsrc è un generatore di silenzio, e -t 4.0 gli dice di durare quanto la clip.
Come ci si sta dentro alla cornice sono tre scelte, e cambiano la faccia del video:
| Modo | Che cosa fa | Quando |
|---|---|---|
| riempi | Ingrandisce e taglia i bordi | Quasi sempre. Il soggetto resta grande. |
| sfoca | Il video intero al centro, dietro lo stesso video sfocato | Quando tagliare toglierebbe qualcosa che serve |
| barre | Il video intero al centro, dietro il nero | Quando l'inquadratura è sacra |
Unire, senza ricomprimere
Adesso che le clip sono identiche, concat fa il suo mestiere, e lo fa senza ricomprimere niente:
ffmpeg -y -f concat -safe 0 -i lista.txt -c copy \
-movflags +faststart grezzo.mp4
Ed è anche il giro più veloce: si comprime una volta sola, durante la normalizzazione.
Quale codificatore, e perché non se ne sceglie uno solo
libx264 lavora col processore e c'è su qualunque computer: è quello dei comandi qui sopra, e gli si chiede la qualità con -crf 20, che vuol dire «tienila a questo livello e usa i bit che servono».
I Mac hanno anche h264_videotoolbox, che usa il chip invece del processore: gli stessi 15 secondi di video nascono in 2,3 secondi invece di qualche decina. In cambio vuole un bitrate fisso (-b:v 8M), perché il -crf non lo ascolta, e a parità di qualità il file pesa di più: nella mia prova 5,4 MB contro 2,6.
⚠️ Su Windows e Linux h264_videotoolbox non esiste, e ffmpeg si ferma con Unknown encoder. Per questo uno script che monta sul computer di qualcun altro non sceglie un codificatore a priori: guarda quali ci sono e prende il migliore fra quelli.
E le misure dopo la catena giusta, sullo stesso caso che prima era rotto:
| Controllo | Senza normalizzare | Con |
|---|---|---|
| Misure a 2, 8 e 12 secondi | 1080×1920, 1280×720, 1920×1080 | sempre 1080×1920 |
| Durata delle due tracce | 15,00 / 11,02 | 15,029 / 15,050 |
| Errori di decodifica | centinaia | zero |
| Volume al secondo 12 | nessuna traccia | −31,8 dB, cioè la musica |
La musica, e il volume giusto
La musica sotto a una voce va tenuta bassa, e «bassa» è un numero: 0,13, cioè il tredici per cento. Sopra a 0,2 comincia a coprire le consonanti, e chi guarda senza cuffie non capisce le parole.
ffmpeg -y -i grezzo.mp4 -stream_loop -1 -i musica.mp3 \
-filter_complex "[1:a]volume=0.13,afade=t=out:st=13.0:d=2[m];
[0:a][m]amix=inputs=2:duration=first:dropout_transition=0,
dynaudnorm=f=250:g=15[a]" \
-map 0:v -map "[a]" -c:v copy -c:a aac -b:a 192k -t 15.05 \
finito.mp4
Le parti che contano: -stream_loop -1 ripete il brano finché serve, così una base da trenta secondi copre anche un video da due minuti. duration=first dice che a comandare è il video, quindi la musica non lo allunga. afade la fa sfumare negli ultimi due secondi, perché una musica tagliata di netto si sente. dynaudnorm pareggia il volume della voce fra una clip e l'altra: due clip girate in due stanze diverse hanno due volumi diversi, e senza questo passaggio chi guarda alza e abbassa il telefono.
I sottotitoli impressi
I sottotitoli in un reel non sono un accessorio: la maggior parte della gente guarda senza audio. E devono essere impressi dentro all'immagine, perché i sottotitoli come file separato Instagram non li legge.
La strada classica è il filtro subtitles di ffmpeg, che prende un file .srt e lo disegna sopra al video. Sul mio computer non funziona, e la ragione vale la pena saperla prima di perderci un'ora:
L'ffmpeg che installi potrebbe non avere i sottotitoli dentro
Il filtro subtitles ha bisogno di una libreria che si chiama libass, e ffmpeg la porta dentro solo se chi lo ha compilato ha voluto. Sul Mac, la versione distribuita da Homebrew il 28 settembre 2026 non ce l'ha: fra i filtri non esistono né subtitles, né ass, né drawtext. Si controlla in un comando:
ffmpeg -hide_banner -filters | grep -E " (subtitles|drawtext) "
Se non stampa niente, i sottotitoli con quel filtro non li fai, e nessun messaggio di errore te lo dirà in modo comprensibile: ffmpeg si lamenterà di un'opzione che non riconosce.
Il ripiego è disegnare ogni blocco di testo come un'immagine trasparente grande quanto il video, e sovrapporla. Si può fare con un programma di grafica, con un browser, con quello che preferisci: quello che conta è che esca un PNG con lo sfondo trasparente e il testo dove lo vuoi.
E questo ripiego ha un vantaggio che lo fa restare anche il giorno che libass torna: libass usa i caratteri installati nel sistema. Se il tuo carattere è quello del tuo marchio e non è installato come font di sistema, con libass i sottotitoli escono in Helvetica. Disegnandoli tu, escono col tuo.
ffmpeg -y -i video.mp4 \
-loop 1 -i sub-001.png \
-loop 1 -i sub-002.png \
-filter_complex "[0:v][1:v]overlay=0:0:enable='between(t,0.5,3.0)'[v1];
[v1][2:v]overlay=0:0:enable='between(t,7.0,10.0)'[v2]" \
-map "[v2]" -map "0:a?" -shortest \
-c:v libx264 -crf 20 -preset veryfast -c:a copy sottotitolato.mp4
enable='between(t,a,b)' accende la sovrapposizione solo nella finestra del blocco. Le sovrapposizioni si incatenano una dopo l'altra, e il video viene attraversato una volta sola.
Il fotogramma che finisce subito
Nel comando qui sopra c'è un -loop 1 davanti a ogni immagine. Sembra un dettaglio ed è il terzo guasto della lezione, il più infido dei tre.
Senza -loop 1, un'immagine consegna un fotogramma solo, al tempo zero, e poi finisce. La sovrapposizione, quando si accende alla sua finestra, non ha più niente da mettere: non dà errore, e non compare niente.
Perché sembra che funzioni
Il primo sottotitolo si vede lo stesso, perché cade vicino al tempo zero, dove quel fotogramma unico è ancora buono. Quindi apri il video, vedi la prima riga comparire al posto giusto, e pensi che sia tutto a posto. Mancano tutte le altre.
L'ho visto succedere: con due blocchi, uno a 0,5 secondi e uno a 7, il primo compariva e il secondo no. Messo -loop 1, compaiono tutti e due. Poi serve -shortest, sennò le immagini in ripetizione sono infinite e la codifica non finisce mai.
La morale è più larga del caso: quando controlli un video montato, guarda la fine e non l'inizio. Tutti e tre i guasti di questa lezione si vedono nella seconda metà.
Laboratorio: tre clip, un reel
Obiettivo: partire dalle tre clip scombinate della Lezione 1 e arrivare a un reel verticale con la musica sotto.
Consegna
- Guarda le tre clip con
ffprobee scrivi su un foglio misure, velocità e presenza dell'audio. Se sono tutte e tre uguali, rigirane una in orizzontale: ti serve il caso difficile. - Prova la strada sbagliata: incollale con
concat -c copysenza normalizzare. Il file esce. - Trova il guasto da solo. Misura la durata delle due tracce separatamente e confronta. Poi tira fuori un fotogramma a metà e uno verso la fine e guarda le misure. Questo passo è il cuore del laboratorio: serve a saper riconoscere un video rotto che sembra sano.
- Normalizza le tre clip al formato verticale e rifai l'unione.
- Rimisura le stesse tre cose, e controlla che adesso tornino.
- Metti la musica a 0,13 e ascolta la fine: la sfumatura si deve sentire.
- Guarda il video dall'inizio alla fine col telefono, senza audio. È come lo vedrà chi lo trova.
Risultato atteso
Un file verticale, con le misure uguali dal primo all'ultimo fotogramma, le due tracce che durano lo stesso e nessun errore di decodifica. Se vuoi il confronto pulito, tieni tutti e due i file: quello rotto serve da paragone, ed è la cosa che si porta in aula.
Mini-test di autoverifica
Istruzioni
Sezione A: 4 domande a risposta multipla (1 punto). Sezione B: 1 domanda aperta (3 punti). Totale 7. Soglia: 60% (5/7).
Sezione A: risposta multipla
concat -c copypretende che le clip siano:
a) corte b) già identiche per misure, velocità e audio c) dello stesso peso d) girate con lo stesso telefono- Una clip senza traccia audio, dentro a un montaggio:
a) non dà problemi b) fa perdere il suono a quelle dopo di lei c) si scarta d) allunga il video - Senza
-loop 1, un'immagine sovrapposta:
a) resta per sempre b) dà errore c) consegna un fotogramma a tempo zero e finisce d) rallenta il video - Il filtro
subtitlesdi ffmpeg può mancare perché:
a) è a pagamento b) serve libass, e chi compila può non metterla c) funziona solo su Windows d) è stato tolto da ffmpeg
Sezione B: risposta aperta
- (3 punti) Un video montato ti sembra a posto. Elenca i tre controlli che fai, in ordine, per esserne sicuro, e spiega per ognuno che cosa scopriresti.
Mostra risposte corrette
Sezione A
- b: incolla tracce senza ricomprimerle, quindi devono già combaciare.
- b: e per questo le si aggiunge una traccia di silenzio vero.
- c: e il primo sottotitolo si vede lo stesso, che è quello che inganna.
- b: si controlla in un comando, prima di perderci tempo.
Sezione B, risposta modello
5. Primo: confronto la durata della traccia video con quella della traccia audio. Se l'audio è più corto, da qualche parte c'è una clip muta e la fine del video è silenziosa. Secondo: tiro fuori tre fotogrammi, uno all'inizio, uno a metà e uno verso la fine, e guardo le misure. Se cambiano, l'intestazione mente e certi lettori stireranno l'immagine. Terzo: lo faccio decodificare tutto e guardo se escono errori sui tempi, che vengono fuori solo ai punti di giunzione. Chi aggiunge «e poi lo guardo dalla fine» ha capito la lezione.
Valutazione (su 7)
- 7: ottimo. 5-6: sufficiente. < 5: rifai il laboratorio fermandoti al punto 3, che è quello che insegna a vedere.
Riassunto della lezione
Cosa hai imparato
- Si guarda dentro prima di toccare. Misure, velocità, rotazione e presenza dell'audio si leggono in un comando.
- Normalizzare è il passo che regge tutto. Incollare clip diverse dà un file che sembra buono e ha l'intestazione che mente.
- Alla clip muta si dà del silenzio vero, sennò il suono finisce prima del video.
- La musica sta a 0,13 e sfuma in coda, e le voci si pareggiano perché due stanze hanno due volumi.
- I sottotitoli impressi vogliono libass, che può mancare; disegnarli come immagini funziona sempre e tiene il tuo carattere.
- I guasti si vedono nella seconda metà, quindi si controlla la fine e non l'inizio.
Prossimi passi
Fin qui hai montato a mano, dando i numeri tu. Nella Lezione 3, Le regole in un file quei numeri li decide l'assistente leggendo le tue due righe di didascalia, e le tue preferenze smettono di essere una cosa da ripetere ogni volta.