O ExoPlayer reproduz a maioria das transmissões ao vivo adaptáveis imediatamente, sem nenhum configuração do Terraform. Consulte a página Formatos compatíveis para mais detalhes.
As transmissões ao vivo adaptáveis oferecem uma janela de mídia disponível que é atualizada intervalos regulares para acompanhar o tempo real atual. Isso significa que a reprodução posição sempre estará em algum lugar nesta janela, na maioria dos casos próximo ao no momento em que o stream é produzido. A diferença entre o tempo real atual e a posição da reprodução são chamadas de compensação ao vivo.
Como detectar e monitorar reproduções ao vivo
Sempre que uma janela ativa for atualizada, instâncias de Player.Listener
registradas
vai receber um evento onTimelineChanged
. Você pode recuperar detalhes sobre o
a reprodução ao vivo atual consultando vários Player
e Timeline.Window
métodos, como listado abaixo e mostrado na figura a seguir.
Player.isCurrentWindowLive
indica se a mídia em reprodução no momento é uma transmissão ao vivo. Esse valor ainda será verdadeiro mesmo se a transmissão ao vivo tiver acabou.Player.isCurrentWindowDynamic
indica se a mídia em reprodução no momento o item ainda está sendo atualizado. Isso geralmente é verdade para transmissões ao vivo que são ainda não terminou. Esse sinalizador também é válido para transmissões que não são ao vivo em alguns casos de uso diferentes.Player.getCurrentLiveOffset
retorna o deslocamento entre o real atual. tempo de reprodução e a posição da reprodução (se disponível).Player.getDuration
retorna a duração da janela ativa atual.Player.getCurrentPosition
retorna a posição de reprodução em relação ao início da janela ativa.Player.getCurrentMediaItem
retorna o item de mídia atual, em queMediaItem.liveConfiguration
contém substituições fornecidas pelo app para o destino parâmetros de ajuste de deslocamento ao vivo e de ajuste em tempo real.Player.getCurrentTimeline
retorna a estrutura de mídia atual em umaTimeline
. OTimeline.Window
atual pode ser recuperado doTimeline
. usandoPlayer.getCurrentWindowIndex
eTimeline.getWindow
. Dentro doWindow
:Window.liveConfiguration
contém o deslocamento em tempo real desejado e o deslocamento em tempo real parâmetros de ajuste. Esses valores são baseados nas informações da mídia e todas as substituições fornecidas pelo app definidas emMediaItem.liveConfiguration
.Window.windowStartTimeMs
é o horário desde a Era Unix em que o a janela ativa é iniciada.Window.getCurrentUnixTimeMs
é a hora desde a Era Unix da em tempo real. Este valor pode ser corrigido por uma diferença conhecida no relógio entre o servidor e o cliente.Window.getDefaultPositionMs
é a posição na janela ativa em que o player iniciará a reprodução por padrão.
Buscando em transmissões ao vivo
Você pode procurar qualquer lugar dentro da janela ao vivo usando Player.seekTo
. A busca
a posição transmitida é relativa ao início da janela ativa. Por exemplo:
seekTo(0)
vai buscar o início da janela ativa. O jogador tentará
manter o mesmo deslocamento em tempo real da posição buscada após uma busca.
A janela ao vivo também tem uma posição padrão em que a reprodução precisa
começar. Essa posição geralmente fica próxima à borda ativa. Você pode procurar
para a posição padrão chamando Player.seekToDefaultPosition
.
interface de reprodução ao vivo
Os componentes de interface padrão do ExoPlayer mostram a duração da janela ativa e
a posição de reprodução atual dentro dele. Isso significa que a posição aparecerá
voltar sempre que a janela ao vivo for atualizada. Se você precisar de
por exemplo, mostrando o horário Unix ou o deslocamento atual, será possível
bifurcar PlayerControlView
e modificá-la para atender às suas necessidades.
Como configurar parâmetros de reprodução ao vivo
O ExoPlayer usa alguns parâmetros para controlar o deslocamento da posição da reprodução. da borda ao vivo e a faixa de velocidades de reprodução que pode ser usada para ajustar esse deslocamento.
O ExoPlayer recebe valores para esses parâmetros de três lugares, em ordem decrescente Ordem de prioridade (o primeiro valor encontrado é usado):
- De acordo com os valores
MediaItem
transmitidos paraMediaItem.Builder.setLiveConfiguration
. - Valores padrão globais definidos em
DefaultMediaSourceFactory
. - Valores lidos diretamente da mídia.
Kotlin
// Global settings. val player = ExoPlayer.Builder(context) .setMediaSourceFactory(DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build() // Per MediaItem settings. val mediaItem = MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build() ) .build() player.setMediaItem(mediaItem)
Java
// Global settings. ExoPlayer player = new ExoPlayer.Builder(context) .setMediaSourceFactory( new DefaultMediaSourceFactory(context).setLiveTargetOffsetMs(5000)) .build(); // Per MediaItem settings. MediaItem mediaItem = new MediaItem.Builder() .setUri(mediaUri) .setLiveConfiguration( new MediaItem.LiveConfiguration.Builder().setMaxPlaybackSpeed(1.02f).build()) .build(); player.setMediaItem(mediaItem);
Os valores de configuração disponíveis são:
targetOffsetMs
: o deslocamento desejado em tempo real. O jogador tentará obter próximo a esse deslocamento ao vivo durante a reprodução, se possível.minOffsetMs
: o deslocamento mínimo permitido em tempo real. Mesmo ao ajustar para as condições atuais da rede, o player não tentará ficar abaixo esse deslocamento durante a reprodução.maxOffsetMs
: o deslocamento máximo permitido em tempo real. Mesmo ao ajustar para as condições atuais da rede, o player não tentará passar esse deslocamento durante a reprodução.minPlaybackSpeed
: a velocidade mínima de reprodução que o player pode usar para reverter. ao tentar alcançar o deslocamento desejado em tempo real.maxPlaybackSpeed
: a velocidade máxima de reprodução que o player pode usar para atingir a velocidade máxima ao tentar alcançar o deslocamento desejado em tempo real.
Ajuste da velocidade do vídeo
Em uma transmissão ao vivo de baixa latência, o ExoPlayer ajusta o deslocamento ao vivo pela mudando levemente a velocidade do vídeo. O jogador tentará fazer a correspondência com o alvo deslocamento em tempo real fornecido pela mídia ou pelo app, mas também tentará reagir ao as condições de rede. Por exemplo, se o buffer ocorrer durante a reprodução, o player diminuirá um pouco a velocidade da reprodução para se afastar da transmissão ao vivo borda Se a rede se tornar estável o suficiente para permitir a reprodução perto do ao vivo novamente, o player acelerará a reprodução para voltar à deslocamento desejado em tempo real.
Se o ajuste automático da velocidade do vídeo não for desejado, ele pode ser desativado
definindo as propriedades minPlaybackSpeed
e maxPlaybackSpeed
como 1.0f
.
Da mesma forma, ele pode ser ativado para transmissões ao vivo de baixa latência. Para isso, configure esses
explicitamente a valores diferentes de 1.0f
. Consulte
seção de configuração acima para
mais detalhes sobre como essas propriedades podem ser definidas.
Como personalizar o algoritmo de ajuste da velocidade de reprodução
Se o ajuste de velocidade estiver ativado, uma LivePlaybackSpeedControl
definirá o que
ajustes são feitos. É possível implementar um modelo
LivePlaybackSpeedControl
ou para personalizar a implementação padrão, que é
DefaultLivePlaybackSpeedControl
. Em ambos os casos, é possível definir uma instância
a criação do player:
Kotlin
val player = ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( DefaultLivePlaybackSpeedControl.Builder().setFallbackMaxPlaybackSpeed(1.04f).build() ) .build()
Java
ExoPlayer player = new ExoPlayer.Builder(context) .setLivePlaybackSpeedControl( new DefaultLivePlaybackSpeedControl.Builder() .setFallbackMaxPlaybackSpeed(1.04f) .build()) .build();
Os parâmetros de personalização relevantes de DefaultLivePlaybackSpeedControl
são:
fallbackMinPlaybackSpeed
efallbackMaxPlaybackSpeed
: os valores mínimos e as velocidades máximas de reprodução que podem ser usadas para ajuste se nem a mídia nem aMediaItem
fornecida pelo app definem os limites.proportionalControlFactor
: controla a fluidez do ajuste de velocidade. Um com alto valor torna os ajustes mais repentinos e reativos, mas também mais propensos ser audível. Um valor menor resulta em uma transição mais suave entre velocidades, mas acabam ficando mais lentas.targetLiveOffsetIncrementOnRebufferMs
: este valor é adicionado ao destino deslocamento ao vivo sempre que ocorrer um buffering, para proceder com mais cautela. Para desativar esse recurso, defina o valor como 0.minPossibleLiveOffsetSmoothingFactor
: um fator de suavização exponencial que é usado para rastrear o mínimo possível de deslocamento ao vivo com base no mídia em buffer. Um valor muito próximo de 1 significa que a estimativa é mais cautelosa e pode levar mais tempo para se ajustar às condições de rede aprimoradas, enquanto um valor menor significa que a estimativa se ajustará mais rapidamente, com um risco maior de em execução em buffer.
BehindLiveWindowException e ERROR_CODE_CAMPAIGNS_LIVE_WINDOW
A posição de reprodução pode ficar atrás da janela ao vivo, por exemplo, se o player
estiver pausada ou armazenando em buffer por um período suficiente. Se isso acontecer,
a reprodução falhará e uma exceção com código de erro
ERROR_CODE_BEHIND_LIVE_WINDOW
será informado por meio de
Player.Listener.onPlayerError
. O código do aplicativo pode querer processar
retomando a reprodução na posição padrão. A PlayerActivity do
o app de demonstração exemplifica essa abordagem.
Kotlin
override fun onPlayerError(error: PlaybackException) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition() player.prepare() } else { // Handle other errors } }
Java
@Override public void onPlayerError(PlaybackException error) { if (error.errorCode == PlaybackException.ERROR_CODE_BEHIND_LIVE_WINDOW) { // Re-initialize player at the live edge. player.seekToDefaultPosition(); player.prepare(); } else { // Handle other errors } }