book_path: /distribute/other-docs/_book.yaml project_path: /distribute/other-docs/_project.yaml
Panduan ini berisi petunjuk bagi developer untuk mengintegrasikan konten video yang direkomendasikan, menggunakan Engage SDK, untuk mengisi pengalaman rekomendasi di seluruh platform Google, seperti TV, perangkat seluler, dan tablet.
Rekomendasi memanfaatkan Cluster rekomendasi untuk menampilkan film dan acara TV dari beberapa aplikasi dalam satu pengelompokan UI. Setiap partner developer dapat menyiarkan maksimum 25 entity di setiap cluster rekomendasi dan dapat ada maksimum 7 cluster rekomendasi per permintaan.
Persiapan
Selesaikan petunjuk Persiapan dalam panduan Memulai.
- Menjalankan publikasi di layanan latar depan.
- Publikasikan data rekomendasi paling banyak sekali sehari, yang dipicu oleh salah satu dari
- Login pertama pengguna pada hari itu. (atau)
- Saat pengguna mulai berinteraksi dengan aplikasi.
Integrasi
AppEngagePublishClient memublikasikan cluster rekomendasi. Gunakan
metode publishRecommendationClusters untuk memublikasikan objek rekomendasi.
Pastikan untuk menginisialisasi klien dan memeriksa ketersediaan layanan seperti yang dijelaskan dalam Panduan memulai.
client.publishRecommendationClusters(recommendationRequest)
Menggabungkan dan memperbarui cluster rekomendasi
Cluster adalah pengelompokan logis entitas. Contoh kode berikut menjelaskan cara membuat cluster berdasarkan preferensi Anda dan cara membuat permintaan publikasi serta meng-upsert semua cluster.
RecommendationClusterType menentukan cara
kluster akan ditampilkan.
// 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()
Saat layanan menerima permintaan, tindakan berikut akan terjadi dalam satu transaksi:
- Data
RecommendationsClusteryang ada dari partner developer akan dihapus. - Data dari permintaan akan diuraikan dan disimpan di
RecommendationsClusteryang diperbarui. Jika terjadi error, seluruh permintaan akan ditolak dan status yang ada dipertahankan.
Sinkronisasi lintas perangkat
Flag SyncAcrossDevices mengontrol apakah data pengelompokan rekomendasi pengguna dibagikan ke Google TV dan tersedia di seluruh perangkatnya seperti TV, ponsel, tablet. Agar rekomendasi berfungsi, setel ke benar (true).
Mendapatkan izin
Aplikasi media harus menyediakan setelan yang jelas untuk mengaktifkan atau menonaktifkan sinkronisasi lintas perangkat. Jelaskan manfaatnya kepada pengguna dan simpan preferensi pengguna
sekali saja, lalu terapkan di publishRecommendations Request yang sesuai. Untuk
mengoptimalkan fitur lintas perangkat, pastikan aplikasi mendapatkan izin pengguna
dan mengaktifkan SyncAcrossDevices ke true.
Menghapus data penemuan video
Untuk menghapus data pengguna secara manual dari server Google TV sebelum periode retensi 60 hari standar, gunakan metode client.deleteClusters(). Setelah
menerima permintaan, layanan akan menghapus semua data penemuan video yang ada untuk profil akun, atau untuk seluruh akun.
Enum DeleteReason menentukan alasan penghapusan data.
Kode berikut menghapus rekomendasi saat logout.
// 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()
)
Membuat entity
SDK telah menentukan entity yang berbeda untuk mewakili setiap jenis item. Entitas berikut didukung untuk cluster Rekomendasi:
Memberikan deskripsi
Berikan deskripsi singkat untuk setiap entitas; deskripsi ini akan ditampilkan saat pengguna mengarahkan kursor ke entitas, sehingga memberikan detail tambahan kepada mereka.
URI pemutaran khusus platform
Buat URI pemutaran untuk setiap platform yang didukung: Android TV, Android, atau iOS. Hal ini memungkinkan sistem memilih URI yang sesuai untuk pemutaran video di platform masing-masing.
Dalam kasus yang jarang terjadi saat URI pemutaran identik untuk semua platform, ulangi untuk setiap platform.
// 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()
Gambar poster
Gambar poster memerlukan URI dan dimensi piksel (tinggi dan lebar). Menargetkan faktor bentuk yang berbeda dengan menyediakan beberapa gambar poster, tetapi pastikan semua gambar mempertahankan rasio aspek 16:9 dan tinggi minimum 200 piksel untuk tampilan yang benar dari entitas "Rekomendasi", terutama dalam Entertainment Space Google. Gambar dengan tinggi kurang dari 200 piksel mungkin tidak ditampilkan.
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)
Alasan rekomendasi
Secara opsional, berikan alasan rekomendasi yang dapat digunakan oleh Google TV untuk membuat alasan mengapa menyarankan Film atau Acara TV tertentu kepada pengguna.
//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()
Menampilkan periode waktu
Jika entitas hanya boleh tersedia dalam waktu terbatas, tetapkan waktu habis masa berlaku kustom. Tanpa waktu habis masa berlaku yang eksplisit, entitas akan otomatis habis masa berlakunya dan dihapus setelah 60 hari. Jadi, tetapkan waktu habis masa berlaku hanya jika entity perlu segera habis masa berlakunya. Tentukan beberapa periode ketersediaan tersebut.
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
Jika Anda telah mengintegrasikan katalog Media atau feed tindakan Media dengan Google TV, Anda tidak perlu membuat entitas terpisah untuk Film atau Acara TV, tetapi Anda dapat membuat MediaActionFeedEntity yang menyertakan kolom wajib diisi DataFeedElementId. ID ini harus unik dan harus cocok dengan
ID di Feed Tindakan Media karena membantu mengidentifikasi konten feed yang di-ingest dan
melakukan pencarian konten media.
val id = "dataFeedElementId"
MovieEntity
Berikut contoh pembuatan MovieEntity dengan semua kolom wajib diisi:
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()
Anda dapat memberikan data tambahan seperti genre, rating konten, tanggal rilis, alasan rekomendasi, dan periode waktu ketersediaan, yang dapat digunakan oleh Google TV untuk tujuan tampilan atau pemfilteran yang lebih baik.
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
Berikut contoh pembuatan TvShowEntity dengan semua kolom wajib diisi:
val tvShowEntity = TvShowEntity.Builder()
.setName("Show title")
.setDescription("A sentence describing TV Show.")
.addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
.addPosterImages(images)
.build();
Secara opsional, berikan data tambahan seperti genre, rating konten, alasan rekomendasi, harga penawaran, jumlah musim, atau jangka waktu ketersediaan, yang dapat digunakan oleh Google TV untuk tujuan tampilan atau pemfilteran yang lebih baik.
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
Berikut contoh pembuatan MediaActionFeedEntity dengan semua kolom wajib diisi:
val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
.setDataFeedElementId(id)
.build()
Secara opsional, berikan data tambahan seperti deskripsi, alasan rekomendasi, dan jangka waktu penayangan, yang dapat digunakan oleh Google TV untuk tujuan penyaringan atau tampilan yang lebih baik.
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
Ini mewakili channel TV live. Berikut contoh pembuatan
LiveTvChannelEntity dengan semua kolom wajib diisi:
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()
Secara opsional, berikan data tambahan seperti rating konten atau alasan rekomendasi.
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
Ini menampilkan kartu program TV live yang sedang atau dijadwalkan untuk ditayangkan di
saluran TV live. Berikut contoh pembuatan LiveTvProgramEntity
dengan semua kolom wajib diisi:
val liveTvProgramEntity = LiveTvProgramEntity.Builder()
// First set the channel information
.setChannelName("Channel Name")
.setChannelId("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 Description")
.addAvailabilityTimeWindow(
DisplayTimeWindow.Builder()
.setStartTimestampMillis(1756713600000L)// 2025-09-01T07:30:00+0000
.setEndTimestampMillis(1756715400000L))// 2025-09-01T08:00:00+0000
.addPosterImage(programImage)
.build()
Secara opsional, berikan data tambahan seperti rating konten, genre, atau alasan rekomendasi.
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()