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