تطبيق واجهة برمجة التطبيقات الخاصة بميزة "مشاهدة المحتوى مع الآخرين"

توضّح هذه الصفحة كيفية استخدام Co-Watching API لدعم سيناريو المشاهدة مع الآخرين.

الإعداد الأولي

لإعداد المكتبة للاستخدام، يجب أن يقوم تطبيق المشاركة المباشرة بتهيئة CoWatchingClient يمثل جلسة مشاهدة مشتركة.

لاستخدام حزمة تطوير البرامج (SDK) للمشاركة المباشرة في Meet، عليك الاتصال AddonClientFactory.getClient . ينتج عن ذلك AddonClient تمثل نقطة الدخول لجلسة المشاهدة مع الآخرين.

لاستخدام البرنامج، اتصل newSessionBuilder من AddonClient لإرجاع أداة إنشاء AddonSession تنفِّذ newSessionBuilder السمة AddonSessionHandler لمعالجة طلبات معاودة الاتصال التي يوفرها للجلسة.

لبدء جلسة، أضِف withCoWatching على منصة الإنشاء.

يعرض نموذج الرمز البرمجي التالي إعدادًا أساسيًا لبرنامج المشاهدة مع الآخرين. الكائن:

Java

class AwesomeVideoAddonSessionHandler implements AddonSessionHandler {}

// For sample implementation, see the "Manage remote state" section below.
class AwesomeVideoCoWatchingHandler implements CoWatchingHandler {}

public ListenableFuture<AddonSession> initialSetup() {
  AddonClient meetClient = AddonClientFactory.getClient();
  return meetClient
      .newSessionBuilder(
          new AwesomeVideoAddonSessionHandler())
      .withCoWatching(new AwesomeVideoCoWatchingHandler())
      .begin();
}

إرسال إشعارات إلى إجراءات المستخدم

عندما ينفِّذ المستخدم المحلي إجراءات، مثل إيقاف الوسائط مؤقتًا أو البحث عنها على أجهزتهم - يجب إبلاغ المكتبة بحيث يمكن إلى المشاركين الآخرين في تجربة المشاهدة مع الآخرين. للحصول على مثال على لمعرفة كيفية إرسال إشعار إلى المكتبة لحالات متعدّدة، راجِع الحصول على البدء.

يمكنك التحكّم في حالة المشاهدة مع الآخرين بالطُرق التالية:

  • CoWatchingClient.notifyBuffering: إرسال إشعار إلى Meet بأنّ الوسائط غير جاهزة لتشغيلها بسبب إلى التخزين المؤقت بسبب تبديل وسائط سابق أو تشغيل الوسائط أو شبكة عادية للاحتقان.
  • CoWatchingClient.notifyEnded: إرسال إشعار إلى Meet بأنّ مشغّل الوسائط وصل إلى نهاية الوسائط الحالية.
  • CoWatchingClient.notifyPauseState إرسال إشعار إلى Meet بأنّ المستخدم أوقف التشغيل مؤقتًا أو استأنفه من الوسائط، حتى يتمكن تطبيق Meet من إجراء نسخ مطابق لهذا الإجراء لدى المستخدمين الآخرين.
  • CoWatchingClient.notifyPlayoutRate: إبلاغ Meet بأنّ المستخدم عدَّل معدّل تشغيل الوسائط إلى قيمة جديدة (على سبيل المثال، 1.25x).
  • CoWatchingClient.notifyQueueUpdate: إبلاغ Meet بتغيير قائمة الانتظار، وبالتالي يمكن لتطبيق Meet إجراء نسخ مطابق لمحتوى المستخدمين الآخرين.
  • CoWatchingClient.notifyReady: إبلاغ Meet باكتمال التخزين المؤقت وأن الوسائط جاهزة للتشغيل، بدءًا من الطابع الزمني المقدم.
  • CoWatchingClient.notifySeekToTimestamp: إبلاغ Meet بأنّ المستخدم طلب نقطة تشغيل الوسائط، حتى يتمكن تطبيق Meet من إجراء نسخ مطابق لهذا الإجراء لدى المستخدمين الآخرين.
  • CoWatchingClient.notifySwitchedToMedia: إبلاغ Meet بأنّ المستخدم بدّل الوسائط، لذا يمكن لتطبيق Meet تمرير ذلك إلى مستخدمين آخرين. يتوفر أيضًا خيار لإجراء تحديث متزامن لقائمة الانتظار.

يعرض نموذج الرمز البرمجي التالي كيفية إشعار المستخدمين:

Java

public void onVideoPaused(Duration currentTimestamp) {
  // Use Meet to broadcast the pause state to ensure other participants also pause.
  this.session.getCoWatching().notifyPauseState(/* paused= */ true, currentTimestamp);
};

إدارة الحالة عن بُعد

لتطبيق التحديثات الواردة من المشاركين عن بُعد، يجب توفير تعرَّف على طريقة لإدارة حالة تشغيل الوسائط المحلية مباشرةً باستخدام الـ CoWatchingHandler.onCoWatchingStateChanged() معاودة الاتصال.

يحتاج تطبيق Meet أيضًا إلى استرداد الوضع الحالي للوسائط من خلال استدعاء CoWatchingHandler.onStateQuery() معاودة الاتصال. يسمى هذا بانتظام، لذلك يجب كتابته ليكون بأداء (على سبيل المثال، أقل من 100 ملي ثانية).

يوضح نموذج الرمز البرمجي التالي تنفيذًا CoWatchingHandler:

Java

class AwesomeVideoCoWatchingHandler implements CoWatchingHandler {
  /** Applies incoming playback state to the local video. */
  public void onCoWatchingStateChanged(CoWatchingState newState) {
    // Handle transition to new video.
    if (!newState.mediaId().equals(this.videoPlayer.videoUrl)) {
      this.videoPlayer.loadVideo(newState.mediaId());
    }

    // Only adjust the local video playout if it's sufficiently diverged from the timestamp in the
    // applied update.
    if (newState
            .mediaPlayoutPosition()
            .minus(this.videoPlayer.videoTimestamp)
            .compareTo(Duration.ofMillis(500))
        > 0) {
      this.videoPlayer.seek(newState.mediaPlayoutPosition());
    }

    // Update pause state, if necessary.
    if (newState.playbackState().equals(PLAY) && this.videoPlayer.isPaused) {
      this.videoPlayer.unpause();
    } else if (newState.playbackState().equals(PAUSE) && !this.videoPlayer.isPaused) {
      this.videoPlayer.pause();
    }
  }

  /** Returns local video playback state. */
  public Optional<QueriedCoWatchingState> onStateQuery() {
    return Optional.of(QueriedCoWatchingState.of(
      /* mediaPlayoutPosition= */ this.videoPlayer.videoTimestamp));
  }
}