ExoPlayer riproduce la maggior parte dei live streaming adattabili senza alcuna configurazione speciale. Per maggiori dettagli, consulta la pagina Formati supportati.
I live streaming adattivi offrono una finestra di contenuti multimediali disponibili che viene aggiornata a intervalli regolari per adattarsi all'evoluzione in tempo reale. Ciò significa che la posizione di riproduzione sarà sempre in questa finestra, nella maggior parte dei casi vicino al tempo reale corrente in cui viene prodotto lo stream. La differenza tra il tempo in tempo reale corrente e la posizione di riproduzione è chiamata offset dal live.
Rilevamento e monitoraggio delle riproduzioni in tempo reale
Ogni volta che una finestra in tempo reale viene aggiornata, le istanze Player.Listener
registrate riceveranno un evento onTimelineChanged
. Puoi recuperare i dettagli sulla riproduzione in diretta corrente eseguendo query su vari metodi Player
e Timeline.Window
, come elencato di seguito e mostrato nella figura seguente.
Player.isCurrentWindowLive
indica se l'elemento media attualmente in riproduzione è un live streaming. Questo valore rimane valido anche se il live streaming è terminato.Player.isCurrentWindowDynamic
indica se l'elemento multimediale attualmente in riproduzione è ancora in fase di aggiornamento. Questo è in genere il caso dei live streaming che non sono ancora terminati. Tieni presente che in alcuni casi questo flag è valido anche per i live streaming non in diretta.Player.getCurrentLiveOffset
restituisce l'offset tra il tempo reale corrente e la posizione di riproduzione (se disponibile).Player.getDuration
restituisce la lunghezza della finestra live corrente.Player.getCurrentPosition
restituisce la posizione di riproduzione rispetto all'inizio della finestra live.Player.getCurrentMediaItem
restituisce l'elemento multimediale corrente, doveMediaItem.liveConfiguration
contiene le sostituzioni fornite dall'app per i parametri di offset in diretta e di aggiustamento dell'offset in diretta target.Player.getCurrentTimeline
restituisce la struttura multimediale corrente in unTimeline
. L'Timeline.Window
corrente può essere recuperato dalTimeline
utilizzandoPlayer.getCurrentMediaItemIndex
eTimeline.getWindow
. All'interno diWindow
:Window.liveConfiguration
contiene i parametri di aggiustamento dell'offset live target e dell'offset live. Questi valori si basano sulle informazioni nei contenuti multimediali e sugli eventuali override forniti dall'app impostati inMediaItem.liveConfiguration
.Window.windowStartTimeMs
è il tempo dall'epoca Unix in cui inizia la finestra in diretta.Window.getCurrentUnixTimeMs
è il tempo trascorso dall'epoca Unix del tempo reale attuale. Questo valore può essere corretto da una differenza di orologio nota tra il server e il client.Window.getDefaultPositionMs
è la posizione nella finestra del live streaming in cui il player avvia la riproduzione per impostazione predefinita.
Avanzamento nei live streaming
Puoi andare a qualsiasi punto all'interno della finestra in diretta utilizzando Player.seekTo
. La posizione di ricerca passata è relativa all'inizio dell'intervallo live. Ad esempio, seekTo(0)
cercherà fino all'inizio della finestra pubblicata. Dopo una ricerca, il player cercherà di mantenere lo stesso offset in tempo reale della posizione di ricerca.
La finestra live ha anche una posizione predefinita in cui dovrebbe
iniziare la riproduzione. Questa posizione si trova in genere vicino al bordo attivo. Puoi andare alla posizione predefinita chiamando Player.seekToDefaultPosition
.
Interfaccia utente della riproduzione in diretta
I componenti dell'interfaccia utente predefiniti di ExoPlayer mostrano la durata della finestra live e la posizione di riproduzione corrente al suo interno. Ciò significa che la posizione sembrerà fare un salto all'indietro ogni volta che la finestra in tempo reale viene aggiornata. Se hai bisogno di un comportamento diverso, ad esempio per mostrare il tempo Unix o l'offset in tempo reale corrente, puoi creare un fork di PlayerControlView
e modificarlo in base alle tue esigenze.
Configurare i parametri di riproduzione dal vivo
ExoPlayer utilizza alcuni parametri per controllare l'offset della posizione di riproduzione dall'edge live e l'intervallo di velocità di riproduzione che possono essere utilizzati per regolare questo offset.
ExoPlayer recupera i valori per questi parametri da tre posizioni, in ordine di priorità decrescente (viene utilizzato il primo valore trovato):
- Per i valori
MediaItem
passati aMediaItem.Builder.setLiveConfiguration
. - Valori predefiniti globali impostati su
DefaultMediaSourceFactory
. - Valori letti direttamente dai contenuti multimediali.
Kotlin
// Global settings. val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build() // Per MediaItem settings. val mediaItem = MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build() ) .build() player.setMediaItem(mediaItem)
Java
// Global settings. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build(); // Per MediaItem settings. MediaItem mediaItem = new MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( new MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build()) .build(); player.setMediaItem(mediaItem);
I valori di configurazione disponibili sono:
targetOffsetMs
: l'offset dal live target. Se possibile, il player cercherà di avvicinarsi a questo offset in tempo reale durante la riproduzione.minOffsetMs
: la differenza minima consentita in tempo reale. Anche se l'offset viene modificato in base alle condizioni di rete attuali, il player non tenterà di scendere al di sotto di questo offset durante la riproduzione.maxOffsetMs
: la differenza massima consentita in tempo reale. Anche se regoli l'offset in base alle condizioni di rete attuali, il player non tenterà di superare questo offset durante la riproduzione.minPlaybackSpeed
: la velocità di riproduzione minima che il player può utilizzare come opzione di riserva quando tenta di raggiungere lo spostamento in tempo reale target.maxPlaybackSpeed
: la velocità di riproduzione massima che il player può utilizzare per mettersi al passo quando tenta di raggiungere lo spostamento dal live target.
Regolazione della velocità di riproduzione
Quando riproduci un live streaming a bassa latenza, ExoPlayer regola l'offset in tempo reale modificando leggermente la velocità di riproduzione. Il player cercherà di corrispondere all'offset in tempo reale del target fornito dai contenuti multimediali o dall'app, ma cercherà anche di reagire alle condizioni mutevoli della rete. Ad esempio, se si verificano nuovi buffering durante la riproduzione, il player rallenta leggermente la riproduzione per allontanarsi dal live streaming. Se la rete diventa sufficientemente stabile da supportare di nuovo la riproduzione più vicino al live streaming, il player accelera la riproduzione per tornare all'offset dal live streaming target.
Se non vuoi che la velocità di riproduzione venga regolata automaticamente, puoi disattivarla impostando le proprietà minPlaybackSpeed
e maxPlaybackSpeed
su 1.0f
.
Analogamente, può essere attivato per i live streaming con latenza non bassa impostandoli esplicitamente su valori diversi da 1.0f
. Per maggiori dettagli su come impostare queste proprietà, consulta la sezione sulla configurazione sopra.
Personalizzazione dell'algoritmo di regolazione della velocità di riproduzione
Se la regolazione della velocità è attivata, un LivePlaybackSpeedControl
definisce gli aggiustamenti da apportare. È possibile implementare un valore personalizzatoLivePlaybackSpeedControl
o personalizzare l'implementazione predefinita, ovveroDefaultLivePlaybackSpeedControl
. In entrambi i casi, è possibile impostare un'istanza durante la compilazione del player:
Kotlin
val player = ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( DefaultLivePlaybackSpeedControl.Builder().setFallbackMaxPlaybackSpeed(1.04f).build() ) .build()
Java
ExoPlayer player = new ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( new DefaultLivePlaybackSpeedControl.Builder() .setFallbackMaxPlaybackSpeed(1.04f) .build()) .build();
I parametri di personalizzazione pertinenti di DefaultLivePlaybackSpeedControl
sono:
fallbackMinPlaybackSpeed
efallbackMaxPlaybackSpeed
: le velocità di riproduzione minime e massime che possono essere utilizzate per la regolazione se né i contenuti multimediali né ilMediaItem
fornito dall'app definiscono i limiti.proportionalControlFactor
: controlla la fluidità della regolazione della velocità. Un valore elevato rende gli aggiustamenti più improvvisi e reattivi, ma anche più probabili di essere udibili. Un valore inferiore consente una transizione più fluida tra le velocità, ma al costo di essere più lenta.targetLiveOffsetIncrementOnRebufferMs
: questo valore viene aggiunto all'offset dal vivo target ogni volta che si verifica un nuovo buffering, per procedere con maggiore cautela. Questa funzionalità può essere disattivata impostando il valore su 0.minPossibleLiveOffsetSmoothingFactor
: un fattore di smorzamento esponenziale utilizzato per monitorare l'offset in tempo reale minimo possibile in base ai contenuti multimediali attualmente memorizzati nella cache. Un valore molto vicino a 1 indica che la stima è più prudente e potrebbe richiedere più tempo per adattarsi al miglioramento delle condizioni di rete, mentre un valore più basso significa che la stima si adegua più rapidamente, con un rischio maggiore di immettere rebuffer.
dietroLiveWindowException e ERROR_CODE_ {8/}_LIVE_WINDOW
La posizione di riproduzione potrebbe rimanere indietro rispetto alla finestra del live streaming, ad esempio se il player
è in pausa o è in buffering per un periodo di tempo sufficientemente lungo. In questo caso, la riproduzione non andrà a buon fine e verrà segnalata un'eccezione con il codice di errore ERROR_CODE_BEHIND_LIVE_WINDOW
tramite Player.Listener.onPlayerError
. Il codice dell'applicazione potrebbe gestire questi errori riprendendo la riproduzione dalla posizione predefinita. PlayerActivity dell'app dimostrativa è un esempio di questo approccio.
Kotlin
override fun onPlayerError(error: PlaybackException) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition() player.prepare() } else { // Handle other errors } }
Java
@Override public void onPlayerError(PlaybackException error) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition(); player.prepare(); } else { // Handle other errors } }