تنفيذ واجهة برمجة التطبيقات 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 الأخرى المشارِكة في تجربة المشاركة المباشرة. للاطّلاع على تفاصيل حول كيفية تلقّي آخر الأخبار من مشارِكين آخرين، يُرجى الانتقال إلى قسم التعامل مع التحديثات الواردة.

يصف الرسم البياني التالي تسلسل الأحداث بعد تشغيل إجراء الإيقاف المؤقت:

بدء الرسم البياني لواجهة برمجة التطبيقات الخاصة بميزة &quot;المشاركة المباشرة&quot;

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

كما هي الحال في إيقاف الفيديو مؤقتًا، إذا ألغى المستخدم الإيقاف المؤقت للفيديو على تطبيقه المحلي، على تطبيق 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();
}

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

عندما يتلقّى تطبيق 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();
    }
  }
}