2015-06-16 12 views
8

Sto creando un mp4 frammentato per lo streaming HTML5, utilizzando il seguente comando:Problema Flush e latenza con la Creazione MP4 frammentato in FFMPEG

-i rtsp://172.20.28.52:554/h264 -vcodec copy -an -f mp4 -reset_timestamps 1 -movflags empty_moov+default_base_moof+frag_keyframe -loglevel quiet - 
  1. "rtsp -i: //172.20.28.52: 554/h264 "perché la sorgente è h264 nei pacchetti rtp in streaming da una telecamera IP. Per motivi di prova, la fotocamera è impostata con GOP di 1 (vale a dire tutti i fotogrammi sono fotogrammi chiave)
  2. "-codifica invcodec" perché non ho bisogno di transcodifica, solo il remuxing per mp4.
  3. "-movflags empty_moov + default_base_moof + frag_keyframe" per creare un mp4 frammentato in base alle specifiche delle estensioni dei sorgenti multimediali.
  4. "-" alla fine per emettere mp4 su stdout. Sto afferrando l'output e inviandolo al webclient attraverso le prese sul web.

Tutto sta funzionando bene, aspetto un problema di latenza che sto cercando di risolvere. Se sto la registrazione ogni volta che un dato è in arrivo da stdout, con il timestamp di arrivo, ottengo questo output:

16/06/2015 15: 40: 45,239 ottenuto dimensione dei dati = 24

16/06/2015 15: 40: 45,240 ottenuto dimensione dei dati = 7197

16/06/2015 15: 40: 45,241 ottenuto dimensione dei dati = 32768

16/06/2015 15: 40: 45,241 dimensione dei dati = 4941

16/06/2015 15 : 40: 45,241 ottenuto dimensione dei dati = 12606

16/06/2015 15: 40: 45,241 ottenuto dimensione dei dati = 6345

16/06/2015 15: 40: 45,241 ottenuto dimensione dei dati = 6339

16/06/2015 15: 40: 45,242 ottenuto dimensione dei dati = 6336

16/06/2015 15: 40: 45,242 ottenuto dimensione dei dati = 6361

16/06/2015 15: 40: 45,242 got dimensione dei dati = 6337

16/06/2015 15: 40: 45,242 ottenuto dimensione dei dati = 6331

16/06/2015 15: 40: 45,242 ottenuto dimensione dei dati = 6359

16/06/2015 15: 40: 45,243 ottenuto dimensione dei dati = 6346

16/06/2015 15: 40: 45,243 ottenuto dimensione dei dati = 6336

16/06/2015 15: 40: 45,243 ottenuto dimensione dei dati = 6338

16/06/2015 15: 40: 45,243 dimensione dei dati = 6357

16/06/20 15 15: 40: 45,243 ottenuto dimensione dei dati = 6357

16/06/2015 15: 40: 45,243 ottenuto dimensione dei dati = 6322

16/06/2015 15:40:45.243 ottenuto dimensione dei dati = 6359

16/06/2015 15: 40: 45,244 ottenuto dimensione dei dati = 6349

16/06/2015 15: 40: 45,244 ottenuto dimensione dei dati = 6353

16/06/2015 15: 40: 45,244 ottenuto dimensione dei dati = 6382

16/06/2015 15: 40: 45,244 ottenuto dimensione dei dati = 6403

16/06/2015 15: 40: 45,304 ha ottenuto la dimensione dei dati = 6393

16/06/2015 15: 40: 4 5,371 ottenuto dimensione dei dati = 6372

16/06/2015 15: 40: 45,437 ottenuto dimensione dei dati = 6345

16/06/2015 15: 40: 45,504 ottenuto dimensione dei dati = 6352

16/06/2015 15: 40: 45,571 ottenuto dimensione dei dati = 6340

16/06/2015 15: 40: 45,637 ottenuto dimensione dei dati = 6331

16/06/2015 15: 40: 45,704 ha ottenuto la dimensione dei dati = 6326

16/06/2015 15:40 : 45,771 ottenuto dimensione dei dati = 6360

16/06/2015 15: 40: 45,838 ottenuto dimensione dei dati = 6294

16/06/2015 15: 40: 45,904 ottenuto dimensione dei dati = 6328

16/06/2015 15: 40: 45,971 ottenuto dimensione dei dati = 6326

16/06/2015 15: 40: 46,038 ottenuto dimensione dei dati = 6326

16/06/2015 15: 40: 46,105 ottenuto dimensione dei dati = 6340

16/06/2015 15: 40: 46,171 ottenuto dimensione dei dati = 6341

16/06/2015 15: 40: 46,238 ottenuto dimensione dei dati = 6332

Come si può vedere, le prime 23 righe (che contengono i dati di circa 1,5 secondi di video) stanno arrivando quasi istantaneamente, e quindi il ritardo tra ogni 2 righe consecutive è ~ 70ms che ha senso perché il video è 15 fotogrammi al secondo. Questo comportamento introduce una latenza di circa 1,5 secondi.

Sembra un problema di svuotamento perché non vedo alcun motivo per cui ffmpeg debba tenere i primi 23 fotogrammi in memoria, specialmente dal momento che ogni fotogramma è un frammento del proprio all'interno del mp4. Non ho potuto, tuttavia, trovare alcun metodo che possa far sì che ffmpeg possa svuotare più velocemente questi dati.

Qualcuno ha un suggerimento?

vorrei notare che questo è un follow-up domanda a questo: Live streaming dash content using mp4box

+0

Mi è venuto in mente che si ha il controllo del 'blocksize' utilizzato per il buffering dell'output. Controlla http://www.ffmpeg.org/ffmpeg-all.html#toc-pipe e verifica se il tweaking di quel valore può esserti d'aiuto. –

+0

@PabloMontilla Ho provato a giocare con alcuni valori diversi di Blocksize e sebbene abbia effettuato l'output in qualche modo, non ha risolto il ritardo iniziale. – galbarm

+0

Ciao @galbarm! Non riesco a far funzionare il video sulla pagina con i parametri 'ffmpeg', ottenendo sempre' Ignora casella di livello superiore non riconosciuto: ftyp'. (hip ip64). Ho anche provato a cambiare '-vcodec' in' libx264', in quel caso ottengo 'Ignora box di primo livello non riconosciuto: mdat'. Puoi per favore descrivere il tuo codice in più o inserirlo da qualche parte? La parte più interessante è il parametro '.addSourceBuffer', cioè la stringa codec. Grazie in anticipo! – zarkone

risposta

4

La chiave per rimuovere il ritardo è di utilizzare l'argomento -probesize:

probesize intero (ingresso)

Set tastatura dimensione in byte, vale a dire la dimensione dei dati da analizzare per ottenere informazioni sul flusso. Un valore superiore sarà abilitare il rilevamento di ulteriori informazioni nel caso in cui sia disperso nel flusso , ma aumenterà la latenza. Deve essere un numero intero non inferiore a 32. Per impostazione predefinita è 5000000.

Per impostazione predefinita il valore è 5.000.000 di byte che equivaleva a ~ 1.5 sec di video. Sono stato in grado di eliminare quasi completamente il ritardo riducendo il valore a 200.000.

0

ho risolto il problema di latenza utilizzando l'opzione -g per impostare il numero di fotogrammi nel gruppo. Nel mio caso ho usato -g 2.Sospetto che se non lo rendi esplicito, il frammento aspetta che l'origine fornisca il fotogramma chiave o utilizzi un valore predefinito molto grande per generare il fotogramma chiave prima di chiudere il frammento e scaricarlo sullo stdout.

+0

Immagino che tu stia transcodificando il video in modo da avere il controllo sulla dimensione del GOP di output. Sto usando ffmpeg in modalità "vcodec copy", quindi lo rimuovo solo in mp4 frammentato.Ho provato a impostare la sorgente del mio video (telecamera ip) per fornire solo fotogrammi chiave, ma non ha aiutato con la latenza iniziale. – galbarm

0

In genere il buffering per stdout è disabilitato in caso di output della console. Se si esegue ffmpeg dal codice, il buffering è abilitato, in modo da ottenere i dati solo quando il buffer è pieno o il comando termina.

È necessario eliminare il buffer di stdout del sistema operativo. Su Windows è impossibile, ma su Ubuntu per l'ex. C'è http://manpages.ubuntu.com/manpages/maverick/man1/stdbuf.1.html

Problemi correlati