בדף הזה נסביר איך משתמשים ב-API לצפייה משותפת כדי לתמוך בתרחיש של צפייה משותפת.
הגדרה ראשונית
כדי להכין את הספרייה לשימוש, אפליקציית השיתוף בזמן אמת צריכה להפעיל אובייקט CoWatchingClient
שמייצג סשן של צפייה משותפת.
כדי להשתמש ב-SDK לשיתוף בזמן אמת ב-Meet, צריך להפעיל את השיטה AddonClientFactory.getClient
. הפעולה הזו מחזירה קוד AddonClient
שמשמש כנקודת הכניסה לסשן של צפייה משותפת.
כדי להשתמש בלקוח, קוראים לשיטה newSessionBuilder
מה-AddonClient
כדי להחזיר builder עבור AddonSession
חדש.
newSessionBuilder
מטמיע את הממשק של AddonSessionHandler
כדי לטפל בקריאות החוזרות (callback) שהתוסף בסשן מספק.
כדי להתחיל סשן, מוסיפים את השיטה withCoWatching
ל-builder.
דוגמת הקוד הבאה מציגה אתחול בסיסי של אובייקט הלקוח לצפייה משותפת:
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);
};
ניהול שמירת המצב ביעד מרוחק
כדי להחיל עדכונים נכנסים מהמשתתפים מרחוק, צריך להציע ל-Meet דרך לנהל ישירות את המצב המקומי להפעלת מדיה באמצעות הקריאה החוזרת CoWatchingHandler.onCoWatchingStateChanged()
.
בנוסף, ב-Meet צריך להפעיל את הקריאה החוזרת (callback) 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));
}
}