Panoramica dell'architettura delle app multimediali

Questa sezione spiega come separare un'app di media player in un controller multimediale (per l'interfaccia utente) e in una sessione multimediale (per il player effettivo). Descrive due architetture di app multimediali: un design client/server adatto alle app audio e un design con singola attività per i video player. Mostra inoltre come fare in modo che le app multimediali rispondano ai controlli hardware e collaborino con altre app che utilizzano lo stream di output audio.

Player e UI

Un'applicazione multimediale che riproduce audio o video solitamente è composta da due parti:

  • Un player che accetta contenuti multimediali digitali e li visualizza come video e/o audio
  • Una UI con controlli di trasporto per eseguire il player e, facoltativamente, visualizzare lo stato

UI e player

In Android puoi creare il tuo player da zero oppure scegliere tra le seguenti opzioni:

  • La classe MediaPlayer fornisce la funzionalità di base per un player essenziale che supporta le origini dati e i formati audio/video più comuni.
  • ExoPlayer è una libreria open source basata su componenti di framework multimediali di livello inferiore come MediaCodec e AudioTrack. ExoPlayer supporta funzionalità ad alte prestazioni come DASH, che non sono disponibili in MediaPlayer. Puoi personalizzare il codice ExoPlayer, semplificando l'aggiunta di nuovi componenti. ExoPlayer può essere utilizzato solo con Android 4.1 e versioni successive.

Sessione multimediale e controller multimediale

Sebbene le API per l'interfaccia utente e il player possano essere arbitrarie, la natura dell'interazione tra le due parti è sostanzialmente la stessa per tutte le app di media player. Il framework Android definisce due classi, una sessione multimediale e un controller multimediale,che impongono una struttura ben definita per la creazione di un'app per il media player.

La sessione multimediale e il controller multimediale comunicano tra loro tramite callback predefiniti corrispondenti ad azioni standard del player (riproduzione, pausa, interruzione e così via), nonché chiamate personalizzate estensibili che puoi utilizzare per definire comportamenti speciali specifici della tua app.

controller-e-sessione

Sessione multimediale

Una sessione multimediale è responsabile di tutte le comunicazioni con il player. Nasconde l'API del player al resto dell'app. Il player viene chiamato solo dalla sessione multimediale che lo controlla.

La sessione mantiene una rappresentazione dello stato del player (in riproduzione/in pausa) e informazioni su ciò che è in riproduzione. Una sessione può ricevere callback da uno o più controller multimediali. In questo modo il player può essere controllato dall'interfaccia utente della tua app e dai dispositivi associati con Wear OS e Android Auto. La logica che risponde alle richiamate deve essere coerente. La risposta a un callback MediaSession deve essere la stessa, indipendentemente dall'app client che ha avviato il callback.

Controller multimediale

Un controller multimediale isola la UI. Il codice UI comunica solo con il controller multimediale, non con il player stesso. Il controller multimediale converte le azioni di controllo del trasporto in callback nella sessione multimediale. Riceve inoltre i callback dalla sessione multimediale ogni volta che lo stato della sessione cambia. Questo fornisce un meccanismo per aggiornare automaticamente l'interfaccia utente associata. Un controller multimediale può connettersi a una sola sessione multimediale alla volta.

Quando utilizzi un controller multimediale e una sessione multimediale, puoi eseguire il deployment di interfacce e/o player diversi durante il runtime. Puoi modificare l'aspetto e/o le prestazioni dell'app in modo indipendente, a seconda delle funzionalità del dispositivo su cui è in esecuzione.

Confronto tra app video e app audio

Durante la riproduzione di un video, sono coinvolti entrambi gli occhi e le orecchie. Durante la riproduzione di contenuti audio puoi ascoltare, ma puoi anche usare un'altra app contemporaneamente. C'è un design diverso per ogni caso d'uso.

App video

Un'app video ha bisogno di una finestra per visualizzare i contenuti. Per questo motivo un'app video viene generalmente implementata come una singola attività Android. La schermata in cui appare il video fa parte dell'attività.

attività del video player

App audio

Non è sempre necessario che l'interfaccia utente di un lettore audio sia visibile. Quando inizia la riproduzione dell'audio, il player può essere eseguito come attività in background. L'utente può passare a un'altra app e lavorare continuando ad ascoltare.

Per implementare questa struttura in Android, puoi creare un'app audio utilizzando due componenti: un'attività per l'interfaccia utente e un servizio per il player. Se l'utente passa a un'altra app, il servizio può essere eseguito in background. Considerando le due parti di un'app audio in componenti separati, ciascuna può essere eseguita in modo più efficiente da sola. In genere l'interfaccia utente ha vita breve rispetto a un player, che può essere eseguito a lungo senza UI.

Attività audio e BrowserService

La libreria di supporto offre due classi per implementare questo approccio client/server: MediaBrowserService e MediaBrowser. Il componente del servizio viene implementato come una sottoclasse di MediaBrowserService contenente la sessione multimediale e il relativo player. L'attività con la UI e il controller multimediale dovrebbe includere un elemento MediaBrowser, che comunica con MediaBrowserService.

L'utilizzo di MediaBrowserService consente ai dispositivi complementari (come Android Auto e Wear) di trovare facilmente la tua app, connettersi all'app, sfogliare i contenuti e controllare la riproduzione, senza accedere affatto all'attività nell'interfaccia utente della tua app. Di fatto, possono essere presenti più app collegate allo stesso MediaBrowserService contemporaneamente, ogni app con il proprio MediaController. Un'app che offre MediaBrowserService dovrebbe essere in grado di gestire più connessioni simultanee.

App multimediali e infrastruttura audio di Android

Un'app multimediale ben progettata deve essere "compatibile" con altre app che riproducono audio. Deve essere pronto per condividere il telefono e collaborare con altre app sul dispositivo che utilizzano l'audio. Dovrebbe inoltre rispondere ai controlli hardware del dispositivo.

gioca-con-gli-altri

Tutto questo comportamento è descritto nella sezione Controllo dell'uscita audio.

La libreria di supporti multimediali

La libreria media-compat contiene corsi utili per la creazione di app in grado di riprodurre audio e video. Queste classi sono compatibili con i dispositivi con Android 2.3 (livello API 9) e versioni successive. Inoltre, funzionano con altre funzionalità di Android per creare un'esperienza Android piacevole e familiare.

L'implementazione consigliata delle sessioni multimediali e dei controller multimediali sono le classi MediaSessionCompat e MediaControllerCompat, definite nella libreria di supporto media-compat. Sostituiscono le versioni precedenti delle classi MediaSession e MediaController introdotte in Android 5.0 (livello API 21). Le classi di compatibilità offrono le stesse funzionalità, ma semplificano lo sviluppo dell'app perché è sufficiente scrivere in un'unica API. La libreria si occupa della compatibilità con le versioni precedenti traducendo i metodi delle sessioni multimediali nei metodi equivalenti sulle versioni precedenti della piattaforma, se disponibili.

Se hai già un'app funzionante che utilizza i corsi precedenti, ti consigliamo di eseguire l'aggiornamento alle classi di compatibilità. Quando utilizzi le versioni compatibili, puoi rimuovere tutte le chiamate a registerMediaButtonReceiver() e qualsiasi metodo da RemoteControlClient.

Misurazione del rendimento

In Android 8.0 (livello API 26) e versioni successive, il metodo getMetrics() è disponibile per alcune classi multimediali. Restituisce un oggetto PersistableBundle contenente informazioni sulla configurazione e sul rendimento, espresse come mappa di attributi e valori. Il metodo getMetrics() è definito per queste classi multimediali:

Le metriche vengono raccolte separatamente per ogni istanza e vengono mantenute per tutta la durata dell'istanza. Se non ci sono metriche disponibili, il metodo restituisce null. Le metriche effettive restituite dipendono dalla classe.