SDK Engage pour les recommandations de vidéos

Ce guide explique aux développeurs comment intégrer leur contenu vidéo recommandé à l'aide du SDK Engage pour renseigner les expériences de recommandations sur les surfaces Google, telles que les téléviseurs, les mobiles et les tablettes.

La recommandation utilise le cluster de recommandations pour afficher des films et des séries TV provenant de plusieurs applications dans un seul regroupement d'UI. Chaque développeur partenaire peut diffuser au maximum 25 entités dans chaque cluster de recommandations. Chaque requête peut comporter au maximum sept clusters de recommandations.

Travail préalable

Avant de commencer, suivez les étapes ci-dessous. 1. Vérifiez que votre application cible le niveau d'API 19 ou supérieur pour cette intégration.

  1. Ajoutez la bibliothèque com.google.android.engage à votre application.

    Il existe des SDK distincts à utiliser pour l'intégration : un pour les applications mobiles et un pour les applications TV.

    Pour mobile

    
      dependencies {
        implementation 'com.google.android.engage:engage-core:1.5.9
      }
    

    pour TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.5
      }
    
  2. Définissez l'environnement du service Engage sur "production" dans le fichier AndroidManifest.xml.

    Pour les APK mobiles

    
    <meta-data
          android:name="com.google.android.engage.service.ENV"
          android:value="PRODUCTION">
    </meta-data>
    

    For tv apk

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. Exécutez la publication sur un service de premier plan.

  4. Publiez les données de recommandations au maximum une fois par jour, en fonction de l'un des éléments suivants :

    1. Première connexion de l'utilisateur de la journée. (ou)
    2. Lorsque l'utilisateur commence à interagir avec l'application.

Intégration

AppEngagePublishClient publie le cluster de recommandations. Utilisez la méthode publishRecommendationClusters pour publier un objet de recommandation.

Utilisez isServiceAvailable()2 pour vérifier si le service est disponible pour l'intégration.

val client = AppEngagePublishClient(context)

client.isServiceAvailable().addOnCompleteListener { task ->
  if (task.isSuccessful) {
  // Handle IPC call success
    if(task.result) {
      // Service is available on the device, proceed with content publish
      // calls.
      client.publishRecommendationClusters(recommendationRequest)
    } else {
      // Service is not available
    }
  } else {
    // The IPC call itself fails, proceed with error handling logic here,
    // such as retry.
  }
}

Clusters de recommandations et demande de publication

Les clusters sont des regroupements logiques d'entités. Les exemples de code suivants expliquent comment créer les clusters en fonction de vos préférences et comment créer une demande de publication pour tous les clusters.

// cluster for popular movies
val recommendationCluster1 = RecommendationCluster
  .Builder()
  .addEntity(movie1)
  .addEntity(movie2)
  .addEntity(movie3)
  .addEntity(movie4)
  .addEntity(tvShow)
  // This cluster is meant to be used as an individual provider row
  .setRecommendationClusterType(TYPE_PROVIDER_ROW)
  .setTitle("Popular Movies")
  .build()

// cluster for live TV programs
val recommendationCluster2 = RecommendationCluster
  .Builder()
  .addEntity(liveTvProgramEntity1)
  .addEntity(liveTvProgramEntity2)
  .addEntity(liveTvProgramEntity3)
  .addEntity(liveTvProgramEntity4)
  .addEntity(liveTvProgramEntity5)
 // This cluster is meant to be used as an individual provider row
  .setRecommendationClusterType(TYPE_PROVIDER_ROW)
  .setTitle("Popular Live TV Programs")
  .build()

// creating a publishing request
val recommendationRequest = PublishRecommendationClustersRequest
  .Builder()
  .setSyncAcrossDevices(true)
  .setAccountProfile(accountProfile)
  .addRecommendationCluster(recommendationCluster1)
  .addRecommendationCluster(recommendationCluster2)
  .build()

Créer un profil de compte

Pour bénéficier d'une expérience personnalisée sur Google TV, fournissez des informations sur votre compte et votre profil. Utilisez AccountProfile pour fournir :

  1. ID de compte : identifiant unique représentant le compte de l'utilisateur dans votre application. Il peut s'agir de l'ID de compte réel ou d'une version correctement masquée.
  2. ID de profil (facultatif) : si votre application accepte plusieurs profils dans un même compte, indiquez un identifiant unique pour le profil utilisateur spécifique.
  3. Locale(facultatif) : vous pouvez éventuellement indiquer la langue préférée de l'utilisateur. Ce champ est utile si vous envoyez MediaActionFeedEntity dans RecommendationRequest.
// If app only supports account
val accountProfile = AccountProfile.Builder()
  .setAccountId("account_id")
  .build();

// If app supports both account and profile
val accountProfile = AccountProfile.Builder()
  .setAccountId("account_id")
  .setProfileId("profile_id")
  .build();

// set Locale
val accountProfile = AccountProfile.Builder()
  .setAccountId("account_id")
  .setProfileId("profile_id")
  .setLocale("en-US")
  .build();

Lorsque le service reçoit la requête, les actions suivantes ont lieu dans une seule transaction :

  • Les données RecommendationsCluster existantes du développeur partenaire sont supprimées.
  • Les données de la requête sont analysées et stockées dans le RecommendationsCluster mis à jour. En cas d'erreur, la requête entière est rejetée, et l'état existant est maintenu.

Synchronisation inter-appareils

L'indicateur SyncAcrossDevices contrôle si les données de cluster de recommandations d'un utilisateur sont partagées avec Google TV et disponibles sur ses appareils tels que le téléviseur, le téléphone et les tablettes. Pour que la recommandation fonctionne, elle doit être définie sur "true".

L'application multimédia doit proposer un paramètre clair permettant d'activer ou de désactiver la synchronisation multi-appareils. Expliquez les avantages à l'utilisateur, stockez sa préférence une seule fois et appliquez-la dans la requête publishRecommendations en conséquence. Pour profiter pleinement de la fonctionnalité multi-appareils, l'application de validation obtient le consentement de l'utilisateur et permet à SyncAcrossDevices d'accéder à true.

Supprimer les données de découverte vidéo

Pour supprimer manuellement les données d'un utilisateur du serveur Google TV avant la période de conservation standard de 60 jours, utilisez la méthode client.deleteClusters(). Une fois la demande reçue, le service supprime toutes les données existantes sur la découverte de vidéos pour le profil du compte ou pour l'ensemble du compte.

L'énumération DeleteReason définit la raison de la suppression des données. Le code suivant supprime les recommandations lors de la déconnexion.

// If the user logs out from your media app, you must make the following call
// to remove recommendations data from the current google TV device,
// otherwise, the recommendations data persists on the current
// google TV device until 60 days later.
client.deleteClusters(
  new DeleteClustersRequest.Builder()
    .setAccountProfile(AccountProfile())
    .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
    .build()
)

// If the user revokes the consent to share data with Google TV,
// you must make the following call to remove recommendations data from
// all current google TV devices. Otherwise, the recommendations data persists
// until 60 days later.
client.deleteClusters(
  new DeleteClustersRequest.Builder()
    .setAccountProfile(AccountProfile())
    .setReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT)
    .build()
)

Créer des entités

Le SDK a défini différentes entités pour représenter chaque type d'élément. Les entités suivantes sont acceptées pour le cluster de recommandations :

  1. MediaActionFeedEntity
  2. MovieEntity
  3. TvShowEntity
  4. LiveTvChannelEntity
  5. LiveTvProgramEntity

Description

Fournissez une brève description pour chaque entité. Elle s'affichera lorsque les utilisateurs pointeront sur l'entité, ce qui leur fournira des informations supplémentaires.

URI de lecture spécifiques à la plate-forme

Créez des URI de lecture pour chaque plate-forme compatible : Android TV, Android ou iOS. Cela permet au système de sélectionner l'URI approprié pour la lecture de la vidéo sur la plate-forme concernée.

Dans le cas rare où les URI de lecture sont identiques pour toutes les plates-formes, répétez-les pour chaque plate-forme.

// Required. Set this when you want recommended entities to show up on
// Google TV
val playbackUriTv = PlatformSpecificUri
  .Builder()
  .setPlatformType(PlatformType.TYPE_ANDROID_TV)
  .setActionUri(Uri.parse("https://www.example.com/entity_uri_for_tv"))
  .build()

// Optional. Set this when you want recommended entities to show up on
// Google TV Android app
val playbackUriAndroid = PlatformSpecificUri
  .Builder()
  .setPlatformType(PlatformType.TYPE_ANDROID_MOBILE)
  .setActionUri(Uri.parse("https://www.example.com/entity_uri_for_android"))
  .build()

// Optional. Set this when you want recommended entities to show up on
// Google TV iOS app
val playbackUriIos = PlatformSpecificUri
  .Builder()
  .setPlatformType(PlatformType.TYPE_IOS)
  .setActionUri(Uri.parse("https://www.example.com/entity_uri_for_ios"))
  .build()

val platformSpecificPlaybackUris =
  Arrays.asList(playbackUriTv, playbackUriAndroid, playbackUriIos)

// Provide appropriate rating for the system.
val contentRating = new RatingSystem
  .Builder()
  .setAgencyName("MPAA")
  .setRating("PG-13")
  .build()

Images poster

Les images de couverture nécessitent un URI et des dimensions en pixels (hauteur et largeur). Ciblez différents facteurs de forme en fournissant plusieurs affiches, mais vérifiez que toutes les images conservent un format 16:9 et une hauteur minimale de 200 pixels pour que l'entité "Recommandations" s'affiche correctement, en particulier dans l'Espace Divertissement de Google. Les images dont la hauteur est inférieure à 200 pixels ne seront peut-être pas diffusées.

Image image1 = new Image.Builder()
  .setImageUri(Uri.parse("http://www.example.com/entity_image1.png");)
  .setImageHeightInPixel(300)
  .setImageWidthInPixel(169)
  .build()

Image image2 = new Image.Builder()
  .setImageUri(Uri.parse("http://www.example.com/entity_image2.png");)
  .setImageHeightInPixel(640)
  .setImageWidthInPixel(360)
  .build()

// And other images for different form factors.
val images = Arrays.asList(image1, image2)

Motif de la recommandation

Vous pouvez éventuellement fournir un motif de recommandation que Google TV peut utiliser pour expliquer pourquoi un film ou une série TV spécifiques sont suggérés à l'utilisateur.

//Allows us to construct reason: "Because it is top 10 on your Channel"
val topOnPartner = RecommendationReasonTopOnPartner
  .Builder()
  .setNum(10) //any valid integer value
  .build()

//Allows us to construct reason: "Because it is popular on your Channel"
val popularOnPartner = RecommendationReasonPopularOnPartner
  .Builder()
  .build()

//Allows us to construct reason: "New to your channel, or Just added"
val newOnPartner = RecommendationReasonNewOnPartner
  .Builder()
  .build()

//Allows us to construct reason: "Because you watched Star Wars"
val watchedSimilarTitles = RecommendationReasonWatchedSimilarTitles
  .addSimilarWatchedTitleName("Movie or TV Show Title")
  .addSimilarWatchedTitleName("Movie or TV Show Title")
  .Builder()
  .build()

//Allows us to construct reason: "Recommended for you by ChannelName"
val recommendedForUser = RecommendationReasonRecommendedForUser
  .Builder()
  .build()

val watchAgain = RecommendationReasonWatchAgain
  .Builder()
  .build()

val fromUserWatchList = RecommendationReasonFromUserWatchlist
  .Builder()
  .build()

val userLikedOnPartner = RecommendationReasonUserLikedOnPartner
  .Builder()
  .setTitleName("Movie or TV Show Title")
  .build()

val generic = RecommendationReasonGeneric.Builder().build()

Période d'affichage

Si une entité ne doit être disponible que pendant une durée limitée, définissez un délai d'expiration personnalisé. En l'absence de délai d'expiration explicite, les entités expirent automatiquement et sont effacées au bout de 60 jours. Par conséquent, ne définissez une heure d'expiration que lorsque les entités doivent expirer plus tôt. Spécifiez plusieurs créneaux de disponibilité.

val window1 = DisplayTimeWindow
  .Builder()
  .setStartTimeStampMillis(now()+ 1.days.toMillis())
  .setEndTimeStampMillis(now()+ 30.days.toMillis())

val window2 = DisplayTimeWindow
  .Builder()
  .setEndTimeStampMillis(now()+ 30.days.toMillis())

val availabilityTimeWindows: List<DisplayTimeWindow> = listof(window1,window2)

DataFeedElementId

Si vous avez intégré votre catalogue de contenus multimédias ou votre flux d'actions multimédias à Google TV, vous n'avez pas besoin de créer des entités distinctes pour les films ou les séries TV. Vous pouvez créer une entité MediaActionFeed qui inclut le champ DataFeedElementId requis. Cet ID doit être unique et correspondre à celui du flux d'actions multimédias, car il permet d'identifier le contenu du flux ingéré et d'effectuer des recherches de contenu multimédia.

val id = "dataFeedEleemntId"

MovieEntity

Voici un exemple de création d'un MovieEntity avec tous les champs obligatoires :


val movieEntity = MovieEntity.Builder()
  .setName("Movie name")
  .setDescription("A sentence describing movie.")
  .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
  .addPosterImages(images)
  // Suppose the duration is 2 hours, it is 72000000 in milliseconds
  .setDurationMills(72000000)
  .build()

Vous pouvez fournir des données supplémentaires telles que les genres, les classifications de contenu, la date de sortie, le motif de recommandation et les périodes de disponibilité. Google TV peut les utiliser pour améliorer l'affichage ou le filtrage.

val genres = Arrays.asList("Action", "Science fiction");
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("pg-13").build();
val contentRatings = Arrays.asList(rating1);
//Suppose release date is 11-02-2025
val releaseDate  = 1739233800000L
val movieEntity = MovieEntity.Builder()
  ...
  .addGenres(genres)
  .setReleaseDateEpochMillis(releaseDate)
  .addContentRatings(contentRatings)
  .setRecommendationReason(topOnPartner or watchedSimilarTitles)
  .addAllAvailabilityTimeWindows(availabilityTimeWindows)
  .build()

TvShowEntity

Voici un exemple de création d'un TvShowEntity avec tous les champs obligatoires :

val tvShowEntity = TvShowEntity.Builder()
  .setName("Show title")
  .setDescription("A sentence describing TV Show.")
  .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
  .addPosterImages(images)
  .build();

Vous pouvez également fournir des données supplémentaires telles que les genres, les classifications du contenu, le motif de la recommandation, le prix de l'offre, le nombre de saisons ou la période de disponibilité, qui peuvent être utilisées par Google TV pour améliorer l'affichage ou le filtrage.

val genres = Arrays.asList("Action", "Science fiction");
val rating1 = RatingSystem.Builder()
  .setAgencyName("MPAA")
  .setRating("pg-13")
  .build();
val price = Price.Builder()
  .setCurrentPrice("$14.99")
  .setStrikethroughPrice("$16.99")
  .build();
val contentRatings = Arrays.asList(rating1);
val seasonCount = 5;
val tvShowEntity = TvShowEntity.Builder()
  ...
  .addGenres(genres)
  .addContentRatings(contentRatings)
  .setRecommendationReason(topOnPartner or watchedSimilarTitles)
  .addAllAvailabilityTimeWindows(availabilityTimeWindows)
  .setSeasonCount(seasonCount)
  .setPrice(price)
  .build()

MediaActionFeedEntity

Voici un exemple de création d'un MediaActionFeedEntity avec tous les champs obligatoires :


val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
  .setDataFeedElementId(id)
  .build()

Vous pouvez éventuellement fournir des données supplémentaires telles que la description, le motif de la recommandation et la période d'affichage, qui peuvent être utilisées par Google TV pour améliorer l'affichage ou à des fins de filtrage.

val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
  .setName("Movie name or TV Show name")
  .setDescription("A sentence describing an entity")
  .setRecommendationReason(topOnPartner or watchedSimilarTitles)
  .addPosterImages(images)
  .build()

LiveTvChannelEntity

Cela représente une chaîne de télévision en direct. Voici un exemple de création d'un LiveTvChannelEntity avec tous les champs obligatoires :

val liveTvChannelEntity = LiveTvChannelEntity.Builder()
  .setName("Channel Name")
  // ID of the live TV channel
  .setEntityId("https://www.example.com/channel/12345")
  .setDescription("A sentence describing this live TV channel.")
  // channel playback uri must contain at least PlatformType.TYPE_ANDROID_TV
  .addPlatformSpecificPlaybackUri(channelPlaybackUris)
  .addLogoImage(logoImage)
  .build()

Vous pouvez éventuellement fournir des données supplémentaires, telles que la classification du contenu ou le motif de la recommandation.

val rating1 = RatingSystem.Builder()
  .setAgencyName("MPAA")
  .setRating("pg-13")
  .build()
val contentRatings = Arrays.asList(rating1)

val liveTvChannelEntity = LiveTvChannelEntity.Builder()
  ...
  .addContentRatings(contentRatings)
  .setRecommendationReason(topOnPartner)
  .build()

LiveTvProgramEntity

Il s'agit d'une fiche de programme TV en direct diffusé ou prévu sur une chaîne de télévision en direct. Voici un exemple de création d'un LiveTvProgramEntity avec tous les champs obligatoires :

val liveTvProgramEntity = LiveTvProgramEntity.Builder()
  // First set the channel information
  .setChannelName("Channel Name")
  .setChanelId("https://www.example.com/channel/12345")
  // channel playback uri must contain at least PlatformType.TYPE_ANDROID_TV
  .addPlatformSpecificPlaybackUri(channelPlaybackUris)
  .setChannelLogoImage(channelLogoImage)
  // Then set the program or card specific information.
  .setName("Program Name")
  .setEntityId("https://www.example.com/schedule/123")
  .setDescription("Program Desccription")
  .addAvailabilityTimeWindow(
      DisplayTimeWindow.Builder()
        .setStartTimestampMillis(1756713600000L)// 2025-09-01T07:30:00+0000
        .setEndTimestampMillis(1756715400000L))// 2025-09-01T08:00:00+0000
  .addPosterImage(programImage)
  .build()

Vous pouvez éventuellement fournir des données supplémentaires, telles que des classifications de contenu, des genres ou un motif de recommandation.

val rating1 = RatingSystem.Builder()
  .setAgencyName("MPAA")
  .setRating("pg-13")
  .build()
val contentRatings = Arrays.asList(rating1)
val genres = Arrays.asList("Action", "Science fiction")

val liveTvProgramEntity = LiveTvProgramEntity.Builder()
  ...
  .addContentRatings(contentRatings)
  .addGenres(genres)
  .setRecommendationReason(topOnPartner)
  .build()

En suivant ces étapes, les développeurs peuvent intégrer des recommandations de contenus vidéo à Google TV, ce qui permet aux utilisateurs de découvrir plus facilement des contenus et d'améliorer leur engagement. Ils peuvent également offrir une expérience de visionnage cohérente et personnalisée sur tous leurs appareils.