2014-04-25 28 views
13

Possiedo un'applicazione server che esegue il rendering di 30 flussi video FPS, quindi la codifica e la mux in tempo reale in un WebM Byte Stream.Come mantenere un flusso video live di MediaSource in-sync?

Sul lato client, una pagina HTML5 apre un WebSocket al server, che inizia a generare il flusso quando viene accettata la connessione. Dopo la consegna dell'intestazione, ogni frame WebSocket successivo è costituito da un singolo SimpleBlock WebM. Un fotogramma chiave si verifica ogni 15 fotogrammi e quando questo accade viene avviato un nuovo Cluster.

Il client crea anche un MediaSource e quando riceve un frame dal WS, aggiunge il contenuto al suo buffer attivo. <video> avvia la riproduzione immediatamente dopo l'aggiunta del primo fotogramma.

Tutto funziona ragionevolmente bene. Il mio unico problema è che il jitter di rete fa in modo che la posizione di riproduzione si sposti dal tempo reale dopo un po '. La mia soluzione attuale è agganciare l'evento updateend, controllare la differenza tra lo video.currentTime e il codice di tempo sul Cluster in arrivo e aggiornare manualmente lo currentTime se non rientra nell'intervallo accettabile. Sfortunatamente, questo provoca una pausa notevole e salta nella riproduzione che è piuttosto spiacevole.

La soluzione si sente anche un po 'strano: io so esattamente dove l'ultimo fotogramma chiave è, eppure devo convertirlo in un intero secondo (secondo le specifiche W3C) prima che io possa passare in currentTime, in cui il browser presumibilmente deve quindi andare in giro e trovare il fotogramma chiave più vicino.

La mia domanda è questa: c'è un modo per dire all'elemento multimediale di cercare sempre l'ultimo fotogramma chiave disponibile o mantenere l'ora di riproduzione sincronizzata con l'ora dell'orologio di sistema?

+0

Hai trovato una soluzione? –

+0

Mi sono reso conto che la soluzione per cambiare il tempo corrente è la migliore, i difetti che causa sono accettabili perché prima che un problema di rete ha causato l'aumento del buffer, quindi un altro problema tecnico è normale ... rimarrà solo con glitch se ci sono problemi di connessione consecutivi durante lo streaming. –

risposta

3

rete jitter fa sì che la posizione di riproduzione alla deriva

Questo non è il tuo problema. Se si verificano interruzioni nel flusso, non è necessario eseguire il buffering a sufficienza prima della riproduzione, e la riproduzione ha solo un buffer di dimensioni appropriate, anche se alcuni secondi dietro il tempo reale (che è normale).

mia soluzione attuale è quella di agganciare nell'evento updateend, controllare la differenza tra il video.currentTime e del codice temporale del cluster entrante

che è vicino al metodo corretto. Ti suggerisco di ignorare il codice temporale del cluster in arrivo e ispezionare invece i tuoi intervalli di tempo bufferizzati. Quello che hai ricevuto sul cluster WebM e ciò che è stato decodificato sono due cose diverse.

Sfortunatamente, questo provoca una pausa notevole e salta nella riproduzione che è piuttosto spiacevole.

In quale altro modo faresti? Puoi saltare in tempo reale o aumentare la velocità di riproduzione per raggiungere il tempo reale. In ogni caso, se vuoi raggiungere il tempo reale, devi saltare in tempo per farlo.

La soluzione si sente anche un po 'strano: io so esattamente dove l'ultimo fotogramma chiave è

È possibile, ma il giocatore non lo fa fino a quando viene decodificato che i media.In ogni caso, il keyframe è irrilevante ... puoi cercare posizioni di non keyframe. Il browser decodifica davanti ai fotogrammi P/B come richiesto.

devo convertirlo in un intero secondo (secondo le specifiche W3C) prima che io possa passare in currentTime

Questo è totalmente falso. Lo currentTime è specificato come double. https://www.w3.org/TR/2011/WD-html5-20110113/video.html#dom-media-currenttime

mia domanda è questa: c'è un modo per dire al supporto Elemento di cercare sempre l'ultimo fotogramma chiave a disposizione, o di tenere il tempo di riproduzione sincronizzata con il tempo di orologio di sistema?

Riproduce automaticamente l'ultimo buffer. Non devi fare nulla. Stai facendo il tuo lavoro assicurandoti che i dati multimediali vengano inseriti nel buffer e impostando la riproduzione il più vicino possibile. Puoi sempre avanzare in avanti se cambia una condizione di rete che ti permette di farlo, ma francamente sembra che tu abbia solo un codice rotto e una strategia di buffering fallita. Altrimenti, la riproduzione sarebbe semplicemente liscia.

L'arresto in caso di caduta non avverrà automaticamente, e non dovrebbe. Se il lettore si interrompe a causa dell'esaurimento del buffer, è necessario ricostruire un buffer prima che la riproduzione possa riprendere. Questo è l'intero punto del buffer.

Inoltre, la tua aspettativa di mantenere tutto in orario con l'orologio di sistema non è una buona idea ed è irragionevole. Dispositivi diversi hanno diverse frequenze di aggiornamento, gestiranno i video a velocità diverse. Basta premere play e lasciarlo giocare. Se si finisce per essere secondi diversi, andare avanti e impostare currentTime, ma essere molto fiducioso di ciò che si è bufferizzato prima di farlo.

+0

Non sei sicuro se hai riscontrato il problema, ma se fornisci un file mp3 ad esempio da un nodo con socket in pacchetti di 2,7 secondi, ad esempio, il lettore si avvia come dovrebbe, ma se lo interrompi manualmente il buffer inizierà ad aumentare e quando suonerai di nuovo inizierà da dove l'hai fermato. Ciò fa sì che la riproduzione non sia sincronizzata con il flusso nodejs. Questo è ciò che succede se si lascia la riproduzione per diverse ore, si interrompe automaticamente a causa di glitch e il buffer inizia ad aumentare. –

+0

Il nodojs invia 2,7 secondi, aspetta che venga riprodotto e quindi invia il pacchetto successivo. Ma con l'aumento del buffer non è più possibile controllare se i dati trasmessi sono stati riprodotti o meno. Ho provato a inviare un "acknowledgement" che dice che il pacchetto è stato riprodotto in modo che il prossimo possa essere consegnato, ma ha altri problemi. Come l'interruzione della riproduzione. Quindi la domanda è di trasmettere dati e riprodurli immediatamente in modo continuo, per ore. –

+0

@KeyneViana Perché dovresti aspettare di inviare il prossimo pezzo di dati? Continua a inviarlo. Inoltre, non dovresti aspettare 2,7 secondi ... I frame MP3 possono essere piccoli come 576 campioni. – Brad