Engage SDK برای توصیه‌های ویدیویی

این راهنما حاوی دستورالعمل‌هایی برای توسعه‌دهندگان است تا محتوای ویدیویی توصیه‌شده خود را بااستفاده از کیت توسعه نرم‌افزار Engage ادغام کنند و تجربه‌های توصیه‌شده را در سطوح Google، مانند تلویزیون، تلفن همراه، و رایانه لوحی، پر کنند.

توصیه از خوشه توصیه برای نمایش فیلم‌ها و نمایش‌های تلویزیونی از چند برنامه در یک گروه رابط کاربری استفاده می‌کند. هر شریک توسعه‌دهنده می‌تواند حداکثر ۲۵ نهاد را در هر خوشه توصیه‌ها همه‌فرستی کند و در هر درخواست می‌تواند حداکثر ۷ خوشه توصیه وجود داشته باشد.

پیش‌کار

دستورالعمل‌های پیش‌کار را در راهنمای «شروع به کار» تکمیل کنید.

  1. انتشار را در سرویس پیش‌زمینه‌ای اجرا کنید.
  2. داده‌های توصیه‌ها را حداکثر یک بار در روز منتشر کنید، که با یکی از موارد زیر راه‌اندازی می‌شود
    • اولین ورود کاربر به سیستم در روز. (یا)
    • وقتی کاربر شروع به تعامل با برنامه می‌کند.

یکپارچه‌سازی

‫AppEngagePublishClient خوشه توصیه را منتشر می‌کند. از روش publishRecommendationClusters برای انتشار شیء توصیه‌ها استفاده کنید.

مطمئن شوید که کارخواه را مقداردهی اولیه کرده‌اید و دردسترس بودن سرویس را همان‌طور که در راهنمای شروع به کار شرح داده شده است بررسی کنید.

client.publishRecommendationClusters(recommendationRequest)

درحال به‌روزرسانی/درج خوشه‌های توصیه

خوشه‌ها گروه‌بندی منطقی نهادها هستند. نمونه‌های کد زیر نحوه ساختن خوشه‌ها براساس اولویت شما و نحوه ایجاد درخواست انتشار و درج/به‌روزرسانی همه خوشه‌ها را توضیح می‌دهد.

RecommendationClusterType تعیین می‌کند که خوشه چگونه نمایش داده شود.

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

وقتی سرویس درخواست را دریافت می‌کند، کنش‌های زیر در یک تراکنش انجام می‌شود:

  • داده‌های RecommendationsCluster موجود از شریک توسعه‌دهنده برداشته می‌شود.
  • داده‌های درخواست تجزیه می‌شود و در RecommendationsCluster به‌روزشده ذخیره می‌شود. درصورت بروز خطا، کل درخواست رد می‌شود و وضعیت موجود حفظ می‌شود.

همگام‌سازی بین‌دستگاهی

پرچم SyncAcrossDevices کنترل می‌کند که آیا داده‌های خوشه توصیه‌های کاربر با Google TV هم‌رسانی شود و در دستگاه‌های او مثل تلویزیون، تلفن، و رایانه لوحی دردسترس باشد یا نه. برای اینکه توصیه کار کند، باید روی «درست» تنظیم شود.

برنامه رسانه باید تنظیمات واضحی برای فعال یا غیرفعال کردن همگام‌سازی بین‌دستگاهی ارائه دهد. مزایا را برای کاربر توضیح دهید و اولویت کاربر را یک‌بار ذخیره کنید و آن را در درخواست publishRecommendations به‌طور مقتضی اعمال کنید. برای بهره‌مندی حداکثری از ویژگی بین‌دستگاهی، مطمئن شوید برنامه رضایت کاربر را کسب می‌کند و SyncAcrossDevices را برای true فعال می‌کند.

حذف داده‌های Engage

برای حذف دستی داده‌های کاربر از سرور Google TV قبل‌از دوره نگهداری استاندارد ۶۰ روزه، از روش client.deleteClusters() استفاده کنید. پس‌از دریافت درخواست، سرویس همه داده‌های Engage موجود را برای نمایه حساب یا برای کل حساب حذف می‌کند.

DeleteReason enum دلیل حذف داده‌ها را تعریف می‌کند. کد زیر توصیه‌ها را هنگام خروج از سیستم برمی‌دارد.

// 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(
  DeleteClustersRequest.Builder()
    .setAccountProfile(accountProfile)
    .setDeleteReason(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(
  DeleteClustersRequest.Builder()
    .setAccountProfile(accountProfile)
    .setDeleteReason(DeleteReason.DELETE_REASON_LOSS_OF_CONSENT)
    .build()
)

ایجاد نهادها

کیت توسعه نرم‌افزار نهادهای مختلفی را برای نمایش هر نوع مورد تعریف کرده است. نهادهای زیر برای خوشه «توصیه» پشتیبانی می‌شوند:

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

شرح ارائه دهید

شرح کوتاهی برای هر نهاد ارائه دهید؛ این شرح وقتی کاربران نشانگر را روی نهاد نگه می‌دارند نمایش داده می‌شود و جزئیات بیشتری به آن‌ها ارائه می‌دهد.

نوشتار دعوت به اقدام

برای هر نهاد، نوشتار دعوت به اقدام اختیاری ارائه دهید. این نوشتار برای تشویق به تعامل به کاربر نشان داده خواهد شد.

برچسب‌ها

درصورت تمایل، فهرستی از برچسب‌ها برای هر نهاد ارائه دهید. از برچسب‌ها می‌توان برای دسته‌بندی و فیلتر کردن استفاده کرد.

URIهای بازپخش مختص پلاتفرم

برای هر پلاتفرم پشتیبانی‌شده (Android TV،‏ Android، یا iOS) شناسه منبع یکسان بازپخش ایجاد کنید. این کار به سیستم اجازه می‌دهد شناسه منبع یکسان مناسب را برای بازپخش ویدیو در پلاتفرم مربوطه انتخاب کند.

در موارد نادری که URI بازپخش برای همه پلاتفرم‌ها یکسان است، آن را برای هر پلاتفرم تکرار کنید.

// 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 = RatingSystem
  .Builder()
  .setAgencyName("MPAA")
  .setRating("PG-13")
  .build()

تصاویر پوستر

تصاویر پوستر به URI و ابعاد پیکسل (ارتفاع و عرض) نیاز دارند. با ارائه چندین تصویر پوستر، عوامل شکل مختلف را هدف قرار دهید، اما مطمئن شوید که همه تصاویر نسبت ابعادی ۱۶:۹ و حداقل ارتفاع ۲۰۰ پیکسل را حفظ کنند تا نهاد «توصیه‌ها» به‌درستی نمایش داده شود، به‌ویژه در فضای سرگرمی Google. تصاویر با ارتفاع کمتر از ۲۰۰ پیکسل ممکن است نشان داده نشوند.

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

val image2 = 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)

دلیل توصیه

درصورت تمایل، دلیل توصیه‌ای ارائه دهید که Google TV بتواند از آن برای ساختن دلایل پیشنهاد دادن «فیلم» یا «نمایش تلویزیونی» خاصی به کاربر استفاده کند.

//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
  .Builder()
  .addSimilarWatchedTitleName("Movie or TV Show Title")
  .addSimilarWatchedTitleName("Movie or TV Show Title")
  .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 userLikedTitle = RecommendationReasonUserLikedTitle
  .Builder()
  .setLikedTitleName("Movie or TV Show Title")
  .build()

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

نمایش بازه زمانی

اگر نهادی فقط باید برای مدت محدودی دردسترس باشد، زمان انقضای سفارشی تنظیم کنید. بدون زمان انقضای صریح، موجودیت‌ها به‌طور خودکار منقضی می‌شوند و پس‌از ۶۰ روز پاک می‌شوند. بنابراین، زمان انقضا را فقط زمانی تنظیم کنید که نهادها باید زودتر منقضی شوند. چندین پنجره دردسترس بودن مشخص کنید.

val window1 = DisplayTimeWindow
  .Builder()
  .setStartTimestampMillis(now() + 1.days.toMillis())
  .setEndTimestampMillis(now() + 30.days.toMillis())
  .build()

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

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

DataFeedElementId

اگر کاتالوگ رسانه یا فید کنش رسانه خود را با Google TV ادغام کرده‌اید، نیازی به ایجاد نهادهای جداگانه برای فیلم یا نمایش تلویزیونی ندارید و درعوض می‌توانید MediaActionFeedEntity ایجاد کنید که شامل فیلد الزامی DataFeedElementId باشد. این شناسه باید منحصربه‌فرد باشد و با شناسه موجود در «فید کنش رسانه» مطابقت داشته باشد، زیرا به شناسایی محتوای فید واردشده و جستجوی محتوای رسانه کمک می‌کند.

val id = "dataFeedElementId"

MovieEntity

در اینجا مثالی از ایجاد MovieEntity با همه فیلدهای الزامی آورده شده است:

val movieEntity = MovieEntity.Builder()
  .setName("Movie name")
  .setDescription("A sentence describing movie.")
  .addPlatformSpecificPlaybackUris(platformSpecificPlaybackUris)
  .addPosterImages(images)
  // Suppose the duration is 2 hours, it is 72000000 in milliseconds
  .setDurationMillis(72000000)
  .setCallToActionText("Watch Now")
  .addTag("Action")
  .build()

می‌توانید داده‌های بیشتری مثل ژانر، رده‌بندی محتوا، تاریخ انتشار، دلیل توصیه، و پنجره‌های زمانی دردسترس بودن را ارائه دهید که ممکن است Google TV از آن‌ها برای نمایش بهبودیافته یا اهداف فیلتر کردن استفاده کند.

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

در اینجا مثالی از ایجاد TvShowEntity با همه فیلدهای الزامی آورده شده است:

val tvShowEntity = TvShowEntity.Builder()
  .setName("Show title")
  .setDescription("A sentence describing TV Show.")
  .addPlatformSpecificPlaybackUris(platformSpecificPlaybackUris)
  .addPosterImages(images)
  .setCallToActionText("Watch Now")
  .addTag("Drama")
  .build()

درصورت تمایل، داده‌های بیشتری مثل ژانر، رده‌بندی محتوا، دلیل توصیه، قیمت پیشنهاد، تعداد فصل، یا بازه زمانی دردسترس بودن را ارائه دهید که ممکن است Google TV از آن‌ها برای نمایش بهتر یا فیلتر کردن استفاده کند.

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

در اینجا مثالی از ایجاد MediaActionFeedEntity با همه فیلدهای الزامی آورده شده است:

val mediaActionFeedEntity = MediaActionFeedEntity.Builder()
  .setDataFeedElementId(id)
  .setCallToActionText("Watch Now")
  .addTag("Action")
  .build()

درصورت تمایل، داده‌های بیشتری مثل شرح، دلیل توصیه، و پنجره زمانی نمایش ارائه دهید که ممکن است Google TV از آن‌ها برای نمایش‌های بهبودیافته یا اهداف فیلتر کردن استفاده کند.

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

این موجودیت نشان‌دهنده کانال تلویزیون زنده است. در اینجا مثالی از ایجاد LiveTvChannelEntity با همه فیلدهای الزامی آورده شده است:

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
  .addPlatformSpecificPlaybackUris(channelPlaybackUris)
  .setLogoImage(logoImage)
  .setCallToActionText("Watch Now")
  .addTag("News")
  .build()

درصورت تمایل، داده‌های بیشتری مثل رده‌بندی محتوا یا دلیل توصیه ارائه دهید.

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

این موجودیت نشان‌دهنده کارت برنامه تلویزیون زنده است که درحال پخش است یا برای پخش در کانال تلویزیون زنده زمان‌بندی شده است. در اینجا مثالی از ایجاد LiveTvProgramEntity با همه فیلدهای الزامی آورده شده است:

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
  .addPlatformSpecificPlaybackUris(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
        .build()
  )
  .addPosterImage(programImage)
  .setCallToActionText("Watch Now")
  .addTag("Sports")
  .build()

درصورت تمایل، داده‌های بیشتری مثل رده‌بندی محتوا، ژانر، یا دلیل توصیه ارائه دهید.

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