MediaTrack
reprezentuje ścieżkę multimediów, która może być strumieniem audio, strumieniem wideo lub tekstem (np. napisami). Aplikacja może grupować, stylizować i aktywować
ścieżki multimedialne.
Konfigurowanie ścieżki
Możesz skonfigurować ścieżkę i przypisać do niej unikalny identyfikator. Poniższy kod umożliwia utworzenie ścieżki tekstowej w języku angielskim, ścieżki tekstowej w języku francuskim i ścieżki audio w języku francuskim – każdy o własnym identyfikatorze:
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();
Grupowanie ścieżek
Możesz zgrupować wiele ścieżek w element multimedialny reprezentowany przez MediaInfo
.
Wystąpienie MediaInfo
pobiera tablicę ścieżek i agreguje inne informacje o elemencie multimedialnym.
Na podstawie przykładu Twoja aplikacja może dodać te 3 ścieżki multimediów do elementu multimedialnego, przesyłając ich listę do MediaInfo.Builder.setMediaTracks(List)
.
Aplikacja musi w ten sposób powiązać ścieżki w elemencie MediaInfo
, zanim załaduje multimedia do odbiornika.
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();
Usuń ścieżki
Aby usunąć wszystkie ścieżki z bieżącego nośnika (np. wyłączyć 3 napisy w przykładzie), wywołaj MediaInfo.Builder.setMediaTracks(List)
i przekaż pustą listę identyfikatorów.
Aktualizowanie ścieżek
Aplikacja może aktywować co najmniej jedną ścieżkę powiązaną z elementem multimedialnym (po załadowaniu multimediów), wywołując metodę RemoteMediaClient.setActiveMediaTracks(long[])
i przekazując identyfikatory ścieżek do aktywacji. W tym przykładzie aktywujemy
francuskie napisy i dźwięk w języku francuskim:
// 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()); } });
Stylizowanie ścieżek tekstowych
TextTrackStyle
zawiera informacje o stylu ścieżki tekstowej. Po utworzeniu lub zaktualizowaniu istniejącego już elementu TextTrackStyle możesz zastosować ten styl do aktualnie odtwarzanego elementu multimedialnego, wywołując metodę RemoteMediaClient.setTextTrackStyle
w ten sposób:
// 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()); } });
Twoja aplikacja powinna pozwalać użytkownikom na aktualizowanie stylu ścieżek tekstowych za pomocą ustawień systemu lub samej aplikacji. W Androidzie KitKat i nowszych możesz używać dostępnych w całym systemie ustawień napisów:
val textTrackStyle = TextTrackStyle.fromSystemSettings(context)
TextTrackStyle textTrackStyle = TextTrackStyle.fromSystemSettings(context);
W przypadku wersji starszych niż KitKat powyższe wywołanie zwróci obiekt, którego pola są niezdefiniowane. Dlatego musisz wypełnić te pola w aplikacji na podstawie wyborów użytkownika i pewnych wartości domyślnych. Styl można zmienić w następujących elementach stylu ścieżki tekstowej:
- Kolor i przezroczystość pierwszego planu (tekstu)
- kolor i przezroczystość tła;
- Typ krawędzi
- Kolor krawędzi
- Skala czcionki
- Rodzina czcionek
- Styl czcionki
Na przykład ustaw czerwony kolor tekstu i nieprzezroczystość 50% (80) w następujący sposób:
textTrackStyle.foregroundColor = Color.parseColor("#80FF0000")
textTrackStyle.setForegroundColor(Color.parseColor("#80FF0000"));
W wersji KitKat i nowszych zarejestruj aplikację, aby otrzymywać powiadomienia o zaktualizowaniu ustawień napisów dla całego systemu. W tym celu musisz wdrożyć w aplikacji CaptioningManager.CaptioningChangeListener
i zarejestrować ten detektor, wywołując:
CaptioningManager.addCaptioningChangeListener(yourChangeListener)
CaptioningManager.addCaptioningChangeListener(yourChangeListener);
Gdy aplikacja otrzyma połączenie z prośbą o zmianę ustawień napisów, musisz wyodrębnić nowe ustawienia i zaktualizować styl napisów do aktualnie odtwarzanych multimediów. Aby to zrobić, wywołaj metodę RemoteMediaClient.setTextTrackStyle
i przekaż nowy styl.
Odbieraj aktualizacje stanu
Jeśli z tym samym odbiorcą jest połączonych wielu nadawców, każdy z nich musi wiedzieć o zmianach u odbiorcy, nawet jeśli zmiany te zostały zainicjowane przez innych nadawców.
W tym celu aplikacja powinna zarejestrować RemoteMediaClient.Listener
i RemoteMediaClient.ProgressListener
.
Jeśli element TextTrackStyle
bieżących multimediów zmieni się, wszyscy powiązani nadawcy zostaną powiadomieni przez obu tych zarejestrowanych detektorów. W takim przypadku pakiet SDK odbiorcy nie sprawdza, czy nowy styl różni się od poprzedniego, i powiadamia o tym wszystkich połączonych nadawców. Jeśli jednak zmieni się stan aktywnych ścieżek, powiadomienia otrzymają tylko RemoteMediaClient.ProgressListener
u połączonych nadawców.
Spełniają wymagania CORS
Do adaptacyjnego streamingu multimediów Google Cast wymaga nagłówków CORS, ale nawet proste strumienie multimediów w formacie mp4 wymagają CORS, jeśli zawierają ścieżki. Jeśli chcesz włączyć ścieżki dla dowolnych multimediów, musisz włączyć CORS zarówno w przypadku strumieni ścieżek, jak i strumieni multimediów. Jeśli więc nie masz na serwerze nagłówków CORS dla prostych multimediów w formacie mp4, a potem dodasz prostą ścieżkę napisów, przesyłanie strumieniowe multimediów nie będzie możliwe, chyba że zaktualizujesz serwer tak, aby zawierał odpowiedni nagłówek CORS. Dodatkowo musisz zezwolić na przynajmniej te nagłówki: Content-Type, Accept-Encoding i Range. Ostatnie 2 nagłówki to dodatkowe nagłówki, które być może wcześniej nie były Ci potrzebne.