Video önerileri için Engage SDK'sı

Bu kılavuzda, geliştiricilerin Engage SDK'yı kullanarak önerilen video içeriklerini entegre etme ve TV, cep telefonu ve tablet gibi Google platformlarında öneri deneyimlerini doldurma talimatları yer almaktadır.

Öneri, filmleri ve TV programlarını göstermek için Öneri kümesinden yararlanır. Bu sayede, birden fazla uygulamadaki içerikler tek bir kullanıcı arayüzü grubunda gösterilir. Her geliştirici iş ortağı, her öneri kümesinde en fazla 25 öğe yayınlayabilir ve istek başına en fazla 7 öneri kümesi olabilir.

Ön çalışma

Başlamadan önce aşağıdaki adımları tamamlayın. 1. Uygulamanızın bu entegrasyon için API düzeyi 19 veya üstünü hedeflediğini doğrulayın.

  1. com.google.android.engage kitaplığını uygulamanıza ekleyin.

    Entegrasyonda kullanılacak ayrı SDK'lar vardır: biri mobil uygulamalar, diğeri ise TV uygulamaları için.

    Mobil cihazlar için

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

    TV için

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.5
      }
    
  2. AndroidManifest.xml dosyasında Engage hizmet ortamını üretime ayarlayın.

    Mobil APK için

    
    <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. Yayınlama işlemini bir ön plan hizmetinde yürütün.

  4. Öneriler verilerini en fazla günde bir kez yayınlayın. Bu işlem, aşağıdakilerden biri tarafından tetiklenir:

    1. Kullanıcının o günkü ilk girişi. (veya)
    2. Kullanıcı uygulamayla etkileşime başladığında

Entegrasyon

AppEngagePublishClient, öneri kümesini yayınlar. Öneri nesnesi yayınlamak için publishRecommendationClusters yöntemini kullanın.

Hizmetin entegrasyona uygun olup olmadığını kontrol etmek için isServiceAvailable()2'yi kullanın.

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.
  }
}

Öneri kümeleri ve yayınlama isteği

Kümeler, öğelerin mantıksal olarak gruplandırılmasıdır. Aşağıdaki kod örneklerinde, tercihlerinize göre kümelerin nasıl oluşturulacağı ve tüm kümeler için nasıl yayınlama isteği oluşturulacağı açıklanmaktadır.

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

Hesap profili oluşturma

Google TV'de kişiselleştirilmiş bir deneyime izin vermek için hesap ve profil bilgilerini sağlayın. AccountProfile kullanarak şunları sağlayabilirsiniz:

  1. Hesap kimliği: Kullanıcının uygulamanızdaki hesabını temsil eden benzersiz tanımlayıcı. Bu, gerçek hesap kimliği veya uygun şekilde karartılmış bir sürüm olabilir.
  2. Profil kimliği (isteğe bağlı): Uygulamanız tek bir hesapta birden fazla profili destekliyorsa belirli kullanıcı profili için benzersiz bir tanımlayıcı sağlayın.
  3. Yerel ayar(isteğe bağlı): İsteğe bağlı olarak kullanıcının tercih ettiği dili sağlayabilirsiniz. Bu alan, MediaActionFeedEntity gönderiyorsanız yararlıdır.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();

Hizmet isteği aldığında tek bir işlemde aşağıdaki işlemler gerçekleşir:

  • Geliştirici iş ortağından alınan mevcut RecommendationsCluster verileri kaldırılır.
  • İstekten gelen veriler ayrıştırılır ve güncellenen RecommendationsCluster içinde depolanır. Hata durumunda isteğin tamamı reddedilir ve mevcut durum korunur.

Cihazlar arası senkronizasyon

SyncAcrossDevices işareti, kullanıcının öneri grubu verilerinin Google TV ile paylaşılıp paylaşılmayacağını ve TV, telefon, tablet gibi cihazlarında kullanılabilir olup olmayacağını kontrol eder. Önerinin çalışması için true olarak ayarlanması gerekir.

Medya uygulaması, cihazlar arası senkronizasyonu etkinleştirmek veya devre dışı bırakmak için net bir ayar sunmalıdır. Kullanıcıya avantajları açıklayın ve kullanıcının tercihini bir kez saklayıp publishRecommendations isteğinde buna göre uygulayın. Cihazlar arası özellikten en iyi şekilde yararlanmak için uygulamanın kullanıcı izni aldığını ve SyncAcrossDevices ile true arasında iletişimi etkinleştirdiğini doğrulayın.

Video keşfi verilerini silme

Bir kullanıcının verilerini standart 60 günlük saklama süresinden önce Google TV sunucusundan manuel olarak silmek için client.deleteClusters() yöntemini kullanın. Hizmet, isteği aldıktan sonra hesap profili veya hesabın tamamı için mevcut tüm video keşfi verilerini siler.

DeleteReason numaralandırması, veri silme nedenini tanımlar. Aşağıdaki kod, kullanıcı oturumu kapatıldığında önerileri kaldırır.

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

Varlık oluşturma

SDK, her öğe türünü temsil etmek için farklı öğeler tanımlamıştır. Öneri kümesi için aşağıdaki öğeler desteklenir:

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

Açıklama

Her bir öğe için kısa bir açıklama girin. Bu açıklama, kullanıcılar öğenin üzerine geldiğinde gösterilerek ek ayrıntılar sunar.

Platforma özel oynatma URI'leri

Desteklenen her platform (Android TV, Android veya iOS) için oynatma URI'leri oluşturun. Bu sayede sistem, ilgili platformda video oynatma için uygun URI'yi seçebilir.

Oynatma URI'lerinin tüm platformlar için aynı olduğu nadir durumlarda, her platform için tekrarlayın.

// 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 resimleri

Poster resimleri için URI ve piksel boyutları (yükseklik ve genişlik) gerekir. Birden fazla poster resmi sağlayarak farklı form faktörlerini hedefleyin ancak tüm resimlerin 16:9 en boy oranını ve "Öneriler" öğesinin doğru şekilde gösterilmesi için minimum 200 piksel yüksekliği koruduğunu doğrulayın. Bu durum, özellikle Google'ın Entertainment Space'inde önemlidir. Yüksekliği 200 pikselden az olan resimler gösterilmeyebilir.

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)

Öneri nedeni

İsteğe bağlı olarak, Google TV'nin kullanıcıya belirli bir filmi veya TV programını neden önereceğini açıklamak için kullanabileceği bir öneri nedeni sağlayın.

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

Görüntüleme zaman aralığı

Bir öğenin yalnızca sınırlı bir süre için kullanılabilir olması gerekiyorsa özel bir geçerlilik bitiş zamanı ayarlayın. Açık bir geçerlilik bitiş tarihi belirtilmediğinde, öğelerin geçerliliği 60 gün sonra otomatik olarak sona erer ve öğeler silinir. Bu nedenle, yalnızca öğelerin daha erken süresinin dolması gerektiğinde bir son kullanma tarihi ayarlayın. Bu türden birden fazla uygunluk aralığı belirtin.

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

Medya kataloğunuzu veya medya işlemi feed'inizi Google TV ile entegre ettiyseniz film veya TV programı için ayrı öğeler oluşturmanız gerekmez. Bunun yerine, gerekli alan olan DataFeedElementId'yi içeren bir MediaActionFeed öğesi oluşturabilirsiniz. Bu kimlik benzersiz olmalı ve alınan feed içeriğinin tanımlanmasına ve medya içeriği aramalarının yapılmasına yardımcı olduğundan Medya İşlemi Feed'indeki kimlikle eşleşmelidir.

val id = "dataFeedEleemntId"

MovieEntity

Aşağıda, gerekli tüm alanları içeren bir MovieEntity oluşturma örneği verilmiştir:


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

Google TV'nin gelişmiş gösterim veya filtreleme amacıyla kullanabileceği türler, içerik derecelendirmeleri, yayın tarihi, öneri nedeni ve kullanılabilirlik zaman aralıkları gibi ek veriler sağlayabilirsiniz.

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

Aşağıda, gerekli tüm alanları içeren bir TvShowEntity oluşturma örneği verilmiştir:

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

Google TV'nin gelişmiş gösterim veya filtreleme amacıyla kullanabileceği türler, içerik derecelendirmeleri, öneri nedeni, teklif fiyatı, sezon sayısı veya kullanılabilirlik zaman aralığı gibi ek veriler de isteğe bağlı olarak sağlanabilir.

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

Aşağıda, gerekli tüm alanları içeren bir MediaActionFeedEntity oluşturma örneği verilmiştir:


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

İsteğe bağlı olarak açıklama, öneri nedeni ve gösterim zaman aralığı gibi ek veriler sağlayın. Bu veriler, Google TV tarafından geliştirilmiş gösterimler veya filtreleme amacıyla kullanılabilir.

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

Bu, canlı TV kanalını temsil eder. Aşağıda, gerekli tüm alanları içeren bir LiveTvChannelEntity oluşturma örneği verilmiştir:

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

İsteğe bağlı olarak içerik derecelendirmeleri veya öneri nedeni gibi ek veriler sağlayın.

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

Bu, bir canlı TV kanalında yayınlanan veya yayınlanması planlanan bir canlı TV programı kartını gösterir. Aşağıda, gerekli tüm alanları içeren bir LiveTvProgramEntity oluşturma örneği verilmiştir:

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

İsteğe bağlı olarak içerik derecelendirmeleri, türler veya öneri nedeni gibi ek veriler sağlayın.

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

Geliştiriciler bu adımları uygulayarak video içeriği önerilerini Google TV'ye başarıyla entegre edebilir, kullanıcıların içerik keşfini ve etkileşimini artırabilir, tüm cihazlarında tutarlı ve kişiselleştirilmiş bir izleme deneyimi sunabilir.