تنفيذ واجهة برمجة التطبيقات Co-Doing API

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

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

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

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

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

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

يعرض نموذج الرمز البرمجي التالي إعدادًا أساسيًا للبرنامج المشترَك الكائن:

Java

class AwesomeVideoAddonSessionHandler implements AddonSessionHandler {}

//For sample implementation, see the "Handle incoming updates" section.
class AwesomeVideoCoDoingHandler implements CoDoingHandler {}

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

إيقاف الفيديو مؤقتًا

عند المشاركة في تجربة مشاركة مباشرة، في حال أوقف المستخدم التشغيل مؤقتًا على تطبيق الفيديو المحلي، فيجب التأكد من أن جميع المشاركين في البث المباشر مشاركة تجربة المستخدم أيضًا إيقاف الفيديو مؤقتًا.

للقيام بذلك، قم بصياغة CoDoingState رسالة توضّح أنّ الفيديو متوقف مؤقتًا، واطلب من Google Meet البث إليه جميع المشاركين الآخرين باستخدام setGlobalState . تصبح الحالة العامة المشتركة هي الحالة الافتراضية لجميع المشاركين، الحالية أو الجديدة إلى أن يتم تعيين حالة جديدة.

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

Java

public void onVideoPaused(String videoUrl, Instant currentTimestamp) {
  // Create an internal state object to share with other participants. Note: It's
  // good practice to encode all metadata—even seemingly irrelevant data—into
  // ActivityState updates to guard against race conditions and other subtle
  // failures.
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(true)
    .build();

  // Create the CoDoingState object to wrap the internal state
  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  // Use Meet to broadcast internal state update to all other participants
  this.coDoingClient.setGlobalState(coDoingState);
};

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

يوضِّح الرسم البياني التالي تسلسل الأحداث بعد إجراء الإيقاف المؤقت مُشغَّلة:

بدء الرسم التوضيحي لواجهة برمجة تطبيقات المشاركة المباشرة.

إلغاء الإيقاف المؤقت للفيديو

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

وعلى جانب المرسل (المستخدم الذي يستأنف الفيديو)، يتمثل الاختلاف الوحيد مثال الإيقاف المؤقت هو تعديل الحالة isPaused.

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

Java

public void onVideoUnpaused(String videoUrl, Instant currentTimestamp) {
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(false)
    .build();

  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  this.coDoingClient.setGlobalState(coDoingState);
}

البحث عن فيديو

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

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

Java

public void onVideoSeeked(String videoUrl, Instant currentTimestamp, bool isPaused) {
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(isPaused)
    .build();

  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  this.coDoingClient.setGlobalState(coDoingState);
}

تشغيل فيديو آخر

إذا غيّر المستخدم أيضًا الفيديو الذي تتم مشاهدته من خلال اختيار فيديو آخر على التطبيق المحلي، يجب أن يشغّل تطبيق Meet الفيديو الجديد لجميع عمليات المشاركة المباشرة المشاركين. يتم تخزين الفيديو الذي تم تغييره في "videoState.videoUrl".

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

Java

public void onVideoChanged(String videoUrl, Duration currentTimestamp, bool isPaused) {
  AwesomeVideoState videoState = AwesomeVideoState
    .builder()
    .videoUrl(videoUrl)
    .videoTimestamp(currentTimestamp)
    .isPaused(isPaused)
    .build();

  CoDoingState coDoingState = new CoDoingState();
  coDoingState.state = SerializationUtils.serialize(videoState);

  this.coDoingClient.setGlobalState(coDoingState);
}

إنهاء المشاركة في اللعب

عندما يختار المستخدم إنهاء النشاط، endSession إلغاء ربط طريقة الدفع بتطبيق Meet. هذا لا يفرض أن ينهي تطبيق Meet الاجتماع، ولا يتسبب في مغادرة المستخدم الاجتماع.

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

Java

public void endCoDoing() {
  this.session.endSession();
}

التعامل مع التحديثات الواردة

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

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

Java

class AwesomeVideoCoDoingHandler implements CoDoingHandler {
  public void onGlobalStateChanged(CoDoingState update) {
    AwesomeVideoState videoState = SerializationUtils.deserialize(update.state());

    // Handle transition to new video.
    if (!videoState.videoUrl.equals(this.videoPlayer.videoUrl)) {
      this.videoPlayer.loadVideo(videoState.videoUrl);
    }

    // If the timestamp in the arriving update has sufficiently diverged, adjust
    // the local video playout.
    if (videoState.videoTimestamp.minus(this.videoPlayer.videoTimestamp).abs() >
                                        Duration.ofSeconds(2)) {
      this.videoPlayer.seek(videoState.videoTimestamp);
    }

    // Update pause state, if necessary.
    if (!videoState.isPaused && this.videoPlayer.isPaused) {
      this.videoPlayer.unpause();
    } else if (videoState.isPaused && !this.videoPlayer.isPaused) {
      this.videoPlayer.pause();
    }
  }
}