Cómo usar pistas multimedia

MediaTrack representa una pista multimedia, que puede ser una transmisión de audio, video o texto (como subtítulos). Tu app puede agrupar, diseñar y activar pistas multimedia.

Cómo configurar un segmento

Puedes configurar un segmento y asignarle un ID único. El siguiente código crea una pista de texto en inglés, una pista de texto en francés y una pista de audio en francés, cada uno con su propio ID:

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();

Pistas del grupo

Es posible agrupar varias pistas en un elemento multimedia, que se representa con MediaInfo Una instancia de MediaInfo toma un array de pistas y agrega otra información sobre el elemento multimedia. A partir del ejemplo, tu app puede agregar esas tres pistas de contenido multimedia a un archivo elemento pasando una lista de esas tres pistas a MediaInfo.Builder.setMediaTracks(List) Tu app debe asociar segmentos en un MediaInfo de esta manera antes de que se cargue. los medios al 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();

Quitar segmentos

Para eliminar todas las pistas del contenido multimedia actual (por ejemplo, desactivar las tres subtítulos en el ejemplo), llama MediaInfo.Builder.setMediaTracks(List) y pasar una lista vacía de IDs.

Actualizar segmentos

Tu app puede activar uno o más segmentos asociados con el contenido multimedia elemento (después de que se carga el contenido multimedia), llamando RemoteMediaClient.setActiveMediaTracks(long[]) y pasa los IDs de los segmentos que se activarán. En este ejemplo, se activa Subtítulos en francés y audio en 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());
        }
    });

Aplica estilo a las pistas de texto

TextTrackStyle Encapsula la información de estilo de una pista de texto. Después de crear o actualizar un TextTrackStyle existente, puedes aplicar ese estilo a la imagen que se está reproduciendo elemento multimedia llamando RemoteMediaClient.setTextTrackStyle: así:

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());
        }
    });

Tu app debe permitir que los usuarios actualicen el estilo de segmentos de texto, ya sea usando la configuración proporcionada por el sistema o por la propia aplicación. En Android KitKat y posteriores, puedes usar la configuración de subtítulos de todo el sistema que proporciona la en la nube:

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

Para las versiones anteriores a KitKat, la llamada anterior mostrará un objeto cuyo Los campos no están definidos, por lo que debes completarlos en tu app, según según las selecciones de los usuarios y algunos valores predeterminados. Puedes aplicarle estilo al siguiente texto elementos de estilo de seguimiento:

  • Color y opacidad en primer plano (texto)
  • Color de fondo y opacidad
  • Tipo de borde
  • Color de borde
  • Escala de fuente
  • Familia de fuentes
  • Estilo de fuente

Por ejemplo, establece el color del texto en rojo (FF) con un 50% de opacidad (80) de la siguiente manera:

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

En KitKat y en las versiones posteriores, debes registrar tu app para recibir una notificación. cuando se actualice la configuración de subtítulos en todo el sistema. Para ello, debes implementar CaptioningManager.CaptioningChangeListener en tu app y registra este objeto de escucha mediante una llamada al siguiente código:

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

Cuando la app recibe una devolución de llamada que indica que se modificó la configuración de subtítulos, necesitaremos extraer la nueva configuración y actualizar el estilo del texto leyenda para el contenido multimedia que se está reproduciendo actualmente llamando RemoteMediaClient.setTextTrackStyle y pasar el estilo nuevo.

Recibe actualizaciones de estado

Cuando se conectan varios remitentes al mismo receptor, es importante cada remitente para estar al tanto de los cambios en el receptor, incluso si estos se iniciaron desde otros remitentes.

Para ello, tu app debe registrar un RemoteMediaClient.Listener y un RemoteMediaClient.ProgressListener

Si el botón TextTrackStyle de los cambios multimedia actuales, se notificará a todos los remitentes conectados a través de los dos objetos de escucha registrados que se mencionan arriba. En este caso, el SDK del receptor no verifica si el diseño nuevo es diferente del anterior y notifica a todos los remitentes conectados independientemente. Sin embargo, si el estado de activo monitorea cambios, solo RemoteMediaClient.ProgressListener en Se notificará a los remitentes conectados.

Cumple con los requisitos de CORS

Para la transmisión de contenido multimedia adaptable, Google Cast requiere la presencia de Encabezados CORS, pero incluso mp4 simple Las transmisiones de contenido multimedia requieren CORS si incluyen pistas. Si quieres habilitar los segmentos Para cualquier contenido multimedia, debes habilitar el CORS para las transmisiones continuas de pistas y para el contenido multimedia. transmisiones continuas. Entonces, si no tienes encabezados CORS disponibles para tu contenido multimedia mp4 simple en tu servidor y luego agregas una pista de subtítulos simple, no podrás para transmitir tu contenido multimedia, a menos que actualices el servidor para que incluya Encabezado CORS. Además, debes permitir al menos los siguientes encabezados: Content-Type, Accept-Encoding y Range. Ten en cuenta que los dos últimos encabezados encabezados adicionales que quizás no necesitabas antes.