本頁說明如何使用 Co-Doing API 協助共同工作 情境。
初始設定
為了準備程式庫使用,即時分享應用程式應將
CoDoingClient
物件。
如要使用 Meet 即時分享 SDK,請呼叫
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
」中。
以下程式碼範例說明如何將更新後的影片網址告知使用者:
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();
}
}
}