Apps que usam a versão independente com.google.android.exoplayer2
no momento
biblioteca e androidx.media
precisam migrar para androidx.media3
. Usar
o script de migração para migrar arquivos de build do Gradle, Java e
Arquivos de origem do Kotlin e arquivos de layout XML do ExoPlayer
2.19.1
para o 1.1.1
do AndroidX Media3.
Visão geral
Antes de migrar, leia as seções a seguir para saber mais sobre os benefícios das novas APIs, as APIs que serão migradas e os pré-requisitos que o projeto do seu app precisa cumprir.
Por que migrar para o Jetpack Media3
- Ele é a nova página inicial do ExoPlayer, enquanto
com.google.android.exoplayer2
é descontinuada. - Acesse a API Player em vários componentes/processos com
MediaBrowser
/MediaController
. - Use os recursos estendidos dos recursos
MediaSession
eMediaController
. - Anuncie recursos de reprodução com controle de acesso detalhado.
- Simplifique seu app removendo
MediaSessionConnector
ePlayerNotificationManager
. - Compatível com versões anteriores das APIs de cliente media-compatibilidade
(
MediaBrowserCompat
/MediaControllerCompat
/MediaMetadataCompat
)
APIs de mídia para migrar para o AndroidX Media3
- ExoPlayer e extensões dele (link em inglês)
Isso inclui todos os módulos do projeto ExoPlayer legado, exceto o mediasession que foi descontinuado. Apps ou módulos, dependendo pacotes nocom.google.android.exoplayer2
podem ser migrados com script de migração. - MediaSessionConnector (dependendo do
androidx.media.*
pacotes deandroidx.media:media:1.4.3+
)
Remova oMediaSessionConnector
e use oandroidx.media3.session.MediaSession
. - MediaBrowserServiceCompat (dependendo do
androidx.media.*
pacotes deandroidx.media:media:1.4.3+
)
Migrar subclasses deandroidx.media.MediaBrowserServiceCompat
paraandroidx.media3.session.MediaLibraryService
e código usandoMediaBrowserCompat.MediaItem
aandroidx.media3.common.MediaItem
. - MediaBrowserCompat (dependendo do
android.support.v4.media.*
pacotes deandroidx.media:media:1.4.3+
)
Migre o código do cliente usandoMediaBrowserCompat
ouMediaControllerCompat
para usar oandroidx.media3.session.MediaBrowser
comandroidx.media3.common.MediaItem
.
Pré-requisitos
Verifique se o projeto está sob controle de origem
Verifique se é possível reverter com facilidade as alterações aplicadas pelas ferramentas de migração com script. Se você ainda não tem o projeto sob controle de origem, este é um bom momento começar com ele. Se, por algum motivo, você não quiser fazer isso, faça uma de backup do projeto antes de iniciar a migração.
Atualizar o app
Recomendamos atualizar seu projeto para usar o versão mais recente da biblioteca do ExoPlayer e remova quaisquer chamadas a métodos descontinuados. Se você pretende usar o script para a migração, você precisará corresponder ao para a qual você está atualizando com a versão manipulada pelo script.
Aumente a compileSdkVersion do app para pelo menos 32.
Faça upgrade do Gradle e do Plug-in do Android Studio para Gradle para uma versão recente. que funcione com as dependências atualizadas acima. Para instância:
- Versão do Plug-in do Android para Gradle: 7.1.0
- Gradle: versão 7.4
Substituir todas as instruções de importação curinga que usam um asterisco (*) e usar instruções de importação totalmente qualificadas: exclua o caractere curinga instruções de importação e usar o Android Studio para importar as instruções (F2 - Alt/Enter, F2 - Alt/Enter, ...).
Migrar de
com.google.android.exoplayer2.PlayerView
paracom.google.android.exoplayer2.StyledPlayerView
. Isso é necessário porque não há um equivalente paracom.google.android.exoplayer2.PlayerView
no AndroidX Media3.
Migrar o ExoPlayer com suporte a script
O script facilita a mudança do com.google.android.exoplayer2
para o novo
de módulos e pacotes em androidx.media3
. O script é aplicado
algumas verificações de validação no projeto e imprimirá avisos se ela falhar.
Caso contrário, ele aplica os mapeamentos de classes e pacotes renomeados no
recursos de um projeto do Gradle do Android escrito em Java ou Kotlin.
usage: ./media3-migration.sh [-p|-c|-d|-v]|[-m|-l [-x <path>] [-f] PROJECT_ROOT]
PROJECT_ROOT: path to your project root (location of 'gradlew')
-p: list package mappings and then exit
-c: list class mappings (precedence over package mappings) and then exit
-d: list dependency mappings and then exit
-l: list files that will be considered for rewrite and then exit
-x: exclude the path from the list of file to be changed: 'app/src/test'
-m: migrate packages, classes and dependencies to AndroidX Media3
-f: force the action even when validation fails
-v: print the exoplayer2/media3 version strings of this script
-h, --help: show this help text
Como usar o script de migração
Faça o download do script de migração (em inglês) na tag do projeto ExoPlayer no GitHub correspondente à versão para a qual você atualizou o aplicativo:
curl -o media3-migration.sh \ "https://raw.githubusercontent.com/google/ExoPlayer/r2.19.1/media3-migration.sh"
Torne o script executável:
chmod 744 media3-migration.sh
Execute o script com
--help
para saber mais sobre as opções.Execute o script com
-l
para listar o conjunto de arquivos selecionados para migração (use-f
para forçar a listagem sem avisos):./media3-migration.sh -l -f /path/to/gradle/project/root
Execute o script com
-m
para mapear pacotes, classes e módulos para a Media3. A execução do script com a opção-m
aplicará as alterações ao .- Parar no erro de validação sem fazer alterações
./media3-migration.sh -m /path/to/gradle/project/root
- Execução forçada
Se o script encontrar uma violação dos pré-requisitos, a migração poderá ser Forçado com a sinalização
-f
:./media3-migration.sh -m -f /path/to/gradle/project/root
# list files selected for migration when excluding paths
./media3-migration.sh -l -x "app/src/test/" -x "service/" /path/to/project/root
# migrate the selected files
./media3-migration.sh -m -x "app/src/test/" -x "service/" /path/to/project/root
Conclua estas etapas manuais depois de executar o script com a opção -m
:
- Verifique como o script mudou seu código: use uma ferramenta de diferenças e corrija
possíveis problemas. Considere registrar um bug se você achar que o script tem
problema geral que foi introduzido sem transmitir a opção
-f
). - Crie o projeto: use
./gradlew clean build
ou no Android O Studio, escolha Arquivo > Sync Project with Gradle Files, depois Build > Limpar projeto e Build > Recriar projeto (monitore seu build na "Build – Saída da versão" guia do Android Studio.
Etapas de acompanhamento recomendadas:
- Resolva a ativação de erros relacionados ao uso de APIs instáveis.
- Substituir chamadas de API descontinuadas: use a API de substituição sugerida. Mantenha o ponteiro do mouse sobre o aviso no Android Studio e consulte o JavaDoc. do símbolo obsoleto para saber o que usar em vez de uma determinada chamada.
- Classifique as instruções de importação: abra o projeto no Android Studio e, em seguida, clique com o botão direito do mouse em um nó de pasta de pacotes no visualizador do projeto e escolha Otimize as importações nos pacotes que contêm os arquivos de origem alterados.
Substitua MediaSessionConnector
por androidx.media3.session.MediaSession
.
No mundo legado do MediaSessionCompat
, o MediaSessionConnector
era
responsável por sincronizar o estado do player com o estado da sessão
e receber comandos de controladores que precisavam de delegação para os
os métodos do player de vídeo. Com o AndroidX Media3, isso é feito diretamente pelo MediaSession
.
sem precisar de um conector.
Remova todas as referências e o uso do MediaSessionConnector: se você usou o script automatizado para migrar classes e pacotes do ExoPlayer, depois a script provavelmente deixou seu código em um estado descompilável em relação o
MediaSessionConnector
que não pode ser resolvido. O Android Studio vai mostrar o código corrompido ao tentar criar ou iniciar o app.No arquivo
build.gradle
em que você mantém suas dependências, adicione um dependência de implementação para o módulo de sessão AndroidX Media3 e remova a dependência legada:implementation "androidx.media3:media3-session:1.4.0"
Substitua
MediaSessionCompat
porandroidx.media3.session.MediaSession
.No site de código em que você criou o
MediaSessionCompat
legado, useandroidx.media3.session.MediaSession.Builder
para criar umaMediaSession
. Passe o jogador para criar o criador de sessões.val player = ExoPlayer.Builder(context).build() mediaSession = MediaSession.Builder(context, player) .setSessionCallback(MySessionCallback()) .build()
Implemente
MySessionCallback
conforme exigido pelo app. Isso é opcional. Se você quer permitir que os controles adicionem itens de mídia ao player, implementarMediaSession.Callback.onAddMediaItems()
Ele atende diversas métodos de API legados que adicionam itens de mídia ao player para reprodução em um de maneira compatível com versões anteriores. Isso inclui métodosMediaController.set/addMediaItems()
do controle Media3, conforme bem como oTransportControls.prepareFrom*/playFrom*
métodos da API legada. Um exemplo de implementação deonAddMediaItems
pode ser encontradas noPlaybackService
do app de demonstração da sessão.Libere a sessão de mídia no site de código em que você destruiu a sessão antes da migração:
mediaSession?.run { player.release() release() mediaSession = null }
Funcionalidade MediaSessionConnector
na Media3
A tabela a seguir mostra as APIs Media3 que lidam com a funcionalidade
implementado anteriormente em MediaSessionConnector
.
MediaSessionConnector | AndroidX Media3 |
---|---|
CustomActionProvider |
MediaSession.Callback.onCustomCommand()/
MediaSession.setCustomLayout() |
PlaybackPreparer |
MediaSession.Callback.onAddMediaItems()
(prepare() é chamado internamente)
|
QueueNavigator |
ForwardingPlayer |
QueueEditor |
MediaSession.Callback.onAddMediaItems() |
RatingCallback |
MediaSession.Callback.onSetRating() |
PlayerNotificationManager |
DefaultMediaNotificationProvider/
MediaNotification.Provider |
Migrar MediaBrowserService
para MediaLibraryService
O AndroidX Media3 introduz MediaLibraryService
, que substitui a
MediaBrowserServiceCompat
. O JavaDoc de MediaLibraryService
e o super
MediaSessionService
fornecem uma boa introdução à API e
modelo de programação assíncrona do serviço.
O MediaLibraryService
é compatível com versões anteriores do
MediaBrowserService
. Um app cliente que está usando MediaBrowserCompat
ou
MediaControllerCompat
continua funcionando sem mudanças de código durante a conexão
para um MediaLibraryService
. Para um cliente, é transparente se o app é
usando um MediaLibraryService
ou um MediaBrowserServiceCompat
legado.
![Diagrama de componentes do app com serviços, atividades e apps externos.](https://developer.android.google.cn/static/media/images/overview.png?authuser=0000&hl=pt)
Para que a compatibilidade com versões anteriores funcione, é necessário registrar os dois serviços interfaces com seu serviço no
AndroidManifest.xml
. Dessa forma, o cliente encontra seu serviço pela interface de serviço necessária:<service android:name=".MusicService" android:exported="true"> <intent-filter> <action android:name="androidx.media3.session.MediaLibraryService"/> <action android:name="android.media.browse.MediaBrowserService" /> </intent-filter> </service>
No arquivo
build.gradle
em que você mantém suas dependências, adicione um dependência de implementação para o módulo de sessão AndroidX Media3 e remova a dependência legada:implementation "androidx.media3:media3-session:1.4.0"
Mude seu serviço para herdar de uma
MediaLibraryService
em vez deMediaBrowserService
Como dito antes, oMediaLibraryService
é compatível com oMediaBrowserService
. Da mesma forma, quanto mais ampla a API que o serviço for e oferecer aos clientes é a mesma. Portanto, é provável que um app possa manter a maior parte da lógica necessária para implementar oMediaBrowserService
. e adaptá-lo para o novoMediaLibraryService
.As principais diferenças em comparação com a versão legada
MediaBrowserServiceCompat
são os seguintes:Implemente os métodos do ciclo de vida do serviço:os métodos que precisam ser substituído no próprio serviço são
onCreate/onDestroy
, em que um aloca/libera a sessão da biblioteca, o player e outros do Google Cloud. Além dos métodos de ciclo de vida de serviço padrão, um aplicativo precisa substituironGetSession(MediaSession.ControllerInfo)
para retornar oMediaLibrarySession
que foi criado noonCreate
.Implementar MediaLibraryService.MediaLibrarySessionCallback: como criar uma sessão exige
MediaLibraryService.MediaLibrarySessionCallback
que implementa métodos reais da API do domínio. Em vez de substituir os métodos de API o serviço legado, você substituirá os métodos doMediaLibrarySession.Callback
.O callback é usado para criar o
MediaLibrarySession
:mediaLibrarySession = MediaLibrarySession.Builder(this, player, MySessionCallback()) .build()
Encontre a API completa da MediaLibrarySessionCallback na API na documentação do Google Cloud.
Implementar
MediaSession.Callback.onAddMediaItems()
: o callbackonAddMediaItems(MediaSession, ControllerInfo, List<MediaItem>)
atende vários métodos de API atuais e legados que adicionam itens de mídia ao player para reprodução de forma compatível com versões anteriores. Isso inclui métodosMediaController.set/addMediaItems()
do controle Media3, e osTransportControls.prepareFrom*/playFrom*
métodos da API legada. Um exemplo de implementação do callback pode podem ser encontradas naPlaybackService
do app de demonstração da sessão.O AndroidX Media3 está usando o
androidx.media3.common.MediaItem
. de MediaBrowserCompat.MediaItem e MediaMetadataCompat. Peças do código vinculado às classes legadas precisa ser alterado de acordo ou mapear para oMediaItem
da Media3.O modelo de programação assíncrona geral mudou para
Futures
em diferente da abordagemResult
removível doMediaBrowserServiceCompat
. A implementação do seu serviço pode retornar umListenableFuture
assíncrona em vez de remover um resultado ou retorna um Future imediato para retornar diretamente um valor.
Remoção do PlayerNotificationManager
O MediaLibraryService
oferece suporte a notificações de mídia automaticamente e o
PlayerNotificationManager
pode ser removido ao usar um MediaLibraryService
ou
MediaSessionService
.
Um app pode personalizar a notificação definindo uma
MediaNotification.Provider
em onCreate()
que substitui o
DefaultMediaNotificationProvider
. Em seguida, MediaLibraryService
se encarrega de
iniciando o serviço em primeiro plano, conforme necessário.
Ao substituir MediaLibraryService.updateNotification()
, um app pode continuar
propriedade plena de publicar uma notificação e iniciar/interromper o serviço em
em primeiro plano, conforme necessário.
Migrar código do cliente usando um MediaBrowser
Com o AndroidX Media3, um MediaBrowser
implementa o MediaController/Player
.
e podem ser usadas para controlar a reprodução de mídia além da navegação na mídia
biblioteca. Se você tivesse que criar um MediaBrowserCompat
e um
MediaControllerCompat
no mundo legado, você pode fazer o mesmo usando apenas
o MediaBrowser
na Media3.
Uma MediaBrowser
pode ser criada e aguardar a conexão com o
serviço que está sendo estabelecido:
scope.launch {
val sessionToken =
SessionToken(context, ComponentName(context, MusicService::class.java)
browser =
MediaBrowser.Builder(context, sessionToken))
.setListener(BrowserListener())
.buildAsync()
.await()
// Get the library root to start browsing the library.
root = browser.getLibraryRoot(/* params= */ null).await();
// Add a MediaController.Listener to listen to player state events.
browser.addListener(playerListener)
playerView.setPlayer(browser)
}
Dê uma olhada
Controlar a reprodução na sessão de mídia
para aprender a criar um MediaController
para controlar a reprodução no
plano de fundo.
Outras etapas e limpeza
Erros de API instável
Após a migração para a Media3, talvez você encontre erros de lint sobre usos instáveis da API.
Essas APIs são seguras para o uso, e os erros de lint são um resultado da nossa nova
de compatibilidade binária. Se você não precisar de binários rigorosos
esses erros podem ser suprimidos com segurança usando uma @OptIn
uma anotação.
Contexto
Nenhum ExoPlayer v1 ou v2 fornecia garantias rigorosas sobre a compatibilidade binária da biblioteca entre as versões subsequentes. A superfície da API do ExoPlayer é muito desde a concepção, para permitir que os aplicativos personalizem quase todos os aspectos do a reprodução. As versões subsequentes do ExoPlayer ocasionalmente introduziam o símbolo renomeações ou outras alterações interruptivas (por exemplo, novos métodos obrigatórios nas interfaces). Em na maioria dos casos essas falhas foram atenuadas com a introdução do novo símbolo além de descontinuar o símbolo antigo para algumas versões, para permitir que os desenvolvedores para migrar os usos, mas nem sempre isso foi possível.
Essas alterações interruptivas resultaram em dois problemas para os usuários do ExoPlayer v1. e v2:
- Um upgrade para a versão do ExoPlayer pode fazer com que a compilação do código seja interrompida.
- Um app que dependia do ExoPlayer diretamente e por meio de um intermediário tinha que garantir que as duas dependências fossem a mesma versão, caso contrário, as incompatibilidades binárias podem resultar em falhas na execução.
Melhorias na Media3
A Media3 garante a compatibilidade binária para um subconjunto da superfície da API. A
as partes que não garantem compatibilidade binária são marcadas com
@UnstableApi
. Para esclarecer essa distinção, o uso de imagens instáveis
Os símbolos da API geram um erro de lint, a menos que sejam anotados com @OptIn
.
Após migrar do ExoPlayer v2 para o Media3, você pode encontrar muitos erros de API erros de lint. Isso pode fazer parecer que a Media3 é "menos estável" do que o ExoPlayer v2. Esse não é o caso. O "instável" da API Media3 têm a mesma nível de estabilidade como toda a superfície da API do ExoPlayer v2, e o garantias de que a superfície da API Media3 estável não está disponível no ExoPlayer v2, tudo. A diferença é que um erro do lint agora alerta para os diferentes níveis de estabilidade.
Processar erros de lint de API instáveis
Consulte a seção de solução de problemas desses erros de lint para conferir detalhes sobre como
anotar os usos de Java e Kotlin de APIs instáveis com @OptIn
.
APIs descontinuadas
As chamadas para APIs descontinuadas aparecem com desconto no Android Estúdio. Recomendamos substituir essas chamadas pela alternativa apropriada. Passe o cursor sobre o símbolo para ver o JavaDoc que informa qual API usar.
![Captura de tela: como exibir o JavaDoc com a alternativa do método descontinuado](https://developer.android.google.cn/static/media/media3/exoplayer/images/deprecation.png?authuser=0000&hl=pt)
Exemplos de código e apps de demonstração
- App de demonstração da sessão AndroidX Media3 (dispositivos móveis e WearOS)
- Ações personalizadas
- Notificação da interface do sistema, MediaButton/BT
- Controle de mídia do Google Assistente
- UAMP: Android Media Player (branch media3) (dispositivos móveis, AutomotiveOS)
- Notificação da interface do sistema, MediaButton/BT, retomada da reprodução
- Controle de reprodução do Google Assistente/Wear OS
- AutomotiveOS: comando e login personalizados