Coupures publicitaires
Le SDK Android Sender est compatible avec les coupures publicitaires et les annonces associées au sein d'une un flux multimédia donné.
Consultez le Présentation des coupures publicitaires Web receiver pour d'autres sur le fonctionnement des coupures publicitaires.
Bien que les coupures puissent être spécifiées à la fois au niveau de l'expéditeur et du destinataire, il est recommandé d'utiliser spécifiées sur Web Receiver et Android TV Receiver pour assurer la cohérence sur toutes les plates-formes.
Sur Android, spécifiez les coupures publicitaires dans une commande de chargement à l'aide de
AdBreakClipInfo
et 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);
Ajouter des actions personnalisées
Une application d'expéditeur peut étendre MediaIntentReceiver
pour gérer des actions personnalisées ou remplacer son comportement. Si vous avez mis en œuvre votre
propre MediaIntentReceiver
, vous devez l'ajouter au fichier manifeste et définir son
nom dans CastMediaOptions
. Cet exemple fournit des actions personnalisées
ignorer, activer/désactiver la lecture multimédia à distance, appuyer sur le bouton multimédia et d'autres types
d'actions.
// 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) { } }
Ajouter un critère personnalisé
Pour que l'application émettrice puisse communiquer avec l'application réceptrice, celle-ci doit
créer un critère personnalisé. L'expéditeur peut utiliser le canal personnalisé pour envoyer la chaîne
les messages au destinataire. Chaque critère personnalisé est défini par un
espace de noms et doit commencer par le préfixe urn:x-cast:
, par exemple :
urn:x-cast:com.example.custom
Vous pouvez avoir plusieurs canaux personnalisés, chacun avec un espace de noms unique. L'application réceptrice peut également
envoyer et recevoir des messages
utilisant le même espace de noms.
Le critère personnalisé est implémenté à l'aide du
Cast.MessageReceivedCallback
interface:
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); } }
Une fois l'application émettrice connectée à l'application réceptrice, le canal personnalisé peut
être créées à l'aide de
setMessageReceivedCallbacks
méthode:
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); }
Une fois le critère personnalisé créé, l'expéditeur peut utiliser le
sendMessage
pour envoyer des messages de chaîne au destinataire via ce canal:
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); } } }
Compatibilité avec la lecture automatique
Consultez la section Lecture automatique et API de mise en file d'attente.
Forcer la sélection d'une image pour les widgets d'expérience utilisateur
Divers composants du framework (à savoir la boîte de dialogue Cast, le mini-contrôleur et l'UIMediaController, le cas échéant) affichent l'illustration du contenu multimédia en cours de diffusion. Les URL des illustrations d'image sont généralement incluses dans le MediaMetadata
pour le contenu multimédia, mais l'application d'envoi peut disposer d'une autre source pour les URL.
La
ImagePicker
La classe définit un moyen de sélectionner une image appropriée dans la liste d'images.
dans un MediaMetadata
, en fonction de l'utilisation de l'image (par exemple, la notification
une miniature ou un arrière-plan en plein écran. L'implémentation par défaut de ImagePicker
choisit toujours la première image, ou renvoie la valeur "null" si aucune image n'est disponible dans la
MediaMetadata
Votre application peut sous-classer ImagePicker
et remplacer le
onPickImage(MediaMetadata, ImageHints)
pour fournir une autre implémentation, puis sélectionner cette sous-classe
avec le
setImagePicker
de CastMediaOptions.Builder
.
ImageHints
fournit des indications à une ImagePicker
sur le type et la taille d'une image à
sélectionnées pour être affichées dans l'interface utilisateur.
Personnaliser les boîtes de dialogue Cast
Gérer le cycle de vie d'une session
SessionManager
est l'emplacement central pour gérer le cycle de vie des sessions. SessionManager
écoutes
vers Android
MediaRouter
l'état de la sélection d'itinéraire change pour démarrer, reprendre et terminer les sessions. Lorsqu’un itinéraire est
sélectionné, SessionManager
créera un
Session
et tente de le démarrer ou de le réactiver. Lorsqu'un itinéraire est désélectionné, SessionManager
met fin à la session en cours.
Par conséquent, pour vous assurer que SessionManager
gère correctement les cycles de vie des sessions, vous devez
vous devez vous assurer que:
- Dans la boîte de dialogue du sélecteur de routes,
appel
MediaRouter.selectRoute(MediaRouter.RouteInfo)
Lorsqu'un utilisateur sélectionne un appareil. - Dans la boîte de dialogue du contrôleur de routage (dans
état ou
caster
state),
appel
MediaRouter.unselect(int)
lorsque l'utilisateur arrête de caster du contenu.
Selon la façon dont vous créez les boîtes de dialogue Cast, des actions supplémentaires peuvent être nécessaires terminé:
- Si vous créez des boîtes de dialogue Cast avec
MediaRouteChooserDialog
etMediaRouteControllerDialog
, ces boîtes de dialogue mettront à jour automatiquement l'itinéraire sélectionné dansMediaRouter
, vous n'avez donc rien à faire. - Si vous configurez l'icône Cast avec
CastButtonFactory.setUpMediaRouteButton(Context, Menu, int)
ouCastButtonFactory.setUpMediaRouteButton(Context, MediaRouteButton)
, alors les dialogues sont en fait créé à l'aide deMediaRouteChooserDialog
etMediaRouteControllerDialog
. vous n'avez rien à faire non plus. - Dans d'autres cas, vous créerez des boîtes de dialogue Cast personnalisées. Vous devez donc
suivez les instructions ci-dessus pour modifier l'état de sélection de l'itinéraire dans
MediaRouter
État "Aucun appareil"
Si vous créez des boîtes de dialogue Cast personnalisées, votre MediaRouteChooserDialog
personnalisée doit gérer correctement le cas où aucun appareil n'est détecté. La boîte de dialogue doit comporter des indicateurs indiquant clairement aux utilisateurs à quel moment votre
l'application tente toujours de trouver des appareils alors que la tentative de détection n'est pas
plus actifs.
Si vous utilisez le MediaRouteChooserDialog
par défaut, l'état zéro pour les appareils
est déjà traitée.
Étapes suivantes
Voici les fonctionnalités que vous pouvez ajouter à votre application Android Sender. Vous pouvez désormais créer une application émettrice pour une autre plate-forme (iOS ou Web), ou créer une application Web Receiver ;