O Jetpack Media3 define uma interface Player
que descreve a funcionalidade básica.
para reprodução de arquivos de vídeo e áudio. ExoPlayer
é a implementação padrão.
da interface na Media3. Recomendamos usar o ExoPlayer, porque ele fornece uma
abrangente de recursos que abrangem a maioria dos casos de uso de reprodução e é
e personalizáveis para outros casos de uso. O ExoPlayer também
abstrai a fragmentação de dispositivo e SO para que seu código funcione de maneira consistente
em todo o ecossistema Android. O ExoPlayer inclui:
- Compatibilidade com playlists
- Suporte a uma variedade de streaming progressivo e adaptativo formatos
- Suporte para inserção de anúncios do lado do cliente e do servidor
- Suporte para reprodução protegida por DRM
Esta página guia você por algumas das principais etapas para criar uma reprodução e, para mais detalhes, consulte nossos guias completos sobre ExoPlayer da Media3:
Primeiros passos
Para começar, adicione uma dependência no ExoPlayer, na IU e nos módulos comuns do Jetpack Media3:
implementation "androidx.media3:media3-exoplayer:1.4.1" implementation "androidx.media3:media3-ui:1.4.1" implementation "androidx.media3:media3-common:1.4.1"
Dependendo do caso de uso, você também pode precisar de outros módulos da Media3,
como exoplayer-dash
para abrir transmissões no formato DASH.
Substitua 1.4.1
pela versão de sua preferência do
biblioteca. Consulte as notas da versão
para conferir a versão mais recente.
Como criar um player de mídia
Com a Media3, é possível usar a implementação incluída do Player
ExoPlayer
, ou crie sua própria implementação personalizada.
Como criar um ExoPlayer
A maneira mais simples de criar uma instância de ExoPlayer
é a seguinte:
Kotlin
val player = ExoPlayer.Builder(context).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build();
É possível criar seu player de mídia no método de ciclo de vida onCreate()
do
Activity
, Fragment
ou Service
onde ele reside.
O Builder
inclui
uma variedade de opções de personalização que podem ser do seu interesse, como:
setAudioAttributes()
para configurar o gerenciamento de seleção de áudiosetHandleAudioBecomingNoisy()
para configurar o comportamento de reprodução quando um dispositivo de saída de áudio estiver desconectadosetTrackSelector()
para configurar a seleção de faixa
A Media3 oferece um componente de interface PlayerView
que pode ser incluído no arquivo
arquivo de layout. Este componente encapsula um PlayerControlView
para reprodução
controles, SubtitleView
para exibir legendas e Surface
para renderização
vídeo.
Como preparar o player
Adicione itens de mídia a uma playlist para
a reprodução com métodos como
setMediaItem()
e addMediaItem()
.
Em seguida, chame prepare()
para
começar a carregar mídia e adquirir os recursos necessários.
Não siga essas etapas antes de o app estar em primeiro plano. Se as
jogador está em um Activity
ou Fragment
, isso significa preparar o jogador na
Método de ciclo de vida onStart()
no nível 24 da API e mais recentes ou no onResume()
Lifecycle no nível 23 da API e anteriores. Para um jogador que está em um Service
,
você pode prepará-lo em onCreate()
.
Controlar o player
Após a preparação do player, você pode controlar a reprodução chamando métodos no player, como:
play()
epause()
para iniciar e pausar a reproduçãoseekTo()
para buscar uma posição no item de mídia atualseekToNextMediaItem()
eseekToPreviousMediaItem()
para navegar pela playlist
Componentes da interface, como PlayerView
ou PlayerControlView
, serão atualizados
da maneira adequada quando vinculados a um jogador.
Solte o player
A reprodução pode exigir recursos com fornecimento limitado, como vídeos
por isso, é importante chamar release()
no seu player para liberar recursos quando ele não for mais necessário.
Se o player estiver em uma Activity
ou Fragment
, libere-o na
Método de ciclo de vida onStop()
no nível 24 da API e mais recentes ou no onPause()
no nível 23 da API e anteriores. Para um jogador que esteja em um Service
, é possível
lançaremos em onDestroy()
.
Gerenciar a reprodução com uma sessão de mídia
No Android, as sessões de mídia oferecem uma maneira padronizada de interagir com uma mídia um jogador através dos limites do processo. Como conectar uma sessão de mídia ao player permite que você anuncie sua reprodução de mídia externamente e receba a reprodução comandos de fontes externas, por exemplo, para integrar com controles de mídia do sistema em dispositivos móveis e grandes e dispositivos de tela.
Para usar sessões de mídia, adicione uma dependência ao módulo de sessão da Media3:
implementation "androidx.media3:media3-session:1.4.1"
Criar uma sessão de mídia
Você pode criar um MediaSession
após inicializar um player da seguinte maneira:
Kotlin
val player = ExoPlayer.Builder(context).build() val mediaSession = MediaSession.Builder(context, player).build()
Java
ExoPlayer player = new ExoPlayer.Builder(context).build(); MediaSession mediaSession = new MediaSession.Builder(context, player).build();
A Media3 sincroniza automaticamente o estado do Player
com o estado da
MediaSession
. Isso funciona com qualquer implementação de Player
, incluindo
ExoPlayer
, CastPlayer
ou um
implementação personalizada.
Conceder controle a outros clientes
Os apps clientes podem implementar um controlador de mídia.
para controlar a reprodução da sua sessão de mídia. Para receber essas solicitações, defina um
callback quando
criar seu MediaSession
.
Quando um controlador está prestes a se conectar à sua sessão de mídia, o
onConnect()
é chamado. Você pode usar o ControllerInfo
fornecido
para decidir se você quer aceitar
ou rejeitar
da solicitação. Confira um exemplo no app de demonstração Media3 Session (link em inglês).
Uma vez conectado, um controlador pode enviar comandos de reprodução para a sessão. A
sessão e delega esses comandos para o player. Reprodução e playlist
Os comandos definidos na interface Player
são processados automaticamente pelo
sessão.
Outros métodos de callback permitem que você lide, por exemplo, com solicitações de
comandos de reprodução personalizados
e modificando a playlist. Esses callbacks incluem um objeto ControllerInfo
para que você
determinar o controle de acesso de acordo com a solicitação.
Tocando mídia em segundo plano
Para continuar a tocar mídia quando o app não estiver em primeiro plano, por exemplo
para tocar músicas, audiolivros ou podcasts mesmo quando o usuário não tiver o app
aberto, seus Player
e MediaSession
precisam ser encapsulados em um
serviço em primeiro plano. A Media3 oferece
MediaSessionService
para essa finalidade.
Como implementar um MediaSessionService
Crie uma classe que estenda MediaSessionService
e instancie seu
MediaSession
no método de ciclo de vida onCreate()
.
Kotlin
class PlaybackService : MediaSessionService() { private var mediaSession: MediaSession? = null // Create your Player and MediaSession in the onCreate lifecycle event override fun onCreate() { super.onCreate() val player = ExoPlayer.Builder(this).build() mediaSession = MediaSession.Builder(this, player).build() } // Remember to release the player and media session in onDestroy override fun onDestroy() { mediaSession?.run { player.release() release() mediaSession = null } super.onDestroy() } }
Java
public class PlaybackService extends MediaSessionService { private MediaSession mediaSession = null; @Override public void onCreate() { super.onCreate(); ExoPlayer player = new ExoPlayer.Builder(this).build(); mediaSession = new MediaSession.Builder(this, player).build(); } @Override public void onDestroy() { mediaSession.getPlayer().release(); mediaSession.release(); mediaSession = null; super.onDestroy(); } }
No manifesto, a classe Service
com uma intent MediaSessionService
filtrar e solicitar a permissão FOREGROUND_SERVICE
para executar um primeiro plano
serviço:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaSessionService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Por fim, na classe que você criou, modifique o método onGetSession()
para controlar
acesso de cliente à sessão de mídia. Retorne um MediaSession
para aceitar o
solicitação de conexão ou retornar null
para rejeitar a solicitação.
Kotlin
// This example always accepts the connection request override fun onGetSession( controllerInfo: MediaSession.ControllerInfo ): MediaSession? = mediaSession
Java
@Override public MediaSession onGetSession(MediaSession.ControllerInfo controllerInfo) { // This example always accepts the connection request return mediaSession; }
Como se conectar à interface
Agora que sua sessão de mídia está em um Service
separado do Activity
ou
Fragment
em que a interface do player fica, você pode usar um MediaController
para vincular
e juntá-los. No método onStart()
da Activity
ou Fragment
com sua
interface, crie um SessionToken
para a MediaSession
e use o SessionToken
para criar um MediaController
. A criação de um MediaController
acontece
de forma assíncrona.
Kotlin
override fun onStart() { val sessionToken = SessionToken(this, ComponentName(this, PlaybackService::class.java)) val controllerFuture = MediaController.Builder(this, sessionToken).buildAsync() controllerFuture.addListener( { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()) }, MoreExecutors.directExecutor() ) }
Java
@Override public void onStart() { SessionToken sessionToken = new SessionToken(this, new ComponentName(this, PlaybackService.class)); ListenableFuture<MediaController> controllerFuture = new MediaController.Builder(this, sessionToken).buildAsync(); controllerFuture.addListener(() -> { // Call controllerFuture.get() to retrieve the MediaController. // MediaController implements the Player interface, so it can be // attached to the PlayerView UI component. playerView.setPlayer(controllerFuture.get()); }, MoreExecutors.directExecutor()) }
MediaController
implementa a interface Player
, então você pode usar a mesma
métodos, como play()
e pause()
, para controlar a reprodução. Semelhante a outro
, não se esqueça de liberar a MediaController
quando ela não estiver mais
necessários, como o método de ciclo de vida onStop()
de uma Activity
, chamando
MediaController.releaseFuture()
Publicar uma notificação
Os serviços em primeiro plano precisam publicar uma notificação enquanto estão ativos. Um
MediaSessionService
vai criar automaticamente
MediaStyle
notificação para
você na forma de um MediaNotification
.
Para fornecer uma notificação personalizada, crie um
MediaNotification.Provider
com DefaultMediaNotificationProvider.Builder
ou criando uma implementação personalizada da interface do provedor. Adicione seu
provedor ao seu MediaSession
com
setMediaNotificationProvider
.
Como anunciar sua biblioteca de conteúdo
Um MediaLibraryService
se baseia em um MediaSessionService
, permitindo que o cliente
para navegar pelo conteúdo de mídia fornecido pelo seu app. Os apps clientes implementam uma
MediaBrowser
para interagir
com seu MediaLibraryService
.
A implementação de um MediaLibraryService
é semelhante à implementação de uma
MediaSessionService
, exceto que, em onGetSession()
, você deve retornar uma
MediaLibrarySession
em vez de MediaSession
. Em comparação com um
MediaSession.Callback
, o MediaLibrarySession.Callback
inclui outros
métodos que permitem que um cliente de navegador navegue pelo conteúdo oferecido pelo seu
serviço de biblioteca.
De forma semelhante a MediaSessionService
, declare a MediaLibraryService
no seu
e solicitar a permissão FOREGROUND_SERVICE
para executar um primeiro plano
serviço:
<service
android:name=".PlaybackService"
android:foregroundServiceType="mediaPlayback"
android:exported="true">
<intent-filter>
<action android:name="androidx.media3.session.MediaLibraryService"/>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
O exemplo acima inclui um filtro de intent para o MediaLibraryService
e, para compatibilidade com versões anteriores, o MediaBrowserService
legado. A
o filtro de intent extra permite que apps clientes usem a API MediaBrowserCompat
.
reconhecer seu Service
.
Um MediaLibrarySession
permite exibir sua biblioteca de conteúdo em uma árvore.
com uma única raiz MediaItem
. Cada MediaItem
da árvore pode ter
qualquer número de nós MediaItem
filhos. É possível veicular uma raiz diferente
árvore diferente, com base na solicitação do app cliente. Por exemplo, a árvore que você
retornar a um cliente que procura uma lista de itens de mídia recomendados só pode
contêm a raiz MediaItem
e um único nível de nós MediaItem
filhos;
enquanto a árvore que você retorna para um aplicativo cliente diferente pode representar uma
biblioteca completa de conteúdo.
Como criar um MediaLibrarySession
Uma MediaLibrarySession
estende a API MediaSession
para adicionar APIs de navegação de conteúdo. Em comparação com
Callback MediaSession
,
o callback MediaLibrarySession
adiciona métodos como:
onGetLibraryRoot()
para quando um cliente solicita oMediaItem
raiz de uma árvore de conteúdoonGetChildren()
para quando um cliente solicita os filhos de umMediaItem
na árvore de conteúdo.onGetSearchResult()
para quando um cliente solicita resultados de pesquisa da árvore de conteúdo para um determinado consulta
Os métodos de callback relevantes vão incluir um LibraryParams
.
com sinais adicionais sobre o tipo de árvore de conteúdo que um app cliente
tem interesse.