Przerwy na reklamę
Pakiet SDK nadawcy na Androida obsługuje przerwy na reklamę i reklamy towarzyszące w danym strumieniu multimediów.
Więcej informacji o tym, jak działają przerwy na reklamę, znajdziesz w artykule Omówienie przerw na reklamę w odbiorniku internetowym.
Przerwy można określać zarówno w aplikacji nadawcy, jak i odbiorcy, ale zalecamy, aby robić to w odbiorniku internetowym i odbiorniku Android TV, aby zachować spójne działanie na różnych platformach.
Na Androidzie określ przerwy na reklamę w poleceniu wczytania za pomocą
AdBreakClipInfo
i AdBreakInfo:
val breakClip1: AdBreakClipInfo = AdBreakClipInfo.Builder("bc0") .setTitle("Clip title") .setPosterUrl("https://www.some.url") .setDuration(60000) .setWhenSkippableInMs(5000) // Set this field so that the ad is skippable .build() val breakClip2: AdBreakClipInfo = … val breakClip3: AdBreakClipInfo = … val break1: AdBreakClipInfo = AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000) .setId("b0") .setBreakClipIds({"bc0","bc1","bc2"}) … .build() val mediaInfo: MediaInfo = MediaInfo.Builder() … .setAdBreaks({break1}) .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .build() val mediaLoadRequestData: MediaLoadRequestData = MediaInfo.Builder() … .setMediaInfo(mediaInfo) .build() remoteMediaClient.load(mediaLoadRequestData)
AdBreakClipInfo breakClip1 = new AdBreakClipInfo.Builder("bc0") .setTitle("Clip title") .setPosterUrl("https://www.some.url") .setDuration(60000) .setWhenSkippableInMs(5000) // Set this field so that the ad is skippable .build(); AdBreakClipInfo breakClip2 = … AdBreakClipInfo breakClip3 = … AdBreakInfo break1 = new AdBreakInfo.Builder(/* playbackPositionInMs= */ 10000) .setId("b0") .setBreakClipIds({"bc0","bc1","bc2"}) … .build(); MediaInfo mediaInfo = new MediaInfo.Builder() … .setAdBreaks({break1}) .setAdBreakClips({breakClip1, breakClip2, breakClip3}) .build(); MediaLoadRequestData mediaLoadRequestData = new MediaInfo.Builder() … .setMediaInfo(mediaInfo) .build(); remoteMediaClient.load(mediaLoadRequestData);
Dodawanie działań niestandardowych
Aplikacja nadawcy może rozszerzyć
MediaIntentReceiver
, aby obsługiwać działania niestandardowe lub zastępować jego działanie. Jeśli masz własną implementację MediaIntentReceiver, musisz dodać ją do pliku manifestu, a także ustawić jej nazwę w CastMediaOptions. Ten przykład zawiera działania niestandardowe, które zastępują przełączanie odtwarzania multimediów na urządzeniu zdalnym, naciśnięcie przycisku multimediów i inne typy działań.
// In AndroidManifest.xml
<receiver android:name="com.example.MyMediaIntentReceiver" />
// In your OptionsProvider var mediaOptions = CastMediaOptions.Builder() .setMediaIntentReceiverClassName(MyMediaIntentReceiver::class.java.name) .build() // Implementation of MyMediaIntentReceiver internal class MyMediaIntentReceiver : MediaIntentReceiver() { override fun onReceiveActionTogglePlayback(currentSession: Session) { } override fun onReceiveActionMediaButton(currentSession: Session, intent: Intent) { } override fun onReceiveOtherAction(context: Context?, action: String, intent: Intent) { } }
// In your OptionsProvider CastMediaOptions mediaOptions = new CastMediaOptions.Builder() .setMediaIntentReceiverClassName(MyMediaIntentReceiver.class.getName()) .build(); // Implementation of MyMediaIntentReceiver class MyMediaIntentReceiver extends MediaIntentReceiver { @Override protected void onReceiveActionTogglePlayback(Session currentSession) { } @Override protected void onReceiveActionMediaButton(Session currentSession, Intent intent) { } @Override protected void onReceiveOtherAction(Context context, String action, Intent intent) { } }
Dodawanie kanału niestandardowego
Aby aplikacja nadawcy mogła komunikować się z aplikacją odbiorcy, musi utworzyć kanał niestandardowy. Nadawca może używać kanału niestandardowego do wysyłania wiadomości tekstowych do odbiorcy. Każdy kanał niestandardowy jest definiowany przez unikalną
przestrzeń nazw i musi zaczynać się od prefiksu urn:x-cast:, np.
urn:x-cast:com.example.custom. Możesz mieć wiele kanałów niestandardowych, z których każdy ma unikalną przestrzeń nazw. Aplikacja odbiorcy może też
wysyłać i odbierać wiadomości
przy użyciu tej samej przestrzeni nazw.
Kanał niestandardowy jest implementowany za pomocą
Cast.MessageReceivedCallback
interfejsu:
class HelloWorldChannel : MessageReceivedCallback { val namespace: String get() = "urn:x-cast:com.example.custom" override fun onMessageReceived(castDevice: CastDevice, namespace: String, message: String) { Log.d(TAG, "onMessageReceived: $message") } }
class HelloWorldChannel implements Cast.MessageReceivedCallback { public String getNamespace() { return "urn:x-cast:com.example.custom"; } @Override public void onMessageReceived(CastDevice castDevice, String namespace, String message) { Log.d(TAG, "onMessageReceived: " + message); } }
Gdy aplikacja nadawcy połączy się z aplikacją odbiorcy, kanał niestandardowy można
utworzyć za pomocą
setMessageReceivedCallbacks
metody:
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.namespace, mHelloWorldChannel) } catch (e: IOException) { Log.e(TAG, "Exception while creating channel", e) }
try { mCastSession.setMessageReceivedCallbacks( mHelloWorldChannel.getNamespace(), mHelloWorldChannel); } catch (IOException e) { Log.e(TAG, "Exception while creating channel", e); }
Po utworzeniu kanału niestandardowego nadawca może użyć metody
sendMessage, aby wysyłać wiadomości tekstowe do odbiorcy za pomocą tego kanału:
private fun sendMessage(message: String) { if (mHelloWorldChannel != null) { try { mCastSession.sendMessage(mHelloWorldChannel.namespace, message) .setResultCallback { status -> if (!status.isSuccess) { Log.e(TAG, "Sending message failed") } } } catch (e: Exception) { Log.e(TAG, "Exception while sending message", e) } } }
private void sendMessage(String message) { if (mHelloWorldChannel != null) { try { mCastSession.sendMessage(mHelloWorldChannel.getNamespace(), message) .setResultCallback( status -> { if (!status.isSuccess()) { Log.e(TAG, "Sending message failed"); } }); } catch (Exception e) { Log.e(TAG, "Exception while sending message", e); } } }
Obsługa autoodtwarzania
Zapoznaj się z sekcją Interfejsy API autoodtwarzania i kolejkowania.
Zastępowanie wyboru obrazu w widżetach interfejsu
Różne komponenty platformy (mianowicie okno Cast, miniodtwarzacz i UIMediaController, jeśli jest skonfigurowany) będą wyświetlać grafikę aktualnie przesyłanych multimediów. Adresy URL grafiki są zwykle zawarte w MediaMetadata multimediów, ale aplikacja nadawcy może mieć alternatywne źródło adresów URL.
Klasa
ImagePicker
określa sposób wybierania odpowiedniego obrazu z listy obrazów
w MediaMetadata, na podstawie użycia obrazu, np. miniatury powiadomienia
lub tła na pełnym ekranie. Domyślna implementacja ImagePicker zawsze wybiera pierwszy obraz lub zwraca wartość null, jeśli w MediaMetadata nie ma obrazu. Twoja aplikacja może utworzyć podklasę ImagePicker i zastąpić metodę
onPickImage(MediaMetadata, ImageHints)
, aby zapewnić alternatywną implementację, a następnie wybrać tę podklasę
za pomocą metody
setImagePicker
klasy CastMediaOptions.Builder.
ImageHints
zawiera wskazówki dla ImagePicker dotyczące typu i rozmiaru obrazu, który ma być wyświetlany w interfejsie.
Dostosowywanie okien Cast
Zarządzanie cyklem życia sesji
SessionManager
to centralne miejsce do zarządzania cyklem życia sesji. SessionManager nasłuchuje
zmian stanu wyboru trasy
MediaRouter
w Androidzie, aby rozpoczynać, wznawiać i kończyć sesje. Gdy trasa zostanie
wybrana, SessionManager utworzy
Session
obiekt i spróbuje go uruchomić lub wznowić. Gdy trasa zostanie odznaczona, SessionManager zakończy bieżącą sesję.
Aby SessionManager prawidłowo zarządzał cyklami życia sesji, musisz:
- W oknie wyboru trasy wywołać
gdy użytkownik wybierze urządzenie.
MediaRouter.selectRoute(MediaRouter.RouteInfo) - W oknie sterowania trasą (w stanie połączenia
lub
przesyłania
),
wywołać
MediaRouter.unselect(int)gdy użytkownik przestanie przesyłać.
W zależności od sposobu tworzenia okien Cast może być konieczne wykonanie dodatkowych działań:
- Jeśli tworzysz okna Cast za pomocą
MediaRouteChooserDialogiMediaRouteControllerDialog, te okna automatycznie zaktualizują wybór trasy wMediaRouterautomatycznie, więc nie musisz nic robić. - Jeśli skonfigurujesz przycisk Cast za pomocą
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)lubCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton), okna zostaną utworzone za pomocąMediaRouteChooserDialogiMediaRouteControllerDialog, więc nie musisz nic robić. - W innych przypadkach będziesz tworzyć niestandardowe okna Cast, więc musisz postępować zgodnie z powyższymi instrukcjami, aby zaktualizować stan wyboru trasy w
MediaRouter.
Stan braku urządzeń
Jeśli tworzysz niestandardowe okna Cast, Twój niestandardowy MediaRouteChooserDialog powinien prawidłowo obsługiwać przypadek, w którym nie znaleziono żadnych urządzeń. Okno powinno zawierać wskaźniki informujące użytkowników, kiedy aplikacja nadal próbuje znaleźć urządzenia, a kiedy próba wykrycia nie jest już aktywna.
Jeśli używasz domyślnego MediaRouteChooserDialog, stan braku urządzeń jest już obsługiwany.
Dalsze kroki
To wszystkie funkcje, które możesz dodać do aplikacji nadawcy na Androida. Możesz teraz utworzyć aplikację nadawcy na inną platformę (iOS lub sieć) albo utworzyć aplikację odbiorcy internetowego.