Используйте медиа-треки

MediaTrack представляет собой мультимедийную дорожку, которая может быть аудиопотоком, видеопотоком или текстом (например, субтитрами или субтитрами). Ваше приложение может группировать, стилизовать и активировать медиа-дорожки.

Настройка трека

Вы можете настроить трек и присвоить ему уникальный идентификатор. Следующий код создает текстовую дорожку на английском языке, текстовую дорожку на французском языке и аудиодорожку на французском языке, каждая из которых имеет свой собственный идентификатор:

Котлин
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()
Ява
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();

Группа треков

Вы можете сгруппировать несколько дорожек в медиа-элемент, который представлен MediaInfo . Экземпляр MediaInfo принимает массив дорожек и объединяет другую информацию об элементе мультимедиа. Опираясь на этот пример, ваше приложение может добавить эти три дорожки мультимедиа в элемент мультимедиа, передав список этих трех дорожек в MediaInfo.Builder.setMediaTracks(List) . Вашему приложению необходимо таким образом связать дорожки в MediaInfo , прежде чем оно загрузит медиафайл в приемник.

Котлин
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()
Ява
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();

Удалить треки

Чтобы удалить все дорожки из текущего мультимедиа (например, отключить три субтитра в примере), вызовите MediaInfo.Builder.setMediaTracks(List) и передайте пустой список идентификаторов.

Обновить треки

Ваше приложение может активировать одну или несколько дорожек, которые были связаны с элементом мультимедиа (после загрузки мультимедиа), вызвав RemoteMediaClient.setActiveMediaTracks(long[]) и передав идентификаторы дорожек, которые необходимо активировать. В этом примере активируются французские субтитры и французское аудио:

Котлин
// 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
                    )
                }
    })
Ява
// 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());
        }
    });

Стиль текстовых дорожек

TextTrackStyle инкапсулирует информацию о стиле текстовой дорожки. После создания или обновления существующего TextTrackStyle вы можете применить этот стиль к воспроизводимому в данный момент элементу мультимедиа, вызвав RemoteMediaClient.setTextTrackStyle , например:

Котлин
// 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
                    )
                }
    })
Ява
remoteMediaClient.setTextTrackStyle(style)
    .setResultCallback(mediaChannelResult -> {
        if (!mediaChannelResult.getStatus().isSuccess()) {
            Log.e(TAG, "Failed to set the style, status code: " +
                    mediaChannelResult.getStatus().getStatusCode());
        }
    });

Ваше приложение должно позволять пользователям обновлять стиль текстовых дорожек, используя настройки, предоставленные системой или самим приложением. В Android KitKat и более поздних версиях вы можете использовать общесистемные настройки субтитров, предоставляемые платформой:

Котлин
val textTrackStyle = TextTrackStyle.fromSystemSettings(context)
Ява
TextTrackStyle textTrackStyle = TextTrackStyle.fromSystemSettings(context);

Для версий до KitKat приведенный выше вызов вернет объект, поля которого не определены, поэтому вам необходимо заполнить эти поля в вашем приложении на основе выбора пользователя и некоторых значений по умолчанию. Вы можете стилизовать следующие элементы стиля текстовой дорожки:

  • Цвет и непрозрачность переднего плана (текста)
  • Цвет фона и непрозрачность
  • Тип кромки
  • Цвет края
  • Масштаб шрифта
  • Семейство шрифтов
  • Стиль шрифта

Например, установите красный цвет текста (FF) с непрозрачностью 50 % (80) следующим образом:

Котлин
textTrackStyle.foregroundColor = Color.parseColor("#80FF0000")
Ява
textTrackStyle.setForegroundColor(Color.parseColor("#80FF0000"));

В KitKat и более поздних версиях вам следует зарегистрировать свое приложение, чтобы получать уведомления об обновлении общесистемных настроек скрытых субтитров. Для этого вам необходимо реализовать CaptioningManager.CaptioningChangeListener в своем приложении и зарегистрировать этот прослушиватель, вызвав:

Котлин
CaptioningManager.addCaptioningChangeListener(yourChangeListener)
Ява
CaptioningManager.addCaptioningChangeListener(yourChangeListener);

Когда ваше приложение получит обратный вызов об изменении настроек подписи, вам потребуется извлечь новые настройки и обновить стиль текстовой подписи для воспроизводимого в данный момент мультимедиа, вызвав RemoteMediaClient.setTextTrackStyle и передав новый стиль.

Получать обновления статуса

Когда к одному и тому же получателю подключено несколько отправителей, каждому отправителю важно знать об изменениях в получателе, даже если эти изменения были инициированы другими отправителями.

Для этого ваше приложение должно зарегистрировать RemoteMediaClient.Listener и RemoteMediaClient.ProgressListener .

Если TextTrackStyle текущего носителя изменится, все подключенные отправители будут уведомлены через оба зарегистрированных прослушивателя. В этом случае SDK получателя не проверяет, отличается ли новый стиль от предыдущего, и независимо от этого уведомляет всех подключенных отправителей. Однако если статус активных дорожек изменится, уведомление будет уведомлено только RemoteMediaClient.ProgressListener в подключенных отправителях.

Удовлетворение требований CORS

Для адаптивной потоковой передачи мультимедиа Google Cast требует наличия заголовков CORS , но даже для простых медиапотоков mp4 требуется CORS, если они включают треки. Если вы хотите включить треки для любого мультимедиа, вам необходимо включить CORS как для ваших потоков треков, так и для ваших медиапотоков. Таким образом, если у вас нет заголовков CORS для вашего простого медиафайла mp4 на вашем сервере, а затем вы добавляете простую дорожку субтитров, вы не сможете осуществлять потоковую передачу мультимедиа, пока не обновите свой сервер, включив в него соответствующий заголовок CORS. Кроме того, вам необходимо разрешить как минимум следующие заголовки: Content-Type, Accept-Encoding и Range. Обратите внимание, что последние два заголовка — это дополнительные заголовки, которые ранее вам, возможно, не были нужны.