Notizie sui prodotti

Media3 1.9.0: novità

Lettura di 6 minuti
Kristina Simakova
Engineering Manager

È disponibile Media3 1.9.0. Oltre alle consuete correzioni di bug e ai miglioramenti delle prestazioni, l'ultima release contiene anche quattro moduli nuovi o in gran parte riscritti:

  • media3-inspector : estrai metadati e frame al di fuori della riproduzione
  • media3-ui-compose-material3 : crea un'interfaccia utente multimediale di base di Material3 Compose in pochi passaggi
  • media3-cast : gestisci automaticamente le transizioni tra le riproduzioni locali e quelle di Cast
  • media3-decoder-av1 : riproduzione AV1 coerente con il decoder di estensione riscritto basato sulla libreria dav1d

Abbiamo anche aggiunto miglioramenti alla gestione della cache e della memoria a PreloadManager e fornito diverse nuove semplificazioni di ExoPlayer, Transformer e MediaSession

Questa release ti offre anche il primo accesso sperimentale a CompositionPlayer per visualizzare in anteprima le modifiche ai contenuti multimediali.  


Continua a leggere per scoprire di più e, come sempre, consulta le note di rilascio complete per una panoramica esaustiva delle modifiche apportate a questa release.

Estrai metadati e frame al di fuori della riproduzione

In molti casi, potresti voler ispezionare i contenuti multimediali senza avviare la riproduzione. Ad esempio, potresti voler rilevare i formati che contiene o la sua durata oppure recuperare le miniature.

Il nuovo modulo media3-inspector combina tutte le utilità per ispezionare i contenuti multimediali senza riproduzione in un unico posto:

  • MetadataRetriever per leggere la durata, il formato e i metadati statici di un MediaItem.
  • FrameExtractor per ottenere frame o miniature da un elemento.
  • MediaExtractorCompat come sostituzione diretta della classe MediaExtractor della piattaforma Android, per ottenere informazioni dettagliate sugli esempi nel file.

MetadataRetriever e FrameExtractor seguono un semplice pattern AutoCloseable. Per maggiori dettagli, consulta le nostre nuove pagine della guida.

suspend fun extractThumbnail(mediaItem: MediaItem) {

  FrameExtractor.Builder(context, mediaItem).build().use {

    val thumbnail = frameExtractor.getThumbnail().await()

  } 

}

Crea un'interfaccia utente multimediale di base di Material3 Compose in pochi passaggi

Nelle release precedenti abbiamo iniziato a fornire codice connettore tra gli elementi dell'interfaccia utente di Compose e l'istanza del player. Con Media3 1.9.0, abbiamo aggiunto un nuovo modulo media3-ui-compose-material3 con pulsanti ed elementi di contenuti Material3 completamente stilizzati. Ti consentono di creare un'interfaccia utente multimediale in pochi passaggi, offrendo al contempo tutta la flessibilità necessaria per personalizzare lo stile. Se preferisci creare il tuo stile dell'interfaccia utente, puoi utilizzare i blocchi predefiniti che si occupano di tutta la logica di aggiornamento e connessione, in modo da doverti concentrare solo sulla progettazione dell'elemento dell'interfaccia utente. Consulta le nostre pagine della guida estesa per i moduli dell'interfaccia utente di Compose.

Stiamo ancora lavorando su altri componenti di Compose, come una barra di scorrimento predefinita, una sostituzione completa e pronta all'uso di PlayerView, nonché l'integrazione di sottotitoli e annunci.

@Composable
fun SimplePlayerUI(player: Player, modifier: Modifier = Modifier) {
  Column(modifier) {
    ContentFrame(player)  // Video surface and shutter logic
    Row (Modifier.align(Alignment.CenterHorizontally)) {                 
      SeekBackButton(player)   // Simple controls
      PlayPauseButton(player)
      SeekForwardButton(player)
    }
  }
}

 

image.png

Interfaccia utente del player di Compose semplice con elementi predefiniti

Gestisci automaticamente le transizioni tra le riproduzioni locali e quelle di Cast

Il CastPlayer nel modulo media3-cast è stato riscritto per gestire automaticamente le transizioni tra la riproduzione locale (ad esempio con ExoPlayer) e la riproduzione Cast remota.

Quando configuri MediaSession, crea semplicemente un CastPlayer intorno a ExoPlayer e aggiungi un MediaRouteButton all'interfaccia utente. Ecco fatto.

// MediaSession setup with CastPlayer 

val exoPlayer = ExoPlayer.Builder(context).build()

val castPlayer = CastPlayer.Builder(context).setLocalPlayer(exoPlayer).build()

val session = MediaSession.Builder(context, castPlayer).build()

// MediaRouteButton in UI 

@Composable fun UIWithMediaRouteButton() {

  MediaRouteButton()

}
image.png

Nuova integrazione di CastPlayer nell'app demo della sessione Media3

Riproduzione AV1 coerente con l'estensione riscritta basata su dav1d

La release 1.9.0 contiene un modulo di estensione AV1 completamente riscritto basato sulla popolare dav1d libreria. 

Come per tutti i moduli del decoder di estensione, tieni presente che è necessario eseguire la build dal codice sorgente  per raggruppare correttamente il codice nativo pertinente. Il raggruppamento di un decoder garantisce coerenza e supporto del formato su tutti i dispositivi, ma poiché esegue la decodifica nel tuo processo, è più adatto ai contenuti di cui ti puoi fidare. 

Integra la gestione della cache e della memoria in PreloadManager

Abbiamo migliorato anche PreloadManager. Ti consentiva già di precaricare i contenuti multimediali in memoria al di fuori della riproduzione e poi di trasferirli senza problemi a un player quando necessario. Sebbene sia abbastanza efficiente, dovevi comunque fare attenzione a non superare i limiti di memoria precaricando accidentalmente troppi contenuti. Con Media3 1.9.0, abbiamo aggiunto due funzionalità che rendono questa operazione molto più semplice e stabile:

  1. Supporto della cache : quando definisci la distanza di precaricamento, ora puoi scegliere PreloadStatus.specifiedRangeCached(0, 5000) come stato di destinazione per gli elementi precaricati. In questo modo, l'intervallo specificato verrà aggiunto alla cache sul disco anziché caricare i dati in memoria. In questo modo, puoi fornire un intervallo di elementi molto più ampio per il precaricamento, poiché quelli più lontani dall'elemento corrente non devono più occupare memoria. Tieni presente che per questa operazione è necessario impostare una Cache in DefaultPreloadManager.Builder.
  2. Gestione automatica della memoria – abbiamo anche aggiornato l'interfaccia LoadControl per gestire meglio il caso di precaricamento, in modo che ora tu possa impostare un limite massimo di memoria esplicito per tutti gli elementi precaricati in memoria. Il valore predefinito è 144 MB e puoi configurare il limite in DefaultLoadControl.Builder. DefaultPreloadManager interromperà automaticamente il precaricamento una volta raggiunto il limite e rilascerà automaticamente la memoria degli elementi a priorità inferiore, se necessario.

Affidati ai nuovi comportamenti predefiniti semplificati in ExoPlayer

Come sempre, abbiamo aggiunto anche molti miglioramenti incrementali a ExoPlayer. Per citarne solo alcuni:

  • Disattivazione e riattivazione dell'audio : avevamo già un metodo setVolume, ma ora abbiamo aggiunto i metodi mute e unmute per ripristinare facilmente il volume precedente senza doverlo tenere traccia.
  • Rilevamento del player bloccato : in alcuni rari casi, il player può bloccarsi in uno stato di buffering o riproduzione senza fare progressi, ad esempio a causa di problemi di codec o configurazioni errate. I tuoi utenti saranno infastiditi, ma tu non vedrai mai questi problemi nelle tue analisi. Per rendere questo aspetto più evidente, il player ora segnala un StuckPlayerException quando rileva uno stato di blocco.
  • Wakelock per impostazione predefinita : in precedenza, la gestione del wakelock era facoltativa, il che comportava casi limite difficili da trovare in cui l'avanzamento della riproduzione poteva essere ritardato di molto durante l'esecuzione in background. Ora questa funzionalità è facoltativa, quindi non devi preoccuparti e puoi anche rimuovere tutta la gestione manuale del wakelock durante la riproduzione.
  • Impostazione semplificata per la logica del pulsante CC : modificare TrackSelectionParameters per indicare "Attiva/disattiva i sottotitoli" è stato sorprendentemente difficile, quindi abbiamo aggiunto una semplice opzione booleana selectTextByDefault per questo caso d'uso.

Semplifica le preferenze dei pulsanti multimediali in MediaSession

Finora, la definizione delle preferenze per i pulsanti da visualizzare nel riquadro delle notifiche multimediali su Android Auto o WearOS richiedeva la definizione di comandi e pulsanti personalizzati, anche se volevi semplicemente attivare un metodo del player standard.

Media3 1.9.0 include una nuova funzionalità che semplifica notevolmente questa operazione: ora puoi definire le preferenze dei pulsanti multimediali con un comando del player standard, senza richiedere la gestione di comandi personalizzati.

session.setMediaButtonPreferences(listOf(
    CommandButton.Builder(CommandButton.ICON_FAST_FORWARD) // choose an icon
      .setDisplayName(R.string.skip_forward)
      .setPlayerCommand(Player.COMMAND_SEEK_FORWARD) // choose an action 
      .build()
))
image.png

Preferenze dei pulsanti multimediali con il pulsante di avanzamento rapido

CompositionPlayer per l'anteprima in tempo reale

La release 1.9.0 introduce CompositionPlayer con una nuova annotazione @ExperimentalApi. L'annotazione indica che è disponibile per la sperimentazione, ma è ancora in fase di sviluppo. 

CompositionPlayer è un nuovo componente delle API di modifica di Media3 progettato per l'anteprima in tempo reale delle modifiche ai contenuti multimediali. Basato sulla nota interfaccia Player di Media3, CompositionPlayer consente agli utenti di vedere le modifiche in azione prima di eseguire il commit al processo di esportazione. Utilizza lo stesso oggetto Composition che passeresti a Transformer per l'esportazione, semplificando il flusso di lavoro di modifica unificando il modello di dati per l'anteprima e l'esportazione.

Ti invitiamo a iniziare a utilizzare CompositionPlayer e a condividere il tuo feedback. Inoltre, tieni d'occhio i prossimi post e aggiornamenti della documentazione per maggiori dettagli.

InAppMuxer come muxer predefinito in Transformer

Transformer ora utilizza InAppMp4Muxer come muxer predefinito per la scrittura di file contenitori multimediali. Internamente, InAppMp4Muxer dipende dal modulo Muxer di Media3, fornendo un comportamento coerente in tutte le versioni dell'API. 

Tieni presente che, sebbene Transformer non utilizzi più MediaMuxer della piattaforma Android per impostazione predefinita, puoi comunque fornire FrameworkMuxer.Factory tramite setMuxerFactory se il tuo caso d'uso lo richiede.

Nuove API di regolazione della velocità

La release 1.9.0 semplifica le API di regolazione della velocità per la modifica dei contenuti multimediali. Abbiamo introdotto nuovi metodi direttamente in EditedMediaItem.Builder per controllare la velocità, rendendo l'API più intuitiva. Ora puoi modificare la velocità di una clip chiamando setSpeed(SpeedProvider provider) su EditedMediaItem.Builder:

val speedProvider = object : SpeedProvider {
    override fun getSpeed(presentationTimeUs: Long): Float {
        return speed
    }

    override fun getNextSpeedChangeTimeUs(timeUs: Long): Long {
        return C.TIME_UNSET
    }
}

EditedMediaItem speedEffectItem = EditedMediaItem.Builder(mediaItem)
    .setSpeed(speedProvider)
    .build()

Questo nuovo approccio sostituisce il metodo precedente di utilizzo di Effects#createExperimentalSpeedChangingEffects(), che abbiamo ritirato e che rimuoveremo in una release futura.

Introduzione dei tipi di tracce per EditedMediaItemSequence

Nella release 1.9.0, EditedMediaItemSequence richiede di specificare i tipi di tracce di output desiderati durante la creazione della sequenza. Questa modifica garantisce una gestione delle tracce più esplicita e robusta in tutta la composizione. 

Questa operazione viene eseguita tramite un nuovo costruttore EditedMediaItemSequence.Builder che accetta un insieme di tipi di tracce (ad es. C.TRACK_TYPE_AUDIO, C.TRACK_TYPE_VIDEO).

Per semplificare la creazione, abbiamo aggiunto nuovi metodi statici di utilità:

  • EditedMediaItemSequence.withAudioFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withVideoFrom(List<EditedMediaItem>)
  • EditedMediaItemSequence.withAudioAndVideoFrom(List<EditedMediaItem>)

Ti invitiamo a eseguire la migrazione al nuovo costruttore o ai metodi di utilità per definizioni di sequenze più chiare e affidabili.

Esempio di creazione di una sequenza solo video:

EditedMediaItemSequence videoOnlySequence =
    EditedMediaItemSequence.Builder(setOf(C.TRACK_TYPE_VIDEO))
        .addItem(editedMediaItem)
        .build()

Se riscontri bug o hai domande o richieste di funzionalità, contattaci tramite lo strumento di monitoraggio dei problemi di Media3. Restiamo in attesa della tua risposta.

Continua a leggere