Aggiungere controlli di riproduzione all'app

Un'app che riproduce contenuti multimediali richiede componenti dell'interfaccia utente per visualizzare contenuti multimediali e controllare la riproduzione. La libreria Media3 include un modulo UI che contiene diversi componenti dell'interfaccia utente. Per dipendere dal modulo UI, aggiungi la seguente dipendenza:

Kotlin

implementation("androidx.media3:media3-ui:1.4.1")

Alla moda

implementation "androidx.media3:media3-ui:1.4.1"

Il componente più importante è PlayerView, una visualizzazione per la riproduzione di contenuti multimediali. PlayerView mostra video, immagini, sottotitoli e copertine degli album durante la riproduzione, nonché i controlli di riproduzione.

PlayerView ha un metodo setPlayer per agganciare e sganciare (tramite null) le istanze di player.

PlayerView

L'elemento PlayerView può essere utilizzato sia per le riproduzioni video, di immagini che audio. Esegue il rendering di video e sottotitoli nel caso della riproduzione di video, bitmap per la riproduzione di immagini e può mostrare l'artwork incluso come metadati nei file audio. Puoi includerlo nei file di layout come qualsiasi altro componente dell'interfaccia utente. Ad esempio, un PlayerView può essere incluso con il seguente XML:

<androidx.media3.ui.PlayerView
    android:id="@+id/player_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    app:show_buffering="when_playing"
    app:show_shuffle_button="true"/>

Lo snippet riportato sopra indica che PlayerView fornisce diversi attributi. Questi attributi possono essere utilizzati per personalizzare il comportamento della visualizzazione, nonché il suo aspetto. La maggior parte di questi attributi ha metodi di impostazione corrispondenti, che possono essere utilizzati per personalizzare la visualizzazione in fase di esecuzione. La documentazione Javadoc di PlayerView elenca questi attributi e metodi setter in modo più dettagliato.

Una volta dichiarata la visualizzazione nel file di layout, puoi cercarla nel metodo onCreate dell'attività:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView = findViewById(R.id.player_view)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  // ...
  playerView = findViewById(R.id.player_view);
}

Una volta inizializzato, un player può essere collegato alla visualizzazione chiamando setPlayer:

Kotlin

// Instantiate the player.
val player = ExoPlayer.Builder(context).build()
// Attach player to the view.
playerView.player = player
// Set the media item to be played.
player.setMediaItem(mediaItem)
// Prepare the player.
player.prepare()

Java

// Instantiate the player.
player = new ExoPlayer.Builder(context).build();
// Attach player to the view.
playerView.setPlayer(player);
// Set the media item to be played.
player.setMediaItem(mediaItem);
// Prepare the player.
player.prepare();

Scegli un tipo di superficie

L'attributo surface_type di PlayerView ti consente di impostare il tipo di superficie utilizzata per la riproduzione dei video. Oltre ai valori spherical_gl_surface_view (che è un valore speciale per la riproduzione di video sferici) e video_decoder_gl_surface_view (per il rendering dei video utilizzando i renderer di estensioni), i valori consentiti sono surface_view, texture_view e none. Se la visualizzazione è solo per la riproduzione audio, è consigliabile utilizzare none per evitare di dover creare una piattaforma, in quanto questa operazione può essere costosa.

Se la visualizzazione riguarda la riproduzione di video normale, utilizza surface_view o texture_view. SurfaceView offre una serie di vantaggi per la riproduzione dei video rispetto a TextureView:

  • Riduzione significativa del consumo di energia su molti dispositivi.
  • Tempi dei fotogrammi più precisi, che si traducono in una riproduzione video più fluida.
  • Supporto per output video HDR di qualità superiore su dispositivi idonei.
  • Supporto per l'output sicuro durante la riproduzione di contenuti protetti da DRM.
  • La possibilità di visualizzare i contenuti video alla massima risoluzione del display su dispositivi Android TV che eseguono l'upscaling del livello dell'interfaccia utente.

Pertanto, se possibile, è preferibile utilizzare SurfaceView anziché TextureView. TextureView deve essere utilizzato solo se SurfaceView non soddisfa le tue esigenze. Ad esempio, prima di Android 7.0 (livello API 24), è necessario creare animazioni fluide o scorrere la superficie video, come descritto nelle note seguenti. In questo caso, è preferibile utilizzare TextureView solo quando SDK_INT è inferiore a 24 (Android 7.0) e SurfaceView negli altri casi.

Navigazione con D-pad su Android TV

Il telecomando di Android TV ha un controllo D-pad che invia comandi che arrivano come evento chiave a dispatchKeyEvent(KeyEvent) del tuo Activity. Questi devono essere delegati alla visualizzazione del player:

Kotlin

override fun dispatchKeyEvent(event: KeyEvent?): Boolean{
  return playerView.dispatchKeyEvent(event!!) || super.dispatchKeyEvent(event)
}

Java

@Override
public boolean dispatchKeyEvent(KeyEvent event) {
  return playerView.dispatchKeyEvent(event) || super.dispatchKeyEvent(event);
}

La richiesta di attivazione della visualizzazione del player è importante per navigare tra i controlli di riproduzione e saltare gli annunci. Valuta la possibilità di richiedere lo stato attivo in onCreate di Activity:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
  super.onCreate(savedInstanceState)
  // ...
  playerView.requestFocus()
  // ...
}

Java

@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // ...
    playerView.requestFocus();
    // ...
}

Se utilizzi Compose su Android TV, devi rendere AndroidView selezionabile e delegare l'evento passando il parametro del modificatore in AndroidView di conseguenza:

AndroidView(
  modifier = modifier
    .focusable()
    .onKeyEvent { playerView.dispatchKeyEvent(it.nativeKeyEvent) },
  factory = { playerView }
)

Sostituisci drawable

PlayerView utilizza PlayerControlView per visualizzare i controlli di riproduzione e la barra di avanzamento. Gli elementi drawable utilizzati da PlayerControlView possono essere sostituiti da elementi drawable con gli stessi nomi definiti nell'applicazione. Consulta il Javadoc PlayerControlView per un elenco dei drawable di controllo che possono essere sostituiti.

Ulteriore personalizzazione

Laddove sia richiesta una personalizzazione diversa da quella descritta sopra, ci aspettiamo che gli sviluppatori di app implementino i propri componenti UI anziché utilizzare quelli forniti dal modulo UI di Media3.