หน้านี้จะอธิบายวิธีใช้ Co-Doing API เพื่อสนับสนุนการทำงานร่วมกัน สถานการณ์
การตั้งค่าเบื้องต้น
เพื่อเตรียมไลบรารีให้พร้อมใช้งาน แอปพลิเคชันการแชร์สดควรเริ่มต้น
CoDoingClient
ที่แสดงเซสชันการทำงานร่วมกัน
หากต้องการใช้ SDK การแชร์สดของ Meet ให้เรียกใช้
AddonClientFactory.getClient
ซึ่งแสดงผลเป็น
AddonClient
ซึ่งทำหน้าที่เป็นจุดแรกเข้าสำหรับเซสชันการทำงานร่วมกัน
หากต้องการใช้ไคลเอ็นต์ ให้เรียกใช้
newSessionBuilder
จาก AddonClient
เพื่อแสดงผลเครื่องมือสร้างสำหรับ
AddonSession
newSessionBuilder
ใช้เมธอด
AddonSessionHandler
ในการจัดการกับ Callback ที่ได้รับจาก
สำหรับเซสชัน
หากต้องการเริ่มเซสชัน ให้เพิ่มเมธอด
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
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีแจ้งให้ผู้ใช้ทราบเกี่ยวกับ 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()
Callback จะถูกเรียกใช้ โดยทั่วไปแล้ว การตัดสินใจให้ดีเกี่ยวกับ
ดำเนินการเพื่อตอบสนองต่อการอัปเดตที่เข้ามาใหม่ เช่น การจับคู่เฉพาะขาเข้า
การประทับเวลาของวิดีโอหากแตกต่างจากการประทับเวลาในเครื่องมากพอ
ตัวอย่างโค้ดต่อไปนี้แสดงวิธีจัดการการอัปเดตต่างๆ ที่เข้ามาใหม่
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();
}
}
}