Usar faixas de mídia

MediaTrack representa uma faixa de mídia, que pode ser um stream de áudio, vídeo ou texto (como legendas ou closed caption). Seu app pode agrupar, estilizar e ativar faixas de mídia.

Configurar uma música

Você pode configurar uma faixa e atribuir um ID exclusivo a ela. O código a seguir cria uma faixa de texto em inglês, uma em francês e uma em francês, cada uma com um ID próprio:

Kotlin
val englishSubtitle = MediaTrack.Builder(1 /* ID */, MediaTrack.TYPE_TEXT)
    .setName("English Subtitle")
    .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
    .setContentId("https://some-url/caption_en.vtt")
    /* language is required for subtitle type but optional otherwise */
    .setLanguage("en-US")
    .build()

val frenchSubtitle = MediaTrack.Builder(2, MediaTrack.TYPE_TEXT)
    .setName("French Subtitle")
    .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
    .setContentId("https://some-url/caption_fr.vtt")
    .setLanguage("fr")
    .build()

val frenchAudio = MediaTrack.Builder(3, MediaTrack.TYPE_AUDIO)
    .setName("French Audio")
    .setContentId("trk0001")
    .setLanguage("fr")
    .build()
Java
MediaTrack englishSubtitle = new MediaTrack.Builder(1 /* ID */,
MediaTrack.TYPE_TEXT)
  .setName("English Subtitle")
  .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
  .setContentId("https://some-url/caption_en.vtt")
  /* language is required for subtitle type but optional otherwise */
  .setLanguage("en-US")
  .build();

MediaTrack frenchSubtitle = new MediaTrack.Builder(2, MediaTrack.TYPE_TEXT)
  .setName("French Subtitle")
  .setSubtype(MediaTrack.SUBTYPE_SUBTITLES)
  .setContentId("https://some-url/caption_fr.vtt")
  .setLanguage("fr")
  .build();

MediaTrack frenchAudio = new MediaTrack.Builder(3, MediaTrack.TYPE_AUDIO)
  .setName("French Audio")
  .setContentId("trk0001")
  .setLanguage("fr")
  .build();

Faixas do grupo

Você pode agrupar várias faixas em um item de mídia, que é representado por MediaInfo. Uma instância de MediaInfo usa uma matriz de faixas e agrega outras informações sobre o item de mídia. Com base no exemplo, seu app pode adicionar essas três faixas de mídia a um item transmitindo uma lista dessas três faixas para MediaInfo.Builder.setMediaTracks(List). O app precisa associar faixas em um MediaInfo dessa maneira antes de carregar a mídia para o receptor.

Kotlin
val tracks: MutableList<MediaTrack> = ArrayList<MediaTrack>()
tracks.add(englishSubtitle)
tracks.add(frenchSubtitle)
tracks.add(frenchAudio)
val mediaInfo = MediaInfo.Builder(url)
    .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
    .setContentType(getContentType())
    .setMetadata(getMetadata())
    .setMediaTracks(tracks)
    .build()
Java
List tracks = new ArrayList();
tracks.add(englishSubtitle);
tracks.add(frenchSubtitle);
tracks.add(frenchAudio);
MediaInfo mediaInfo = MediaInfo.Builder(url)
  .setStreamType(MediaInfo.STREAM_TYPE_BUFFERED)
  .setContentType(getContentType())
  .setMetadata(getMetadata())
  .setMediaTracks(tracks)
  .build();

Remover faixas

Para remover todas as faixas da mídia atual (como desativar as três legendas no exemplo), chame MediaInfo.Builder.setMediaTracks(List) e transmita uma lista vazia de IDs.

Atualizar músicas

O app pode ativar uma ou mais faixas associadas ao item de mídia (depois que a mídia for carregada), chamando RemoteMediaClient.setActiveMediaTracks(long[]) e transmitindo os IDs das faixas a serem ativadas. Este exemplo ativa o subtítulo em francês e o áudio em francês:

Kotlin
// the ID for the French subtitle is '2' and for the French audio '3'
remoteMediaClient.setActiveMediaTracks(longArrayOf(2, 3))
    .setResultCallback(ResultCallback {
            mediaChannelResult: RemoteMediaClient.MediaChannelResult ->
                if (!mediaChannelResult.status.isSuccess) {
                    Log.e(TAG, "Failed with status code:" +
                            mediaChannelResult.status.statusCode
                    )
                }
    })
Java
// the ID for the French subtitle is '2' and for the French audio '3'
remoteMediaClient.setActiveMediaTracks(new long[]{2, 3})
    .setResultCallback(mediaChannelResult -> {
        if (!mediaChannelResult.getStatus().isSuccess()) {
            Log.e(TAG, "Failed with status code:" +
                    mediaChannelResult.getStatus().getStatusCode());
        }
    });

Estilizar faixas de texto

TextTrackStyle encapsula as informações de estilo de uma faixa de texto. Depois de criar ou atualizar um TextTrackStyle, você pode aplicar esse estilo ao item de mídia em reprodução chamando RemoteMediaClient.setTextTrackStyle desta forma:

Kotlin
// the ID for the French subtitle is '2' and for the French audio '3'
remoteMediaClient.setTextTrackStyle(style)
    .setResultCallback(ResultCallback {
            mediaChannelResult: RemoteMediaClient.MediaChannelResult ->
                if (!mediaChannelResult.status.isSuccess) {
                    Log.e(TAG, "Failed to set the style, status code: " +
                            mediaChannelResult.status.statusCode
                    )
                }
    })
Java
remoteMediaClient.setTextTrackStyle(style)
    .setResultCallback(mediaChannelResult -> {
        if (!mediaChannelResult.getStatus().isSuccess()) {
            Log.e(TAG, "Failed to set the style, status code: " +
                    mediaChannelResult.getStatus().getStatusCode());
        }
    });

O app precisa permitir que os usuários atualizem o estilo das faixas de texto usando as configurações fornecidas pelo sistema ou pelo próprio app. No Android KitKat e versões mais recentes, você pode usar as configurações de legenda do sistema fornecidas pelo framework:

Kotlin
val textTrackStyle = TextTrackStyle.fromSystemSettings(context)
Java
TextTrackStyle textTrackStyle = TextTrackStyle.fromSystemSettings(context);

Para versões anteriores ao KitKat, a chamada acima vai retornar um objeto com campos indefinidos. Portanto, é necessário preencher esses campos no app com base nas seleções do usuário e em alguns valores padrão. Você pode estilizar os seguintes elementos de estilo de faixa de texto:

  • Cor e opacidade do primeiro plano (texto)
  • Cor e opacidade de segundo plano
  • Tipo de borda
  • Cor da borda
  • Escala da fonte
  • Família de fontes
  • Estilo da fonte

Por exemplo, defina a cor do texto como vermelho (FF) com 50% de opacidade (80) da seguinte maneira:

Kotlin
textTrackStyle.foregroundColor = Color.parseColor("#80FF0000")
Java
textTrackStyle.setForegroundColor(Color.parseColor("#80FF0000"));

Nas versões KitKat e mais recentes, é necessário registrar seu app para receber uma notificação quando as configurações de legendas do sistema forem atualizadas. Para isso, é necessário implementar CaptioningManager.CaptioningChangeListener no app e registrar esse listener chamando:

Kotlin
CaptioningManager.addCaptioningChangeListener(yourChangeListener)
Java
CaptioningManager.addCaptioningChangeListener(yourChangeListener);

Quando o app receber um retorno de chamada informando que as configurações de legenda mudaram, será necessário extrair as novas configurações e atualizar o estilo da legenda de texto da mídia que está sendo reproduzida no momento, chamando RemoteMediaClient.setTextTrackStyle e transmitindo o novo estilo.

Receber atualizações de status

Quando vários remetentes estão conectados ao mesmo destinatário, é importante que cada remetente esteja ciente das mudanças no destinatário, mesmo que elas tenham sido iniciadas por outros remetentes.

Para isso, seu app precisa registrar um RemoteMediaClient.Listener e um RemoteMediaClient.ProgressListener.

Se o TextTrackStyle da mídia atual mudar, todos os remetentes conectados serão notificados pelos dois listeners registrados acima. Nesse caso, o SDK do receptor não verifica se o novo estilo é diferente do anterior e notifica todos os remetentes conectados. No entanto, se o status das faixas ativas mudar, apenas o RemoteMediaClient.ProgressListener nos remetentes conectados será notificado.

Atender aos requisitos do CORS

Para streaming de mídia adaptável, o Google Cast exige a presença de cabeçalhos CORS, mas até mesmo streams de mídia mp4 simples exigem CORS se incluem faixas. Se você quiser ativar as faixas para qualquer mídia, ative o CORS para os streams de faixas e de mídia. Portanto, se você não tiver cabeçalhos CORS disponíveis para sua mídia mp4 simples no servidor e adicionar uma faixa de legenda simples, não vai conseguir transmitir a mídia, a menos que atualize o servidor para incluir o cabeçalho CORS apropriado. Além disso, é necessário permitir pelo menos os seguintes cabeçalhos: Content-Type, Accept-Encoding e Range. Observe que os dois últimos cabeçalhos são cabeçalhos adicionais que podem não ter sido necessários anteriormente.