Hướng dẫn tích hợp Engage SDK cho TV

Tính năng Tiếp tục xem tận dụng cụm Tiếp tục để hiển thị các video đang xem dở và các tập tiếp theo cần xem trong cùng một phần của chương trình truyền hình, từ nhiều ứng dụng trong một nhóm giao diện người dùng. Bạn có thể làm nổi bật các thực thể của họ trong cụm tiếp nối này. Hãy làm theo hướng dẫn này để tìm hiểu cách nâng cao mức độ tương tác của người dùng thông qua trải nghiệm Tiếp tục xem bằng Engage SDK.

Chuẩn bị trước

Trước khi bắt đầu, hãy hoàn tất các bước sau:

  1. cập nhật lên Target API 19 trở lên

  2. Thêm thư viện com.google.android.engage vào ứng dụng của bạn:

    Có các SDK riêng biệt để sử dụng trong quá trình tích hợp: một cho ứng dụng di động và một cho ứng dụng truyền hình.

    Thiết bị di động

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

    TV

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.2
      }
    
  3. Đặt môi trường dịch vụ Engage thành môi trường phát hành chính thức trong tệp AndroidManifest.xml.

    Thiết bị di động

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

    TV

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION" />
    
  4. Thêm quyền cho WRITE_EPG_DATA đối với tệp APK của TV

    <uses-permission android:name="com.android.providers.tv.permission.WRITE_EPG_DATA" />
    
  5. Xác minh việc xuất bản nội dung đáng tin cậy bằng cách sử dụng một dịch vụ nền, chẳng hạn như androidx.work, để lập lịch.

  6. Để mang đến trải nghiệm xem liền mạch, hãy xuất bản dữ liệu xem tiếp khi những sự kiện này xảy ra:

    1. Đăng nhập lần đầu: Khi người dùng đăng nhập lần đầu tiên, hãy xuất bản dữ liệu để đảm bảo nhật ký xem của họ có sẵn ngay lập tức.
    2. Tạo hoặc chuyển đổi hồ sơ (Ứng dụng có nhiều hồ sơ): Nếu ứng dụng của bạn hỗ trợ nhiều hồ sơ, hãy xuất bản dữ liệu khi người dùng tạo hoặc chuyển đổi hồ sơ.
    3. Gián đoạn quá trình phát video: Để giúp người dùng tiếp tục xem từ đoạn video mà họ đã dừng lại, hãy xuất bản dữ liệu khi họ tạm dừng hoặc dừng video, hoặc khi ứng dụng thoát trong quá trình phát.
    4. Cập nhật khay Tiếp tục xem (Nếu được hỗ trợ): Khi người dùng xoá một mục khỏi khay Tiếp tục xem, hãy phản ánh thay đổi đó bằng cách xuất bản dữ liệu đã cập nhật.
    5. Số lượt xem hết video:
      1. Đối với phim, hãy xoá bộ phim đã xem xong khỏi khay Tiếp tục xem. Nếu bộ phim đó thuộc một loạt phim, hãy thêm bộ phim tiếp theo để giữ chân người dùng.
      2. Đối với các tập, hãy xoá tập đã xem xong và thêm tập tiếp theo trong loạt chương trình (nếu có) để khuyến khích người dùng tiếp tục xem.

Mã mẫu

Ứng dụng mẫu này minh hoạ cách nhà phát triển có thể tích hợp với các API khám phá video để gửi dữ liệu người dùng được cá nhân hoá đến Google. Ứng dụng mẫu này cũng minh hoạ cách tạo một mô-đun chung có thể được nhập vào cả ứng dụng di động và ứng dụng truyền hình, thời điểm gọi các API xuất bản và xoá, cũng như cách sử dụng Worker để gọi các API xuất bản và xoá.

Tích hợp

AccountProfile

Để cho phép trải nghiệm "xem tiếp" phù hợp trên Google TV, hãy cung cấp thông tin tài khoản và hồ sơ. Sử dụng AccountProfile để cung cấp:

  1. Mã tài khoản: Giá trị nhận dạng riêng biệt đại diện cho tài khoản của người dùng trong ứng dụng của bạn. Đây có thể là mã tài khoản thực tế hoặc một phiên bản được làm rối mã nguồn một cách thích hợp.

  2. Mã nhận dạng hồ sơ (không bắt buộc): Nếu ứng dụng của bạn hỗ trợ nhiều hồ sơ trong một tài khoản, hãy cung cấp giá trị nhận dạng duy nhất cho hồ sơ người dùng cụ thể (một lần nữa, là giá trị thực hoặc giá trị bị làm rối).

// If your app only supports account
val accountProfile = AccountProfile.Builder()
    .setAccountId("your_users_account_id")
    .build()

// If your app supports both account and profile
val accountProfile = AccountProfile.Builder()
    .setAccountId("your_users_account_id")
    .setProfileId("your_users_profile_id")
    .build()

Tạo thực thể

SDK đã xác định các thực thể khác nhau để đại diện cho từng loại mục. Cụm tiếp tục hỗ trợ các thực thể sau:

  1. MovieEntity
  2. TvEpisodeEntity
  3. LiveStreamingVideoEntity
  4. VideoClipEntity

Chỉ định URI và hình ảnh áp phích dành riêng cho nền tảng cho các thực thể này.

Ngoài ra, hãy tạo URI phát cho từng nền tảng (chẳng hạn như Android TV, Android hoặc iOS) nếu bạn chưa tạo. Vì vậy, khi người dùng tiếp tục xem trên mỗi nền tảng, ứng dụng sẽ sử dụng một URI phát được nhắm đến để phát nội dung video.

// Required. Set this when you want continue watching 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()

// Required. Set this when you want continue watching entities to show up on
// Google TV Android app, Entertainment Space, Playstore Widget
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 continue watching 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)

Hình ảnh áp phích cần có URI và kích thước pixel (chiều cao và chiều rộng). Nhắm đến nhiều kiểu dáng bằng cách cung cấp nhiều hình ảnh áp phích, nhưng hãy xác minh rằng tất cả hình ảnh đều duy trì tỷ lệ khung hình 16:9 và chiều cao tối thiểu là 200 pixel để hiển thị chính xác thực thể "Xem tiếp", đặc biệt là trong Không gian giải trí của Google. Hình ảnh có chiều cao dưới 200 pixel có thể không xuất hiện.

val images = Arrays.asList(
    Image.Builder()
        .setImageUri(Uri.parse("http://www.example.com/entity_image1.png"))
        .setImageHeightInPixel(300)
        .setImageWidthInPixel(169)
        .build(),
    Image.Builder()
        .setImageUri(Uri.parse("http://www.example.com/entity_image2.png"))
        .setImageHeightInPixel(640)
        .setImageWidthInPixel(360)
        .build()
    // Consider adding other images for different form factors
)
MovieEntity

Ví dụ này cho thấy cách tạo MovieEntity với tất cả các trường bắt buộc:

val movieEntity = MovieEntity.Builder()
   .setWatchNextType(WatchNextType.TYPE_CONTINUE)
   .setName("Movie name")
   .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
   .addPosterImages(images)
   // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
   .setLastEngagementTimeMillis(1701388800000)
   // Suppose the duration is 2 hours, it is 72000000 in milliseconds
   .setDurationMills(72000000)
   // Suppose last playback offset is 1 hour, 36000000 in milliseconds
   .setLastPlayBackPositionTimeMillis(36000000)
   .build()

Khi bạn cung cấp các thông tin như thể loại và mức phân loại nội dung, Google TV có thể giới thiệu nội dung của bạn theo nhiều cách linh hoạt hơn và kết nối nội dung đó với đúng người xem.

val genres = Arrays.asList("Action", "Science fiction")
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("PG-13").build()
val contentRatings = Arrays.asList(rating1)
val movieEntity = MovieEntity.Builder()
    ...
    .addGenres(genres)
    .addContentRatings(contentRatings)
    .build()

Các thực thể sẽ tự động vẫn có sẵn trong 60 ngày, trừ phi bạn chỉ định thời gian hết hạn ngắn hơn. Chỉ đặt thời gian hết hạn tuỳ chỉnh nếu bạn cần xoá thực thể trước khoảng thời gian mặc định này.

// Set the expiration time to be now plus 30 days in milliseconds
val expirationTime = DisplayTimeWindow.Builder()
    .setEndTimestampMillis(now().toMillis()+2592000000).build()
val movieEntity = MovieEntity.Builder()
    ...
    .addAvailabilityTimeWindow(expirationTime)
    .build()
TvEpisodeEntity

Ví dụ này cho thấy cách tạo TvEpisodeEntity với tất cả các trường bắt buộc:

val tvEpisodeEntity = TvEpisodeEntity.Builder()
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Episode name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(72000000) // 2 hours in milliseconds
    // 45 minutes and 15 seconds in milliseconds is 2715000
    .setLastPlayBackPositionTimeMillis(2715000)
    .setEpisodeNumber("2")
    .setSeasonNumber("1")
    .setShowTitle("Title of the show")
    .build()

Chuỗi số tập (chẳng hạn như "2") và chuỗi số phần (chẳng hạn như "1") sẽ được mở rộng thành dạng thức phù hợp trước khi xuất hiện trên thẻ tiếp tục xem. Xin lưu ý rằng đây phải là một chuỗi số, đừng đặt "e2", "tập 2", "s1" hoặc "mùa 1".

Nếu một chương trình truyền hình cụ thể chỉ có một phần, hãy đặt số phần là 1.

Để tối đa hoá cơ hội cho người xem tìm thấy nội dung của bạn trên Google TV, hãy cân nhắc cung cấp thêm dữ liệu như thể loại, mức phân loại nội dung và khung giờ có sẵn, vì những thông tin này có thể cải thiện các lựa chọn hiển thị và lọc.

val genres = Arrays.asList("Action", "Science fiction")
val rating1 = RatingSystem.Builder().setAgencyName("MPAA").setRating("PG-13").build()
val contentRatings = Arrays.asList(rating1)
val tvEpisodeEntity = TvEpisodeEntity.Builder()
    ...
    .addGenres(genres)
    .addContentRatings(contentRatings)
    .setSeasonTitle("Season Title")
    .setShowTitle("Show Title")
    .build()
VideoClipEntity

Sau đây là ví dụ về cách tạo VideoClipEntity với tất cả các trường bắt buộc.

VideoClipEntity đại diện cho một đoạn video do người dùng tạo, chẳng hạn như video trên YouTube.

val videoClipEntity = VideoClipEntity.Builder()
    .setPlaybackUri(Uri.parse("https://www.example.com/uri_for_current_platform")
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Video clip name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(600000) //10 minutes in milliseconds
    .setLastPlayBackPositionTimeMillis(300000) //5 minutes in milliseconds
    .addContentRating(contentRating)
    .build()

Bạn có thể tuỳ ý đặt người tạo, hình ảnh người tạo, thời gian tạo tính bằng mili giây hoặc khoảng thời gian có sẵn .

LiveStreamingVideoEntity

Sau đây là ví dụ về cách tạo một LiveStreamingVideoEntity với tất cả các trường bắt buộc.

val liveStreamingVideoEntity = LiveStreamingVideoEntity.Builder()
    .setPlaybackUri(Uri.parse("https://www.example.com/uri_for_current_platform")
    .setWatchNextType(WatchNextType.TYPE_CONTINUE)
    .setName("Live streaming name")
    .addPlatformSpecificPlaybackUri(platformSpecificPlaybackUris)
    .addPosterImages(images)
    // Timestamp in millis for sample last engagement time 12/1/2023 00:00:00
    .setLastEngagementTimeMillis(1701388800000)
    .setDurationMills(72000000) //2 hours in milliseconds
    .setLastPlayBackPositionTimeMillis(36000000) //1 hour in milliseconds
    .addContentRating(contentRating)
    .build()

Bạn có thể tuỳ ý đặt thời gian bắt đầu, đài truyền hình, biểu tượng đài truyền hình hoặc khung thời gian có sẵn cho thực thể phát trực tiếp.

Để biết thông tin chi tiết về các thuộc tính và yêu cầu, hãy xem tài liệu tham khảo về API.

Cung cấp dữ liệu cụm Tiếp tục

AppEngagePublishClient chịu trách nhiệm xuất bản cụm Tiếp tục. Bạn sử dụng phương thức publishContinuationCluster() để xuất bản một đối tượng ContinuationCluster.

Trước tiên, bạn nên dùng isServiceAvailable() để kiểm tra xem dịch vụ có thể tích hợp hay không.

client.publishContinuationCluster(
    PublishContinuationClusterRequest
        .Builder()
        .setContinuationCluster(
            ContinuationCluster.Builder()
                .setAccountProfile(accountProfile)
                .addEntity(movieEntity1)
                .addEntity(movieEntity2)
                .addEntity(tvEpisodeEntity1)
                .addEntity(tvEpisodeEntity2)
                .setSyncAcrossDevices(true)
                .build()
        )
        .build()
)

Khi dịch vụ nhận được yêu cầu, các hành động sau đây sẽ diễn ra trong một giao dịch:

  • Dữ liệu ContinuationCluster hiện có của đối tác nhà phát triển sẽ bị xoá.
  • Dữ liệu của yêu cầu được phân tích cú pháp và lưu trữ trong ContinuationCluster đã cập nhật.

Trong trường hợp xảy ra lỗi, toàn bộ yêu cầu sẽ bị từ chối và trạng thái hiện tại sẽ được duy trì.

API xuất bản là các API chèn và cập nhật; sẽ thay thế nội dung hiện tại. Nếu cần cập nhật một thực thể cụ thể trong ContinuationCluster, bạn sẽ cần xuất bản lại tất cả các thực thể.

Bạn chỉ nên cung cấp dữ liệu ContinuationCluster cho tài khoản người lớn. Chỉ xuất bản khi AccountProfile thuộc về người lớn.

Đồng bộ hoá trên nhiều thiết bị

Cờ SyncAcrossDevices kiểm soát việc dữ liệu ContinuationCluster của người dùng có được đồng bộ hoá trên các thiết bị như TV, điện thoại, máy tính bảng, v.v. hay không. Theo mặc định, tính năng đồng bộ hoá trên nhiều thiết bị sẽ bị tắt.

Giá trị:

  • true: Dữ liệu ContinuationCluster được chia sẻ trên tất cả các thiết bị của người dùng để mang đến trải nghiệm xem liền mạch. Bạn nên dùng lựa chọn này để có trải nghiệm tốt nhất trên nhiều thiết bị.
  • false: Dữ liệu ContinuationCluster chỉ được dùng trên thiết bị hiện tại.

Ứng dụng đa phương tiện phải cung cấp một chế độ cài đặt rõ ràng để bật/tắt tính năng đồng bộ hoá trên nhiều thiết bị. Giải thích lợi ích cho người dùng, lưu trữ lựa chọn ưu tiên của người dùng một lần và áp dụng lựa chọn đó trong publishContinuationCluster cho phù hợp.

// Example to allow cross device syncing.
client.publishContinuationCluster(
    PublishContinuationClusterRequest
        .Builder()
        .setContinuationCluster(
            ContinuationCluster.Builder()
                .setAccountProfile(accountProfile)
                .setSyncAcrossDevices(true)
                .build()
        )
        .build()
)

Để khai thác tối đa tính năng trên nhiều thiết bị, hãy xác minh rằng ứng dụng có được sự đồng ý của người dùng và bật SyncAcrossDevices thành true. Nhờ đó, nội dung có thể đồng bộ hoá liền mạch trên các thiết bị, mang lại trải nghiệm tốt hơn cho người dùng và tăng mức độ tương tác. Ví dụ: một đối tác đã triển khai tính năng này nhận thấy số lượt nhấp vào nút "xem tiếp" tăng 40% vì nội dung của họ xuất hiện trên nhiều thiết bị.

Xoá dữ liệu Khám phá video

Để xoá dữ liệu của người dùng khỏi máy chủ Google TV theo cách thủ công trước thời hạn lưu giữ tiêu chuẩn là 60 ngày, hãy sử dụng phương thức client.deleteClusters(). Khi nhận được yêu cầu, dịch vụ sẽ xoá tất cả dữ liệu hiện có về hoạt động khám phá video cho hồ sơ tài khoản hoặc cho toàn bộ tài khoản.

Liệt kê DeleteReason xác định lý do xoá dữ liệu. Đoạn mã sau đây sẽ xoá dữ liệu xem tiếp khi người dùng đăng xuất.


// If the user logs out from your media app, you must make the following call
// to remove continue watching data from the current google TV device,
// otherwise, the continue watching data will persist on the current
// google TV device until 60 days later.
client.deleteClusters(
    DeleteClustersRequest.Builder()
        .setAccountProfile(AccountProfile())
        .setReason(DeleteReason.DELETE_REASON_USER_LOG_OUT)
        .setSyncAcrossDevices(true)
        .build()
)

Thử nghiệm

Sử dụng ứng dụng xác minh để xác minh rằng quá trình tích hợp Engage SDK đang hoạt động chính xác. Ứng dụng xác minh cung cấp các công cụ giúp bạn xác minh dữ liệu và xác nhận rằng các ý định truyền tin đang được xử lý đúng cách.

Sau khi bạn gọi API xuất bản, hãy xác nhận rằng dữ liệu của bạn đang được xuất bản chính xác bằng cách kiểm tra ứng dụng xác minh. Cụm tiếp tục của bạn sẽ xuất hiện dưới dạng một hàng riêng biệt trong giao diện của ứng dụng.

  • Chỉ đặt Cờ dịch vụ tương tác cho các bản dựng không phải bản phát hành trong tệp kê khai Android của ứng dụng.
  • Cài đặt và mở ứng dụng Engage Verify
  • Nếu isServiceAvailablefalse, hãy nhấp vào nút "Bật/tắt" để bật.
  • Nhập tên gói của ứng dụng để tự động xem dữ liệu đã xuất bản sau khi bạn bắt đầu xuất bản.
  • Kiểm thử các thao tác sau trong ứng dụng của bạn:
    • Đăng nhập.
    • Chuyển đổi giữa các hồ sơ(nếu có).
    • Bắt đầu, sau đó tạm dừng video hoặc quay lại trang chủ.
    • Đóng ứng dụng trong khi video đang phát.
    • Xoá một mục khỏi hàng "Xem tiếp" (nếu được hỗ trợ).
  • Sau mỗi thao tác, hãy xác nhận rằng ứng dụng của bạn đã gọi API publishContinuationClusters và dữ liệu được hiển thị chính xác trong ứng dụng xác minh.
  • Ứng dụng xác minh sẽ hiển thị dấu kiểm "Ổn cả" màu xanh lục cho các thực thể được triển khai đúng cách.

    Ảnh chụp màn hình ứng dụng xác minh thành công
    Hình 1. Ứng dụng xác minh thành công
  • Ứng dụng xác minh sẽ gắn cờ mọi thực thể có vấn đề.

    Ảnh chụp màn hình lỗi ứng dụng xác minh
    Hình 2. Lỗi ứng dụng xác minh
  • Để khắc phục các thực thể có lỗi, hãy dùng điều khiển từ xa của TV để chọn và nhấp vào thực thể trong ứng dụng xác minh. Các vấn đề cụ thể sẽ xuất hiện và được đánh dấu bằng màu đỏ để bạn xem xét (xem ví dụ bên dưới).

    Thông tin chi tiết về lỗi của Ứng dụng xác minh
    Hình 3. Thông tin chi tiết về lỗi ứng dụng xác minh

API REST

Engage SDK cung cấp một REST API để mang đến trải nghiệm xem tiếp nhất quán trên các nền tảng không phải Android, chẳng hạn như iOS, Roku TV. API này cho phép nhà phát triển cập nhật trạng thái "Xem tiếp" cho những người dùng đã chọn sử dụng tính năng này trên các nền tảng không phải Android.

Điều kiện tiên quyết

  • Trước tiên, bạn phải hoàn tất quy trình tích hợp dựa trên Engage SDK trên thiết bị. Bước quan trọng này thiết lập mối liên kết cần thiết giữa mã nhận dạng người dùng của Google và AccountProfile của ứng dụng.
  • Quyền truy cập và xác thực API: Để xem và bật API trong Dự án Google Cloud, bạn phải trải qua quy trình đưa vào danh sách cho phép. Tất cả các yêu cầu API đều yêu cầu xác thực.

Có được quyền truy cập

Để có quyền truy cập vào API và bật API trong Google Cloud Console, bạn cần đăng ký tài khoản.

  1. Bạn phải có mã khách hàng Google Workspace. Nếu không có sẵn, bạn có thể cần thiết lập Google Workspace cũng như mọi Tài khoản Google mà bạn muốn dùng để gọi API.
  2. Thiết lập tài khoản bằng Google Cloud Console bằng cách sử dụng email được liên kết với Google Workspace.
  3. Tạo dự án mới
  4. Tạo một tài khoản dịch vụ để xác thực API. Sau khi tạo tài khoản dịch vụ, bạn sẽ có 2 mục sau:
    • Mã tài khoản dịch vụ.
    • Một tệp JSON chứa khoá tài khoản dịch vụ của bạn. Hãy bảo mật tệp này, bạn sẽ cần tệp này để xác thực ứng dụng sau này.
  5. Giờ đây, Workspace và các Tài khoản Google liên kết có thể sử dụng API REST. Sau khi thay đổi được truyền tải, bạn sẽ nhận được thông báo về việc API đã sẵn sàng để được tài khoản dịch vụ của bạn gọi hay chưa.
  6. Hãy làm theo các bước này để chuẩn bị thực hiện một lệnh gọi API được uỷ quyền.

Xuất bản Cụm Tiếp tục

Để xuất bản Dữ liệu khám phá video, hãy thực hiện yêu cầu POST đến API publishContinuationCluster bằng cú pháp sau.

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/profiles/{profile_id}/publishContinuationCluster

Trong trường hợp:

  • package_name: Tên gói của nhà cung cấp nội dung nghe nhìn
  • accountId: Mã nhận dạng duy nhất cho tài khoản của người dùng trong hệ thống của bạn. Khoá này phải khớp với accountId được dùng trong đường dẫn trên thiết bị.
  • profileId: Mã nhận dạng duy nhất cho hồ sơ người dùng trong tài khoản trong hệ thống của bạn. Mã này phải khớp với profileId được dùng trong đường dẫn trên thiết bị.

URL của tài khoản không có hồ sơ là:

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/publishContinuationCluster

Tải trọng cho yêu cầu được biểu thị trong trường entities. entities đại diện cho danh sách các thực thể nội dung có thể là MovieEntity hoặc TVEpisodeEntity. Đây là trường bắt buộc.

Nội dung yêu cầu

Trường

Loại

Bắt buộc

Nội dung mô tả

thực thể

Danh sách các đối tượng MediaEntity

Danh sách các thực thể nội dung (tối đa 5), chỉ 5 thực thể hàng đầu sẽ được giữ lại và những thực thể còn lại sẽ bị loại bỏ.Danh sách trống được phép cho biết người dùng đã xem xong tất cả các thực thể.

Trường entities chứa movieEntitytvEpisodeEntity riêng lẻ.

Trường

Loại

Bắt buộc

Nội dung mô tả

movieEntity

MovieEntity

Một đối tượng đại diện cho một bộ phim trong ContinuationCluster.

tvEpisodeEntity

TvEpisodeEntity

Một đối tượng đại diện cho một tập của chương trình truyền hình trong ContinuationCluster.

Mỗi đối tượng trong mảng thực thể phải là một trong các loại MediaEntity có sẵn, cụ thể là MovieEntityTvEpisodeEntity, cùng với các trường chung và theo loại.

Đoạn mã sau đây minh hoạ tải trọng của phần nội dung yêu cầu cho API publishContinuationCluster.

{
  "entities": [
    {
      "movieEntity": {
        "watch_next_type": "WATCH_NEXT_TYPE_CONTINUE",
        "name": "Movie1",
        "platform_specific_playback_uris": [
          "https://www.example.com/entity_uri_for_android",
          "https://www.example.com/entity_uri_for_iOS"
        ],
        "poster_images": [
          "http://www.example.com/movie1_img1.png",
          "http://www.example.com/movie1_imag2.png"
        ],
        "last_engagement_time_millis": 864600000,
        "duration_millis": 5400000,
        "last_play_back_position_time_millis": 3241111
      }
    },
    {
      "tvEpisodeEntity": {
        "watch_next_type": "WATCH_NEXT_TYPE_CONTINUE",
        "name": "TV SERIES EPISODE 1",
        "platform_specific_playback_uris": [
          "https://www.example.com/entity_uri_for_android",
          "https://www.example.com/entity_uri_for_iOS"
        ],
        "poster_images": [
          "http://www.example.com/episode1_img1.png",
          "http://www.example.com/episode1_imag2.png"
        ],
        "last_engagement_time_millis": 864600000,
        "duration_millis": 1800000,
        "last_play_back_position_time_millis": 2141231,
        "episode_display_number": "1",
        "season_number": "1",
        "show_title": "title"
      }
    }
  ]
}

Xoá dữ liệu khám phá video

Dùng API clearClusters để xoá dữ liệu khám phá video.

Sử dụng URL POST để xoá các thực thể khỏi dữ liệu khám phá video. Để xoá dữ liệu cụm tiếp tục, hãy thực hiện yêu cầu POST đến API clearClusters bằng cú pháp sau.

https://tvvideodiscovery.googleapis.com/v1/packages/{package_name}/accounts/{account_id}/profiles/{profile_id}/clearClusters

Trong trường hợp:

  • package_name: Tên gói của nhà cung cấp nội dung nghe nhìn.
  • accountId: Mã nhận dạng duy nhất cho tài khoản của người dùng trong hệ thống của bạn. Khoá này phải khớp với accountId được dùng trong đường dẫn trên thiết bị.
  • profileId: Mã nhận dạng duy nhất cho hồ sơ người dùng trong tài khoản trong hệ thống của bạn. Mã này phải khớp với profileId được dùng trong đường dẫn trên thiết bị.

Tải trọng cho API clearClusters chỉ chứa một trường reason, trong đó có một DeleteReason chỉ định lý do xoá dữ liệu.

{
  "reason": "DELETE_REASON_LOSS_OF_CONSENT"
}

Thử nghiệm

Sau khi đăng dữ liệu thành công, hãy dùng tài khoản kiểm thử người dùng để xác minh rằng nội dung dự kiến xuất hiện trong hàng "Xem tiếp" trên các nền tảng mục tiêu của Google, chẳng hạn như Google TV và ứng dụng di động Google TV trên Android và iOS.

Trong quá trình kiểm thử, hãy cho phép độ trễ truyền dữ liệu hợp lý trong vài phút và tuân thủ các yêu cầu về việc xem, chẳng hạn như xem một phần của phim hoặc xem xong một tập. Hãy tham khảo Nguyên tắc về danh sách Xem tiếp dành cho nhà phát triển ứng dụng để biết thông tin chi tiết.

Tải xuống

Trước khi tải xuống, bạn phải đồng ý với các điều khoản và điều kiện sau.

Ðiều khoản và điều kiện

以下是 Android 软件开发套件许可协议

1. 简介

1.1 Google 会按照本许可协议的条款向您授予使用 Android 软件开发套件(在本许可协议中称为“SDK”,具体包括 Android 系统文件、一些已打包好的 API 和一些 Google API 插件)的许可。本许可协议是您和 Google 之间就您使用 SDK 而达成的具有法律约束力的合约。 1.2“Android”是指通过 Android 开源项目(项目网址为:https://source.android.com/)提供的用于设备的 Android 软件堆栈(会不时更新)。1.3“兼容实现”是指满足以下条件的任何 Android 设备:(i) 符合 Android 兼容性定义文档(位于 Android 兼容性网站 https://source.android.com/compatibility 上,会不时更新)的要求;(ii) 成功通过 Android 兼容性测试套件 (CTS) 测试。 1.4“Google”是指 Google LLC,一家按照美国特拉华州法律成立并按照美国法律运营的公司,其主要营业地点为 1600 Amphitheatre Parkway, Mountain View, CA 94043, USA。

2. 接受本许可协议

2.1 要使用 SDK,您必须先同意本许可协议。如果您不接受本许可协议,则无法使用 SDK。 2.2 点击接受和/或使用此 SDK,即表示您特此同意本许可协议的条款。 2.3 如果美国或其他国家/地区(包括您居住或使用 SDK 时所在的国家/地区)的法律禁止您作为自然人获取 SDK,则您无法使用 SDK,也无法接受本许可协议。 2.4 如果您代表您的雇主或其他实体同意受本许可协议约束,则您声明并保证您拥有充足的法定权力来让您的雇主或上述实体受本许可协议的约束。如果您不具备必要的授权,则不得代表您的雇主或其他实体接受本许可协议或使用 SDK。

3. Google 授予的 SDK 许可

3.1 Google 依据本许可协议的条款授予您有限的、全球性、免版税、不可转让、非独占性且不可再许可的 SDK 使用许可,其用途仅限针对 Android 的兼容实现来开发应用。 3.2 您不得使用此 SDK 来开发适用于其他平台(包括 Android 的非兼容实现)的应用或开发其他 SDK。您当然可以随意开发用于其他平台(包括 Android 的非兼容实现)的应用,但不能将此 SDK 用于该目的。 3.3 您同意 Google 或第三方拥有此 SDK 的所有法定权利、所有权和利益,包括此 SDK 中存在的所有知识产权。“知识产权”是指专利法、版权法、商业秘密法、商标法以及任何和所有其他所有权法案中现行规定的任何及所有权利。Google 保留未明确授予您的所有权利。 3.4 您不得将 SDK 用于本许可协议未明确允许的任何用途。除非适用的第三方许可有相关要求,您不得对 SDK 或 SDK 的任何部分进行复制(备份用途除外)、修改、改编、再分发、反编译、逆向工程、反汇编或创建其衍生作品。 3.5 对于依据开源软件许可授权的 SDK 组件,其使用、复制和分发仅受该开源软件许可条款的制约,不受本许可协议的约束。 3.6 您同意 Google 所提供的 SDK 可在未事先通知您的情况下出现形式和性质上的改变,并且未来的 SDK 版本可以不兼容在较早的 SDK 版本上开发的应用。您同意,一般情况下,Google 可在不事先通知您的情况下自行决定(永久或暂时)停止向您或更多用户提供 SDK(或 SDK 内的任何功能)。 3.7 本许可协议中的任何内容均未授权您使用 Google 的任何商品名、商标、服务商标、徽标、域名或其他显著品牌特征。 3.8 对于 SDK 中可能附带或包含的任何所有权声明(包括版权和商标通告),您同意不会移除、模糊处理或更改这些声明。

4. 您对 SDK 的使用

4.1 Google 同意,对于您使用 SDK 开发的任何软件应用,Google 不能以本许可协议为由从您(或您的许可方)处获取这些应用的权利、所有权或利益,包括这些应用中存在的任何知识产权。 4.2 您同意,只在 (a) 本许可协议和 (b) 相关司法辖区内的任何适用法律法规或公认的惯例或准则(包括任何与从美国或其他相关国家/地区进口或向其出口数据或软件相关的法律)允许的情况下使用 SDK 以及编写应用。 4.3 您同意,如果您使用 SDK 开发面向一般公众用户的应用,您将会保护这些用户的隐私权和合法权利。如果用户向您提供用户名、密码或其他登录信息或个人信息,您必须确保用户知晓这些信息将供您的应用使用,并且您必须为这些用户提供足以满足法律要求的隐私权声明和保护。如果您的应用存储了用户提供的个人信息或敏感信息,则必须安全存储这类信息。如果用户为您的应用提供了 Google 账号信息,您的应用只能在用户允许时出于用户所许可的有限目的使用该信息访问用户的 Google 账号。 4.4 您同意您不会利用 SDK 从事任何干扰、破坏、损坏或以未经授权方式访问任何第三方(包括但不限于 Google 或任何移动通信运营商)的服务器、网络或其他财产或服务的行为(包括应用的开发或分发)。 4.5 您同意,对于您通过 Android 和/或 Android 版应用创建、传输或显示的任何数据、内容或资源,以及由此造成的任何后果(包括 Google 可能会蒙受的任何损失或损害),您要承担全部责任,且 Google 对您或任何第三方不承担任何责任。 4.6 您同意,对于未按本许可协议、任何适用的第三方合同或服务条款或任何适用法律法规的规定履行义务的任何行为以及由此造成的后果(包括 Google 或任何第三方可能会蒙受的损失或损害),您承担全部责任,且 Google 对您或任何第三方均不承担任何责任。

5. 开发者凭据

5.1 您同意负责维护 Google 向您发放或您自行选择的任何开发者凭据的机密性,并且对使用您的开发者凭据开发的所有应用承担全部责任。

6. 隐私权和信息

6.1 为了不断地对 SDK 进行创新和改进,Google 可能会通过软件收集某些使用情况统计信息,包括但不限于唯一标识符、关联的 IP 地址、软件版本号,以及关于 SDK 中正在使用的工具和/或服务以及使用方式的信息。在收集任何上述信息之前,SDK 都会通知您并征求您的同意。未经您同意,Google 不会擅自收集此类信息。6.2 Google 会对收集的数据进行汇总分析,从而改进 SDK,并会按照 Google 隐私权政策(网址为 https://policies.google.com/privacy)维护这些数据。 6.3 为了改进 SDK,我们可能会与 Google 合作伙伴分享经过匿名化和汇总处理的数据集。

7. 第三方应用

7.1 如果您使用 SDK 运行由第三方开发的应用,或者运行会访问由第三方提供的数据、内容或资源的应用,则您须同意 Google 对于此类应用、数据、内容或资源概不负责。您了解,对于您可通过此类第三方应用访问的所有数据、内容或资源,均由最初提供这些内容的人员承担全部责任;对于您因使用或访问任何此类第三方应用、数据、内容或资源而可能蒙受的任何损失或损坏,Google 概不负责。 7.2 您应了解,通过此类第三方应用向您提供的数据、内容和资源可能会受到提供者(或代表他们的其他个人或公司)所拥有的知识产权的保护。除非相关所有者明确给予许可,否则您不得修改、出租、租赁、借出、出售、分发这些数据、内容或资源(全部或部分),也不得以其为基础创建衍生作品。 7.3 您承认,您对此类第三方应用、数据、内容或资源的使用行为可能会受到您与相关第三方之间达成的独立条款的制约。在这种情况下,本许可协议不会影响您与这些第三方之间的法律关系。

8. 使用 Android API

8.1 Google 数据 API 8.1.1 如果您使用任何 API 从 Google 检索数据,即表示您承认这些数据可能会受到 Google 或这些数据的提供方(或者代表他们的其他人员或公司)拥有的知识产权的保护。使用任何此类 API 时,您可能会受到附加服务条款的制约。除非相关服务条款允许,否则您不得修改、出租、租赁、借出、出售、分发这些数据(全部或部分),也不得以其为基础创建衍生作品。 8.1.2 如果您使用任何 API 从 Google 检索用户数据,即表示您承认并同意,您只有在征得用户明确同意时才会检索数据,并且只能在用户允许时出于用户许可的有限目的检索数据。如果您使用 Android Recognition Service API(请参阅以下网址对应的文档:https://developer.android.com/reference/android/speech/RecognitionService,其内容会不时更新),即表示您承认使用此 API 时需遵循针对以 Google 作为数据处理方的产品的数据处理附录(附录网址为 https://privacy.google.com/businesses/gdprprocessorterms/,其内容会不时更新)。点击接受,即表示您特此同意遵循与数据处理方为 Google 的产品相关的数据处理附录的相关条款。

9. 终止本许可协议

9.1 本许可协议将持续有效,直至您或 Google 按以下规定终止本协议。 9.2 如果您想终止本许可协议,可通过停止使用 SDK 以及任何相关开发者凭据予以终止。 9.3 如果出现以下任意情况,Google 可随时终止本许可协议: (A) 您违反了本许可协议的规定;或 (B) 根据法律 Google 必须终止本协议;或 (C) 与 Google 合作向您提供 SDK 的特定部分(例如 API)的合作伙伴终止了与 Google 的合作关系,或者不再向您提供 SDK 的特定部分;或 (D) Google 决定不再向您所居住的国家/地区,或您使用相关服务时所在的国家/地区提供 SDK 或 SDK 的特定部分,或者 Google 单方面判定向您提供 SDK 或特定的 SDK 服务不再具有商业可行性。 9.4 当本许可协议终止时,您与 Google 受益于、受制于(或在本许可协议有效期内随时间累积)或明示将无限期延续的所有法定权利、义务和责任将不受此终止的影响,并且第 14.7 段的规定将继续无限期地适用于上述权利、义务和责任。

10. 免责声明

10.1 您明确了解并同意自行承担使用 SDK 的风险,并且 SDK 是“按原样”和“现状”提供,不由 Google 提供任何类型的保证。 10.2 您对 SDK 的使用以及通过 SDK 下载或以其他方式获得的任何材料的使用均由您自行斟酌并承担相关风险,对于由此给您的设备或计算机系统造成的任何数据损坏,您必须自行承担10.3 Google 另外明确声明,对于任何形式(无论是明示或暗示)的保证和条件,包括但不限于关于适销性、

11. 责任限制

11.1 因任何原因导致 Google、其子公司和关联公司及其许可方因任何原因,

12. 赔偿

12.1 您同意在法律允许的最大范围内,为 Google、其关联公司及其各自的董事、高级职员、员工和代理人出于任何和所有索赔、诉讼、诉讼或程序,以及任何和所有损失、法律责任、损害、

13. 许可协议的变更

13.1 Google 在发布新版 SDK 时可能会对本许可协议进行一些变更。做出这些更改后,Google 将在提供 SDK 的网站上公布新版本的许可协议。 14.1 本许可协议构成您和 Google 之间的完整法律协议,且您对 SDK 的使用(不包括 Google 根据单独书面协议为您提供的任何服务)将受本协议的约束。同时,本协议将完全取代您和 Google 之前就 SDK 达成的任何协议。 14.2 您同意,即使 Google 未行使或强制执行本许可协议中所述的(或 Google 根据任何适用法律所享有的)任何法定权利或补救措施,也不应视为 Google 正式自动放弃这些权利,Google 仍然可以行使这些权利或采取相应补救措施。 14.3 如果对此类事项有司法管辖权的任何法院判定本许可协议的任何规定无效,我们会将相应规定从本许可协议中移除,本协议其余部分不受影响。本许可协议的其余条款将继续有效并可强制执行。 14.4 您承认并同意,Google 的每一个子公司都应为本许可协议的第三方受益人,此类其他公司应有权直接执行本许可协议,并根据本许可协议的规定主张相关权益(或有利于他们的权利)。除此之外,其他任何个人或公司均不得成为本许可协议的第三方受益人。 14.5 出口限制。SDK 会受到美国出口法律和法规的限制。您必须遵守所有适用于 SDK 的国内以及国际出口法律和法规。这些法律包括对目的地、最终用户和最终用途的限制。 14.6 未经另一方的事先书面许可,您或 Google 不得转让或转移本许可协议中授予的权利。未经另一方事先书面批准,您或 Google 均不得将其在本许可协议下的责任或义务委托给他人。 14.7 本许可协议以及您与 Google 依据本许可协议而建立的关系应受美国加利福尼亚州法律(该州的法律冲突条款除外)的约束。您和 Google 同意服从加利福尼亚州圣克拉拉县法院的专有司法辖权,以此来解决因本许可协议产生的任何法律事务。尽管有上述规定,您同意仍允许 Google 在任何管辖区申请禁令救济(或同等类型的紧急法律救济)。 2021 年 7 月 27 日
Tải

verify_app_multiplatform_public_20250602.apk