2012-10-22 32 views
33

Sto lavorando a un servizio TV online. Uno degli obiettivi è che il video venga riprodotto senza plug-in aggiuntivi del browser (ad eccezione di Flash).Streaming live tramite MP4

Ho deciso di utilizzare MP4, perché è supportato dalla maggior parte dei browser HTML5 e Flash (per fallback). I video vengono transcodificati da ASF su un server da FFMpeg.

Tuttavia, ho trovato che MP4 non può essere trasmesso in diretta perché ha un atomo moov per i metadati che deve specificare la lunghezza. FFMpeg non può trasmettere direttamente mp4 allo stdout, perché mette il moov alla fine del file. (Live transcoding and streaming of MP4 works in Android but fails in Flash player with NetStream.Play.FileStructureInvalid error)

Naturalmente, MPEG-TS esiste, ma non è supportato da HTML5 <video>.

Quello che ho pensato è un metodo per transcodificare lo streaming in tempo reale su MP4 e su ogni nuova richiesta HTTP per esso, prima invia un moov che specifica un numero molto lungo per la lunghezza del video, quindi avvia l'invio il resto del file MP4.

È possibile utilizzare MP4 per lo streaming in questo modo?

Dopo alcune ricerche e la risposta di av501, capisco che le dimensioni dei frame devono essere conosciute in modo che possano funzionare.

Il file mp4 può essere segmentato in parti più piccole in modo che possa essere trasmesso in streaming?

Ovviamente, il passaggio a un altro contenitore/formato è un'opzione, ma l'unico formato compatibile sia con Flash sia con HTML5 è mp4/h264, quindi se devo supportare entrambi, dovrei effettuare la transcodifica due volte.

risposta

5

Ecco i miei pensieri, ragazzi, alcuni potrebbero essere in qualche modo lontani. Supplico l'ignoranza perché nessuno ha veramente documentato questo processo in modo completo, è una supposizione educata.

AvAssetWriter codifica solo su un file, non sembra esserci alcun modo per ottenere il video codificato in memoria. Leggendo il file mentre viene scritto da un thread in background per dire che un socket ha come risultato un flusso elementare, questo è essenzialmente un m4v, che è un contenitore con h264/acc mdata, ma nessun moov atomo. (in altre parole nessuna intestazione) Nessun lettore fornito da Apple può riprodurre questo stream, ma un player modificato basato su ffplay dovrebbe essere in grado di decodificare e riprodurre il flusso. Questo dovrebbe funzionare, perché ffplay usa libavformat che può decodificare flussi elementari, un avvertimento dato che non ci sono informazioni sulla lunghezza del file, alcune cose devono essere determinate dal gioco, DTS e PTS e anche il giocatore non può cercare all'interno del file.

In alternativa, è possibile utilizzare il comando Naul dal flusso m4v per creare un flusso rtmp.

Se si desidera discutere ulteriormente è possibile contattarmi direttamente.

Come ottenere i dati.

Dal momento che dovresti ricostruire il file dal lato ricevente in ogni caso, immagino che potresti semplicemente segmentarlo, Steve McFarin ha scritto un piccolo AppleSegmentedEcorder che puoi trovare nella sua pagina github, questo risolve alcuni dei problemi per moov atom dato che hai tutte le informazioni sul file.

+1

ecco una buona spiegazione, iniziando a sembrare come rtmp o qualche protocollo personalizzato è la strada da percorrere http://fabiensanglard.net/mobile_progressive_playback/index.php –

+0

la tua risposta ha avvertenza, ha scritto sopra. Il tempo è materia per lo streaming e la riproduzione. quindi -1 – agfe2

2

No, non è solo la lunghezza molto lunga .. è necessario conoscere la dimensione esatta di ogni frame per creare l'intestazione in un mp4. [che è il motivo per cui viene creato alla fine dai vari encoder].

+0

Queste informazioni non possono essere lasciate vuote? Dopo alcuni ritocchi, sono riuscito a creare un file m4v (fondamentalmente un MP4) senza un moov atom, e ha giocato in Totem, senza mostrare alcuna informazione sulla lunghezza del video. – Ivo

+0

M4v è un mp4 (contenitore) contenente il file elementare o solo il file elementare? Senza l'intestazione non è più conforme. Quindi, se gioca o meno dipende da quanto intelligente è il giocatore. Alcuni giocatori potrebbero lavorare duro e provare a risolvere il problema. Ma la maggior parte non la giocherà. – av501

+0

Sì, sembra che m4v possa essere solo un file mp4 o uno stream h264 non elaborato. Quelli che funzionavano nel browser erano mp4 e quello generato da ffmpeg era un flusso grezzo. Quindi sembra che non può essere fatto, dopo tutto. – Ivo

0

Solo guardando il secondo paragrafo della tua domanda ("I video sono transcodificati da ASF su un server da ffmpeg."), Hai detto che stai usando ffmpeg per transcodificare i video sul server.

Utilizzare qt-faststart o MP4Box per posizionare l'atomo MOOV all'inizio del file. (anche tu ti assicuri che usando H264 Video & codec audio AAC per supporto universale)

Spero che questo ti abbia aiutato.

+2

Non è così. Dopo numerose ricerche su google, ho scoperto che qt-faststart è stato menzionato molto - ma non funzionerà per lo streaming live poiché lo streaming è CONTINUO - i frame/lunghezza non possono essere conosciuti dall'inizio, quindi un atomo MOOV non può essere creato. qt-faststart sarebbe di aiuto se quello che mi serviva fosse pseudostreaming (download continuo). – Ivo

17

È possibile utilizzare MP4 frammentato. Un file MP4 frammentato è costruita la seguente:

moov [moof mdat]+ 

La scatola moov quindi contiene solo informazioni di base sui binari (come molti, il loro tipo, l'inizializzazione di codec e così via), ma nessuna informazione circa i campioni in pista. Le informazioni sulle posizioni dei campioni e sulle dimensioni del campione sono nella casella moof, ciascuna casella moof è seguita da un mdat che contiene gli esempi come descritto nella casella moof precedente. Tipicamente si dovrebbe scegliere la lunghezza di una coppia (moof, mdat) di circa 2,4 o 8 secondi (non ci sono specifiche su questo, ma questi valori sembrano essere ragionevoli per la maggior parte degli usi).

Questo è un modo per costruire un flusso MP4 senza fine.

+0

dai uno sguardo qui: https://groups.google.com/forum/?fromgroups=#!topic/mp4parser-discussion/e7yg6clATHc questo tipo sembra avere problemi molto simili. –

+3

Il mp4 in definitiva frammentato è come lo streaming live di Apple HTTP e fa un buon lavoro. L'ho ignorato all'inizio perché pensavo che la frammentazione sembrasse una complicazione inutile, ma ora vedo che è l'unica opzione possibile. – Ivo

+0

@SebastianAnnies Sembra funzionare, tuttavia (almeno) Safari sembra richiedere a ciascun frammento una richiesta Range GET separata (dall'inizio del frammento fino a EOF, ma termina prematuramente), rendendo l'intera gestione dello streaming molto più fastidiosa. Hai la stessa esperienza? –