Uno stream 24/7 che non si riconnette tra un video e l'altro: un unico ffmpeg alimentato tramite pipe
Video
Un canale live che trasmette video finiti 24/7 ha due design semplici, e entrambi perdono qualcosa. Riavviare ffmpeg per ogni video interrompe la connessione RTMP a ogni cambio. Una playlist concat viene letta una sola volta all'avvio, quindi un nuovo video deve attendere il riavvio successivo.
Il design
Ogni video viene convertito una volta in MPEG-TS alle dimensioni e al frame rate dello stream; un video verticale viene posizionato su una copia sfocata di sé stesso invece che su bande nere. Un processo ffmpeg legge MPEG-TS dallo standard input e codifica a bitrate costante con un keyframe ogni due secondi, come si aspetta l'ingest live. Un piccolo feeder scrive i file preparati in quella pipe uno dopo l'altro, a ritmo reale, scegliendo il file successivo a ogni cambio: prima i video mai riprodotti, poi quelli riprodotti meno di recente. Il lettore MPEG-TS di ffmpeg nota che i timestamp di ogni file ripartono da zero e li sposta, così l'output prosegue senza interruzioni.
Dettaglio uno: il ritmo dal primo byte
La nostra prima versione avviava l'orologio quando partiva ffmpeg. La preparazione del primo file richiedeva nove secondi, quindi il feeder pensava di essere in ritardo di nove secondi e li inviava tutti insieme. Avviare l'orologio al primo byte scritto ha risolto: una sessione di 53 secondi ha prodotto 53 secondi di stream.
Dettaglio due: l'audio in corrispondenza del cambio
A un cambio, l'audio del file successivo iniziava 17 millisecondi prima della fine dell'audio del file precedente. L'encoder avvertiva che l'input andava "indietro nel tempo" e il muxer correggeva un timestamp. Il resampling con aresample=async=1:min_hard_comp=0.01:first_pts=0 taglia o aggiunge padding a tali sovrapposizioni prima che l'encoder le veda. In una sessione di poco più di un minuto con cinque cambi, tutti i timestamp audio e video nello stream ricevuto aumentavano, e lo stream è stato decodificato senza un singolo errore.
Dettaglio tre: alcuni avvisi sono normali
Ogni file riavvia i contatori MPEG-TS e il proprio orologio, quindi ffmpeg segnala "Packet corrupt" e "timestamp discontinuity" a ogni cambio. Queste righe sono attese e le teniamo fuori dal log affinché gli errori reali risaltino.
Il watchdog
Se ffmpeg esce o il suo avanzamento si ferma per un minuto, lo stream riparte con pause crescenti e invia un messaggio dopo ripetuti fallimenti. Nel nostro test abbiamo interrotto manualmente l'encoder; lo stream è tornato attivo dopo sette secondi e un video aggiunto durante l'esecuzione si è unito alla rotazione senza una riconnessione. Un riavvio è una breve riconnessione, quindi imposta la trasmissione su YouTube in modo che parta automaticamente e non si fermi automaticamente. La stream key è oscurata in ogni riga di log, anche in quelle di ffmpeg. Studio distribuisce questo canale live come servizio systemd.