הטמעת ממשק ה-API לצפייה משותפת

בדף הזה נסביר איך להשתמש ב-API לצפייה משותפת כדי לתמוך בתרחיש של צפייה משותפת.

הגדרה ראשונית

כדי להכין את הספרייה לשימוש, אפליקציית השיתוף בזמן אמת צריכה לאתחל CoWatchingClient שמייצג פעילות של צפייה משותפת.

כדי להשתמש ב-SDK של שיתוף בזמן אמת ב-Meet, צריך להתקשר AddonClientFactory.getClient . הפעולה הזו תחזיר AddonClient המשמשת כנקודת הכניסה לפעילות של צפייה משותפת.

כדי להשתמש בלקוח, קוראים לפונקציה newSessionBuilder מ-AddonClient כדי להחזיר builder עבור AddonSession. newSessionBuilder מיישם את AddonSessionHandler הממשק שמטפל בקריאות חוזרות (callbacks) שסופקו על ידי עבור הסשן.

כדי להתחיל סשן, צריך להוסיף את withCoWatching ל-builder.

דוגמת הקוד הבאה מציגה אתחול בסיסי של הלקוח לצפייה משותפת object:

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));
  }
}