Engage SDK สำหรับการแนะนำวิดีโอ

คู่มือนี้มีวิธีการสำหรับนักพัฒนาแอปในการผสานรวมเนื้อหาวิดีโอที่แนะนำโดยใช้ Engage SDK เพื่อแสดงประสบการณ์การแนะนำในแพลตฟอร์มต่างๆ ของ Google เช่น ทีวี อุปกรณ์เคลื่อนที่ และแท็บเล็ต

คำแนะนำจะใช้คลัสเตอร์คำแนะนำเพื่อแสดงภาพยนตร์และรายการทีวีจากแอปหลายแอปในการจัดกลุ่ม UI เดียว พาร์ทเนอร์นักพัฒนาแอปแต่ละรายสามารถ ออกอากาศเอนทิตีได้สูงสุด25 รายการในคลัสเตอร์คำแนะนำแต่ละรายการ และมีคลัสเตอร์คำแนะนำได้สูงสุด7 รายการต่อคำขอ

สิ่งที่ต้องเตรียมก่อนดำเนินการ

ทำตามวิธีการงานเบื้องต้นในคู่มือเริ่มต้นใช้งาน

  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 Flag ควบคุมว่าระบบจะแชร์ข้อมูลคลัสเตอร์คำแนะนำของผู้ใช้กับ Google TV และพร้อมใช้งานในอุปกรณ์ต่างๆ เช่น ทีวี โทรศัพท์ แท็บเล็ต หรือไม่ ต้องตั้งค่าเป็น "จริง" เพื่อให้คำแนะนำทำงานได้

แอปพลิเคชันสื่อต้องมีการตั้งค่าที่ชัดเจนเพื่อเปิดหรือปิดใช้การซิงค์ข้ามอุปกรณ์ อธิบายสิทธิประโยชน์ให้ผู้ใช้ทราบและจัดเก็บค่ากำหนดของผู้ใช้เพียงครั้งเดียว แล้วนำไปใช้ในpublishRecommendationsคำขอตามนั้น หากต้องการใช้ฟีเจอร์ข้ามอุปกรณ์ให้เกิดประโยชน์สูงสุด โปรดยืนยันว่าแอปได้รับความยินยอมจากผู้ใช้และเปิดใช้ SyncAcrossDevices เป็น true

ลบข้อมูลการค้นพบวิดีโอ

หากต้องการลบข้อมูลของผู้ใช้จากเซิร์ฟเวอร์ Google TV ด้วยตนเองก่อนระยะเวลาเก็บรักษามาตรฐาน 60 วัน ให้ใช้เมธอด client.deleteClusters() เมื่อได้รับคำขอ บริการจะลบข้อมูลการค้นพบวิดีโอที่มีอยู่ทั้งหมดสำหรับโปรไฟล์บัญชีหรือทั้งบัญชี

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

สร้างเอนทิตี

SDK ได้กำหนดเอนทิตีต่างๆ เพื่อแสดงรายการแต่ละประเภท ระบบรองรับเอนทิตีต่อไปนี้สำหรับคลัสเตอร์คำแนะนำ

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

ระบุคำอธิบาย

ระบุคำอธิบายสั้นๆ สำหรับแต่ละเอนทิตี คำอธิบายนี้จะแสดง เมื่อผู้ใช้วางเมาส์เหนือเอนทิตี เพื่อให้รายละเอียดเพิ่มเติมแก่ผู้ใช้

ข้อความกระตุ้นการตัดสินใจ

ระบุข้อความกระตุ้นให้ดำเนินการที่ไม่บังคับสำหรับแต่ละเอนทิตี ข้อความนี้จะแสดงต่อผู้ใช้เพื่อกระตุ้นการมีส่วนร่วม

แท็ก

ระบุรายการแท็กสำหรับแต่ละเอนทิตี (ไม่บังคับ) คุณใช้แท็กเพื่อ จัดหมวดหมู่และกรองได้

URI การเล่นเฉพาะแพลตฟอร์ม

สร้าง URI การเล่นสำหรับแต่ละแพลตฟอร์มที่รองรับ ได้แก่ Android TV, Android หรือ iOS ซึ่งจะช่วยให้ระบบเลือก URI ที่เหมาะสมสำหรับการเล่นวิดีโอบนแพลตฟอร์มที่เกี่ยวข้องได้

ในกรณีที่หายากซึ่งมี 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 = new RatingSystem
  .Builder()
  .setAgencyName("MPAA")
  .setRating("PG-13")
  .build()

ภาพโปสเตอร์

ภาพโปสเตอร์ต้องมี URI และขนาดพิกเซล (ความสูงและความกว้าง) โปรดกำหนดเป้าหมายรูปแบบของอุปกรณ์หลายๆ แบบ โดยจัดให้มีภาพโปสเตอร์หลายภาพ และตรวจสอบว่าภาพทั้งหมดมีสัดส่วนการแสดงผล 16:9 และมีความสูงอย่างน้อย 200 พิกเซล เพื่อให้แสดงผลเอนทิตี "รายการแนะนำ" ได้อย่างถูกต้องโดยเฉพาะภายใน Entertainment Space ของ Google ทั้งนี้ระบบอาจไม่แสดงรูปภาพที่มีความสูงน้อยกว่า 200 พิกเซล

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)

เหตุผลของคำแนะนำ

คุณอาจระบุเหตุผลในการแนะนำซึ่ง 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
  .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()

กรอบเวลาที่แสดง

หากเอนทิตีควรพร้อมใช้งานในช่วงระยะเวลาจำกัดเท่านั้น ให้ตั้งค่าเวลาหมดอายุที่กำหนดเอง หากไม่มีเวลาหมดอายุที่ชัดเจน ระบบจะ ลบเอนทิตีโดยอัตโนมัติหลังจากผ่านไป 60 วัน ดังนั้นให้ตั้งเวลาหมดอายุเฉพาะในกรณีที่ต้องให้เอนทิตีหมดอายุก่อน ระบุช่วงเวลาที่พร้อมให้บริการดังกล่าวหลายช่วง

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

หากผสานรวมแคตตาล็อกสื่อหรือฟีดการกระทำของสื่อกับ Google TV คุณไม่จำเป็นต้องสร้างเอนทิตีแยกต่างหากสำหรับภาพยนตร์หรือรายการทีวี แต่สามารถ สร้าง MediaActionFeedEntity ซึ่งมี ฟิลด์ที่จำเป็น DataFeedElementId แทนได้ รหัสนี้ต้องไม่ซ้ำกันและต้องตรงกับรหัสในฟีดการดำเนินการกับสื่อ เนื่องจากจะช่วยระบุเนื้อหาฟีดที่ส่งผ่านข้อมูลแล้วและค้นหาเนื้อหาสื่อ

val id = "dataFeedElementId"

MovieEntity

ต่อไปนี้เป็นตัวอย่างการสร้าง MovieEntity โดยมีฟิลด์ที่ต้องระบุทั้งหมด

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)
  .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.")
  .addPlatformSpecificPlaybackUri(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
  .addPlatformSpecificPlaybackUri(channelPlaybackUris)
  .addLogoImage(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
  .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)
  .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()