حزمة Engage SDK لاقتراحات الفيديوهات

يحتوي هذا الدليل على تعليمات للمطوّرين لدمج محتوى فيديوهم المقترَح باستخدام Engage SDK لتعبئة تجارب الاقتراحات على مساحات عرض Google، مثل التلفزيون والأجهزة الجوّالة والأجهزة اللوحية.

تستفيد ميزة "الاقتراحات" من مجموعة الاقتراحات لعرض الأفلام والبرامج التلفزيونية من تطبيقات متعددة في مجموعة واحدة لواجهة المستخدم. يمكن لكل شريك مطوّر بث 25 عنصرًا كحد أقصى في كل مجموعة اقتراحات، ويمكن أن تتضمّن كل مجموعة 7 مجموعات اقتراحات كحد أقصى لكل طلب.

العمل التمهيدي

قبل البدء، يُرجى إكمال الخطوات التالية. ‫1. تأكَّد من أنّ تطبيقك يستهدف المستوى 19 أو أعلى لواجهة برمجة التطبيقات لإجراء عملية الدمج هذه.

  1. أضِف مكتبة com.google.android.engage إلى تطبيقك.

    هناك حِزم تطوير برامج (SDK) منفصلة لاستخدامها في عملية الدمج: حزمة لتطبيقات الأجهزة الجوّالة وحزمة لتطبيقات التلفزيون.

    للأجهزة الجوّالة

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

    للتلفزيون

    
      dependencies {
        implementation 'com.google.android.engage:engage-tv:1.0.2
      }
    
  2. اضبط بيئة خدمة Engage على الإصدار العلني في ملف AndroidManifest.xml.

    لملف APK للأجهزة الجوّالة

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

    حزمة APK للتلفزيون

    
    <meta-data
        android:name="com.google.android.engage.service.ENV"
        android:value="PRODUCTION">
    </meta-data>
    
  3. تنفيذ النشر في خدمة تعمل في المقدّمة

  4. نشر بيانات "الاقتراحات" مرة واحدة يوميًا كحد أقصى، وذلك استجابةً لأحد الخيارَين التاليَين:

    1. أول تسجيل دخول للمستخدِم في اليوم. (أو)
    2. عندما يبدأ المستخدِم التفاعل مع التطبيق.

التكامل

AppEngagePublishClient تنشر مجموعة الاقتراحات. استخدِم الطريقة publishRecommendationClusters لنشر عنصر recommendations.

استخدِم isServiceAvailable()2 للتحقّق مما إذا كانت الخدمة متاحة للدمج.

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

مجموعات الاقتراحات وطلب النشر

المجموعات هي تجميع منطقي للكيانات. توضّح أمثلة الرموز البرمجية التالية كيفية إنشاء المجموعات استنادًا إلى إعداداتك المفضّلة وكيفية إنشاء طلب نشر لجميع المجموعات.

// cluster for popular movies
val recommendationCluster1 = RecommendationCluster
  .Builder()
  .addEntity(movie)
  .addEntity(tvShow)
  .setTitle("Popular Movies")
  .build()

// cluster for top searches
val recommendationCluster2 = RecommendationCluster
  .Builder()
  .addEntity(movie)
  .addEntity(tvShow)
  .setTitle("Top Searches")
  .build()

// creating a publishing request
val recommendationRequest = PublishRecommendationClustersRequest
  .Builder()
  .setSyncAcrossDevices(true)
  .setAccountProfile(accountProfile)
  .addRecommendationCluster(recommendationCluster1)
  .addRecommendationCluster(recommendationCluster2)
  .build()

إنشاء ملف شخصي للحساب

للسماح بتجربة مخصّصة على Google TV، يُرجى تقديم معلومات عن الحساب والملف الشخصي. استخدِم AccountProfile لتقديم ما يلي:

  1. رقم تعريف الحساب: معرّف فريد يمثّل حساب المستخدم ضمن تطبيقك. ويمكن أن يكون هذا المعرّف هو رقم تعريف الحساب الفعلي أو نسخة ملفّقة بشكلٍ مناسب.
  2. رقم تعريف الملف الشخصي (اختياري): إذا كان تطبيقك يتيح استخدام ملفات شخصية متعددة ضمن حساب واحد، قدِّم معرّفًا فريدًا لملف المستخدم الشخصي المحدّد.
  3. اللغة(اختيارية): يمكنك اختياريًا تقديم اللغة المفضّلة للمستخدم. يكون هذا الحقل مفيدًا إذا كنت ترسل MediaActionFeedEntity في 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();

عندما تتلقّى الخدمة الطلب، يتم تنفيذ الإجراءات التالية في معاملة واحدة:

  • تتم إزالة بيانات RecommendationsCluster الحالية من حساب شريك المطوّر.
  • يتم تحليل البيانات الواردة من الطلب وتخزينها في ملف RecommendationsCluster المعدَّل. في حال حدوث خطأ، يتم رفض الطلب بالكامل ويتم الحفاظ على الحالة الحالية.

المزامنة على جميع الأجهزة

يتحكم الرمز SyncAcrossDevices في ما إذا كانت بيانات المستخدم المُجمَّعة في مجموعات الاقتراحات تُشارك مع Google TV وتصبح متاحة على جميع أجهزته، مثل التلفزيون والهاتف والأجهزة اللوحية. لكي يعمل الاقتراح، يجب ضبطه على true.

يجب أن يقدّم تطبيق الوسائط إعدادًا واضحًا لتفعيل ميزة المزامنة بين الأجهزة أو إيقافها. اشرح المزايا للمستخدم واحفظ إعداداته المفضّلة مرة واحدة وطبِّقها في publishRecommendations الطلب وفقًا لذلك. للاستفادة إلى أقصى حدّ من ميزة "الوصول على جميع الأجهزة"، تأكَّد من أنّ التطبيق يحصل على موافقته ويفعّل الإعدادات من SyncAcrossDevices إلى true.

حذف بيانات "اقتراحات الفيديو"

لحذف بيانات المستخدم يدويًا من خادم Google TV قبل انقضاء فترة الاحتفاظ العادية التي تبلغ 60 يومًا، استخدِم طريقة client.deleteClusters(). عندتلقّي الطلب، تحذف الخدمة جميع بيانات اكتشاف الفيديوهات الحالية في ملف التعريف الخاص بالحساب أو في الحساب بالكامل.

تحدِّد القائمة المحدَّدة DeleteReason سبب حذف البيانات. تزيل التعليمة البرمجية التالية الاقتراحات عند تسجيل الخروج.

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

الوصف

قدِّم وصفًا موجزًا لكلّ عنصر، وسيتم عرض هذا الوصف عندما يمرّر المستخدِمون مؤشر الماوس فوق العنصر، ما يقدّم لهم تفاصيل إضافية.

عناوين URL لتشغيل المحتوى الخاصة بالمنصة

أنشئ عناوين URL لتشغيل المحتوى لكل نظام أساسي متوافق: Android TV أو Android أو iOS. ويسمح ذلك للنظام باختيار عنوان URL المناسب لتشغيل الفيديو على منصته المعنيّة.

في الحالة النادرة التي تكون فيها معرّفات الموارد المنتظمة (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()

صور الملصقات

تتطلّب صور الملصقات عنوان URL وأبعادًا بالبكسل (الارتفاع والعرض). استهدِف أشكال الأجهزة المختلفة من خلال تقديم صور ملصقات متعددة، ولكن تأكَّد من أنّ جميع الصور تحافظ على نسبة عرض إلى ارتفاع 16:9 والحد الأدنى للارتفاع 200 بكسل لأجل عرض عنصر "الاقتراحات" بشكل صحيح، خاصةً ضمن مساحة الترفيه من 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، لن تحتاج إلى إنشاء عناصر منفصلة للفيلم أو البرنامج التلفزيوني، ويمكنك بدلاً من ذلك إنشاء عنصر MediaActionFeed يتضمّن الحقل المطلوب DataFeedElementId. يجب أن يكون هذا المعرّف فريدًا وأن يتطابق مع المعرّف في خلاصة إجراءات الوسائط، لأنّ ذلك يساعد في تحديد محتوى الخلاصة الذي تم نقله و إجراء عمليات بحث عن محتوى الوسائط.

val id = "dataFeedEleemntId"

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

من خلال تنفيذ هذه الخطوات، يمكن للمطوّرين دمج اقتراحات محتوى الفيديو بنجاح في Google TV، ما يؤدي إلى تعزيز استكشاف المستخدمين للمحتوى والتفاعل معه، ويمنحهم تجربة مشاهدة متّسقة ومخصّصة على جميع أجهزتهم.