SDK Engage para recomendações de vídeo

Este guia contém instruções para que os desenvolvedores integrem conteúdo de vídeo recomendado, usando o SDK Engage, para preencher experiências de recomendações em plataformas do Google, como TV, dispositivos móveis e tablets.

A recomendação usa o cluster de recomendação para mostrar filmes e programas de TV de vários apps em um grupo de interfaces. Cada parceiro de desenvolvedor pode transmitir no máximo 25 entidades em cada cluster de recomendações, e pode haver no máximo sete clusters de recomendação por solicitação.

Pré-trabalho

Antes de começar, siga estas etapas. 1. Verifique se o app é direcionado ao nível 19 da API ou mais recente para essa integração.

  1. Adicione a biblioteca com.google.android.engage ao app.

    Há SDKs separados para usar na integração: um para apps para dispositivos móveis e outro para apps de TV.

    Para dispositivos móveis

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

    para TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.2
      }
    
  2. Defina o ambiente do serviço Engage como produção no arquivo AndroidManifest.xml.

    Para o APK para dispositivos móveis

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

    Para APK de TV

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. Executar a publicação em um serviço em primeiro plano.

  4. Publicar dados de recomendações no máximo uma vez por dia, acionados por

    1. Primeiro login do usuário do dia. (ou)
    2. Quando o usuário começa a interagir com o aplicativo.

Integração

AppEngagePublishClient publica o cluster de recomendação. Use o método publishRecommendationClusters para publicar um objeto de recomendações.

Use isServiceAvailable()2 para verificar se o serviço está disponível para integração.

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 recomendação e uma solicitação de publicação

Os clusters são agrupamentos lógicos das entidades. Os exemplos de código abaixo explicam como criar os clusters com base na sua preferência e como criar uma solicitação de publicação para todos os clusters.

// cluster for popular movies
val recommendationCluster1 = RecommendationCluster
  .Builder()
  .addEntity(movie)
  .addEntity(tvShow)
  .setTitle("Popular Movies")
  .build()

// cluster for top searches
val recommendationCluster2 = RecommendationCluster
  .Builder()
  .addEntity(movie)
  .addEntity(tvShow)
  .setTitle("Top Searches")
  .build()

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

Criar um perfil de conta

Para permitir uma experiência personalizada no Google TV, forneça informações de conta e perfil. Use o AccountProfile para fornecer:

  1. ID da conta: um identificador exclusivo que representa a conta do usuário no seu app. Pode ser o ID real da conta ou uma versão obfuscada adequada.
  2. ID do perfil (opcional): se o app oferecer suporte a vários perfis em uma única conta, forneça um identificador exclusivo para o perfil de usuário específico.
  3. Localidade(opcional): você pode fornecer o idioma preferido do usuário. Esse campo é útil se você enviar MediaActionFeedEntity no 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();

Quando o serviço recebe a solicitação, as seguintes ações ocorrem em uma transação:

  • Os dados do RecommendationsCluster do parceiro do desenvolvedor são removidos.
  • Os dados da solicitação são analisados e armazenados no RecommendationsCluster atualizado. Em caso de erro, a solicitação inteira é rejeitada e o estado atual é mantido.

Sincronização entre dispositivos

A flag SyncAcrossDevices controla se os dados de cluster de recomendações de um usuário são compartilhados com o Google TV e estão disponíveis em todos os dispositivos, como TV, smartphone e tablet. Para que a recomendação funcione, ela precisa ser definida como "true".

O app de mídia precisa fornecer uma configuração clara para ativar ou desativar a sincronização entre dispositivos. Explique os benefícios para o usuário e armazene a preferência dele uma vez e aplique-a na solicitação publishRecommendations. Para aproveitar ao máximo o recurso entre dispositivos, verifique se o app recebe o consentimento do usuário e permite que SyncAcrossDevices seja true.

Excluir os dados de descoberta de vídeo

Para excluir manualmente os dados de um usuário do servidor do Google TV antes do período padrão de retenção de 60 dias, use o método client.deleteClusters(). Ao receber a solicitação, o serviço exclui todos os dados de descoberta de vídeo do perfil da conta ou de toda a conta.

O tipo enumerado DeleteReason define o motivo da exclusão de dados. O código a seguir remove as recomendações ao sair.

// 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()
)

Criar entidades

O SDK definiu entidades diferentes para representar cada tipo de item. As entidades abaixo oferecem suporte ao cluster de recomendação:

  1. MediaActionFeedEntity
  2. MovieEntity
  3. TvShowEntity

Descrição

Forneça uma breve descrição para cada entidade. Essa descrição será exibida quando os usuários passarem o cursor sobre a entidade, fornecendo mais detalhes.

URIs de reprodução específicos da plataforma

Crie URIs de reprodução para cada plataforma com suporte: Android TV, Android ou iOS. Isso permite que o sistema selecione o URI apropriado para a reprodução de vídeo na respectiva plataforma.

No caso raro em que os URIs de reprodução são idênticos para todas as plataformas, repita o processo para cada plataforma.

// 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()

Poster images

As imagens de cartaz exigem um URI e dimensões em pixels (altura e largura). Segmente diferentes formatos fornecendo várias imagens de cartaz, mas verifique se todas as imagens mantêm uma proporção de 16:9 e uma altura mínima de 200 pixels para a exibição correta da entidade "Recomendações", especialmente no Espaço de entretenimento do Google. Imagens com altura menor que 200 pixels podem não ser exibidas.

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)

Motivo da recomendação

Opcionalmente, forneça um motivo da recomendação que pode ser usado pelo Google TV para criar motivos para sugerir um filme ou programa de TV específico ao usuário.

//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()

Janela de tempo de exibição

Se uma entidade precisar estar disponível apenas por um período limitado, defina um prazo de validade personalizado. Sem um prazo de validade explícito, as entidades expiram e são apagadas automaticamente após 60 dias. Portanto, defina um prazo de validade apenas quando as entidades precisarem ser expiradas mais cedo. Especifique várias janelas de disponibilidade.

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

Se você integrou seu catálogo de mídia ou feed de ação de mídia ao Google TV, não é necessário criar entidades separadas para filmes ou programas de TV. Em vez disso, você pode criar uma entidade MediaActionFeed que inclui o campo obrigatório DataFeedElementId. Esse ID precisa ser exclusivo e corresponder ao ID no feed de ação de mídia, porque ajuda a identificar o conteúdo do feed ingerido e realizar pesquisas de conteúdo de mídia.

val id = "dataFeedEleemntId"

MovieEntity

Confira um exemplo de como criar um MovieEntity com todos os campos obrigatórios:


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()

Você pode fornecer outros dados, como gêneros, classificações de conteúdo, data de lançamento, motivo da recomendação e janelas de disponibilidade, que podem ser usados pelo Google TV para exibições aprimoradas ou fins de filtragem.

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

Confira um exemplo de como criar um TvShowEntity com todos os campos obrigatórios:

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

Forneça dados adicionais, como gêneros, classificações de conteúdo, motivo da recomendação, preço da oferta, contagem de temporadas ou período de disponibilidade, que podem ser usados pelo Google TV para exibições aprimoradas ou para fins de filtragem.

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

Confira um exemplo de como criar um MediaActionFeedEntity com todos os campos obrigatórios:


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

Opcionalmente, forneça outros dados, como descrição, motivo da recomendação e janela de exibição, que podem ser usados pelo Google TV para exibições aprimoradas ou filtragem.

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

Ao implementar essas etapas, os desenvolvedores podem integrar recomendações de conteúdo em vídeo ao Google TV, aumentando a descoberta e o engajamento do usuário, oferecendo uma experiência de visualização consistente e personalizada para os usuários em todos os dispositivos.