จับภาพสตรีมวิดีโอจากองค์ประกอบใดก็ได้

François Beaufort
François Beaufort

Screen Capture API ช่วยให้คุณจับภาพทั้งแท็บปัจจุบันได้ Element Capture API ช่วยให้คุณจับภาพและบันทึกองค์ประกอบ HTML ที่เฉพาะเจาะจงได้ ซึ่งจะเปลี่ยนการจับภาพทั้งแท็บเป็นการจับภาพซับต้นไม้ DOM ที่เฉพาะเจาะจง โดยจับภาพเฉพาะรายการที่สืบทอดโดยตรงจากองค์ประกอบเป้าหมาย กล่าวคือ ฟีเจอร์นี้จะครอบตัดและนำทั้งเนื้อหาที่บดบังและถูกบดบังออก

เหตุผลที่ควรใช้การจับองค์ประกอบ

การพิจารณาข้อกำหนดของแอปพลิเคชันการประชุมทางวิดีโอจะช่วยให้คุณเข้าใจว่า Element Capture มีประโยชน์ในกรณีใดบ้าง หากมีแอปพลิเคชันการประชุมทางวิดีโอที่ให้คุณฝังแอปพลิเคชันของบุคคลที่สามใน iframe ในบางครั้งคุณอาจต้องการจับภาพ iframe นั้นเป็นวิดีโอและส่งไปยังผู้เข้าร่วมระยะไกล

ภาพหน้าจอของการโทรผ่านวิดีโอคอลใน Chrome
Elad ใช้แอปพลิเคชันของบุคคลที่สามในการโทรผ่านวิดีโอคอนเฟอเรนซ์กับ François

การเรียกใช้ getDisplayMedia() และอนุญาตให้ผู้ใช้เลือกแท็บปัจจุบันจะเป็นการส่งแท็บปัจจุบันทั้งหมด ซึ่งมีแนวโน้มที่จะส่งวิดีโอของผู้ใช้กลับไปยังผู้ใช้ คุณสามารถครอบตัดส่วนนี้ออกได้โดยใช้การจับภาพเฉพาะพื้นที่

อย่างไรก็ตาม จะเกิดอะไรขึ้นหากผู้นำเสนอโต้ตอบกับแอปพลิเคชันการประชุมทางวิดีโอและเนื้อหาบางอย่าง เช่น รายการแบบเลื่อนลง ปรากฏขึ้นบนเนื้อหาที่มีไว้สำหรับการบันทึก

ภาพหน้าจอของรายการแบบเลื่อนลงที่บดบังเนื้อหาที่ต้องการจับภาพ
รายการแบบเลื่อนลงจะปรากฏที่ด้านบนของเนื้อหาที่ต้องการจับภาพ

การจับภาพพื้นที่ทำงานจะไม่ช่วยคุณในเรื่องนี้ รายการแบบเลื่อนลงบางส่วนอาจปรากฏบนหน้าจอของผู้เข้าร่วมระยะไกล

ภาพหน้าจอของรายการแบบเลื่อนลงที่จับภาพไว้
รายการแบบเลื่อนลงของ Elad จะปรากฏที่ด้านบนของเนื้อหาที่ François ได้รับ

การจับภาพเฉพาะพื้นที่ที่จับภาพองค์ประกอบบางส่วนด้วยวิธีนี้ (หรือที่เรียกว่าการบดบังเนื้อหา) จะทำให้เกิดปัญหาหลายประการ ดังนี้

  • การบดบังเนื้อหาอาจบดบังเนื้อหาที่ผู้ใช้ตั้งใจจะแชร์
  • เนื้อหาที่บดบังอาจเป็นเรื่องส่วนตัว (เช่น การแจ้งเตือนแชท)
  • การบดบังเนื้อหาอาจทำให้เกิดความสับสน (เช่น การจัดเรียงแอปพลิเคชันใหม่อาจแสดงวิดีโอของผู้เข้าร่วมระยะไกลเหนือเป้าหมายที่บันทึกไว้เป็นระยะเวลาสั้นๆ)

Element Capture API ช่วยแก้ปัญหาเหล่านี้ทั้งหมดโดยให้คุณกําหนดเป้าหมายองค์ประกอบที่ต้องการแชร์

ภาพหน้าจอขององค์ประกอบเป้าหมายที่ไม่มีรายการแบบเลื่อนลงในมุมมอง
François ไม่เห็นรายการแบบเลื่อนลงจาก Elad

ฉันจะใช้การจับองค์ประกอบได้อย่างไร

captureTarget คือองค์ประกอบในหน้าเว็บซึ่งมีเนื้อหาที่ผู้ใช้ต้องการบันทึก คุณต้องการให้เว็บแอปการประชุมทางวิดีโอจับภาพ captureTarget และแชร์กับผู้เข้าร่วมจากระยะไกล คุณจึงอนุมาน RestrictionTarget จาก captureTarget หลังจากจํากัดแทร็กวิดีโอโดยใช้ RestrictionTarget นี้แล้ว ตอนนี้เฟรมในแทร็กวิดีโอดังกล่าวจะประกอบด้วยเฉพาะพิกเซลที่เป็นส่วนหนึ่งของ captureTarget และ DOM สืบทอดโดยตรงเท่านั้น

หาก captureTarget เปลี่ยนขนาด รูปร่าง หรือตำแหน่ง แทร็กวิดีโอจะเปลี่ยนตามไปด้วยโดยไม่จำเป็นต้องมีการป้อนข้อมูลเพิ่มเติมจากเว็บแอปใดแอปหนึ่ง การบดบังเนื้อหาที่ปรากฏ หายไป หรือเคลื่อนไหวไปรอบๆ ก็ไม่จำเป็นต้องมีการจัดการพิเศษเช่นกัน

โปรดตรวจสอบขั้นตอนเหล่านี้อีกครั้ง

เริ่มต้นด้วยการอนุญาตให้ผู้ใช้จับภาพแท็บปัจจุบัน

// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
 preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();

กำหนด RestrictionTarget โดยการเรียกใช้ RestrictionTarget.fromElement() พร้อมองค์ประกอบที่คุณเลือกเป็นอินพุต

// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

จากนั้นเรียกใช้ restrictTo() ในแทร็กวิดีโอโดยให้ RestrictionTarget เป็นอินพุต เมื่อ Promise สุดท้ายได้รับการแก้ไขแล้ว เฟรมทั้งหมดที่ตามมาจะถูกจํากัด

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

// Enjoy! Transmit remotely.

ข้อมูลเจาะลึก

การตรวจหาองค์ประกอบ

หากต้องการตรวจสอบว่าระบบรองรับ RestrictionTarget.fromElement() หรือไม่ ให้ใช้

if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
  // Deriving a restriction target is supported.
}

ดึงข้อมูล RestrictionTarget

โฟกัสที่องค์ประกอบชื่อ captureTarget หากต้องการดึงข้อมูล RestrictionTarget จากข้อมูลดังกล่าว ให้เรียกใช้ RestrictionTarget.fromElement(captureTarget) Promise ที่แสดงผลจะได้รับการแก้ไขด้วยออบเจ็กต์ RestrictionTarget ใหม่หากดำเนินการสำเร็จ มิเช่นนั้นระบบจะปฏิเสธหากคุณสร้างออบเจ็กต์ RestrictionTarget จำนวนที่ไม่สมเหตุสมผล

const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);

ออบเจ็กต์ RestrictionTarget จัดเรียงได้ ซึ่งแตกต่างจากองค์ประกอบ เช่น คุณสามารถส่งไปยังเอกสารอื่นได้โดยใช้ Window.postMessage()

จำกัด

เมื่อบันทึกแท็บ แทร็กวิดีโอจะแสดง restrictTo() เมื่อจับภาพแท็บปัจจุบัน คุณสามารถเรียกใช้ restrictTo() ด้วย null หรือ RestrictionTarget ใดก็ได้ที่มาจากองค์ประกอบภายในแท็บปัจจุบัน

การเรียกใช้ restrictTo(restrictionTarget) จะเปลี่ยนแทร็กวิดีโอเป็นการจับภาพ captureTarget ราวกับว่ามีการวาดขึ้นมาเองโดยแยกจาก DOM ที่เหลือ ระบบจะบันทึกรายการที่สืบทอดมาจาก captureTarget ด้วย และจะยกเว้นรายการที่เป็นพี่น้องของ captureTarget จากการบันทึก ผลที่ได้คือเฟรมที่ส่งในแทร็กจะปรากฏราวกับว่าถูกครอบตัดตามรูปทรงของ captureTarget และระบบจะนำเนื้อหาที่บดบังและถูกบดบังออก

// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);

การเรียกใช้ restrictTo(null) จะเปลี่ยนแทร็กกลับเป็นสถานะเดิม

// Stop restricting.
await track.restrictTo(null);

หากการเรียกใช้ restrictTo() สำเร็จ ระบบจะแก้ไข Promise ที่แสดงผลเมื่อรับประกันได้ว่าเฟรมวิดีโอทั้งหมดที่ตามมาจะถูกจำกัดไว้ที่ captureTarget

หากไม่สำเร็จ ระบบจะปฏิเสธ Promise การเรียกใช้ restrictTo() ไม่สำเร็จอาจเกิดจากสาเหตุข้อใดข้อหนึ่งต่อไปนี้

  • หากrestrictionTargetได้รับการมินต์ในแท็บอื่นที่ไม่ใช่แท็บที่บันทึก (โปรดทราบว่าเมื่อใช้ปุ่ม "แชร์แท็บนี้แทน" ผู้ใช้อาจเปลี่ยนแท็บที่จะบันทึกได้ทุกเมื่อ)
  • หาก restrictionTarget มาจากองค์ประกอบที่ไม่มีอยู่อีกต่อไป
  • หากแทร็กมีโคลน (ดูปัญหา 1509418)
  • หากแทร็กปัจจุบันไม่ใช่แทร็กวิดีโอที่บันทึกด้วยตนเอง
  • หากองค์ประกอบที่ restrictionTarget นำมาจากไม่มีสิทธิ์จำกัด

ข้อควรพิจารณาเกี่ยวกับการจับภาพด้วยตนเอง

เมื่อแอปเรียก getDisplayMedia() และผู้ใช้เลือกจับภาพแท็บของแอปเอง เราจะเรียกการดำเนินการนี้ว่า "การจับภาพด้วยตนเอง"

วิธีการ restrictTo() จะแสดงในแทร็กวิดีโอการจับภาพแท็บ ไม่ใช่แค่สำหรับการจับภาพตนเอง แต่ขณะนี้การจับภาพองค์ประกอบใช้ได้กับการจับภาพตนเองเท่านั้น ดังนั้น เราขอแนะนำให้ตรวจสอบว่าผู้ใช้เลือกแท็บปัจจุบันหรือไม่ก่อนที่จะพยายามจำกัดแทร็ก ซึ่งทำได้โดยใช้แฮนเดิลการจับภาพ นอกจากนี้ คุณยังขอให้เบราว์เซอร์กระตุ้นให้ผู้ใช้ถ่ายภาพด้วยตนเองได้โดยใช้ preferCurrentTab

ความโปร่งใส

เฟรมวิดีโอที่แอปได้รับผ่าน getDisplayMedia() จะไม่มีช่องอัลฟ่า หากแอปตั้งค่าเป้าหมายการจับภาพแบบโปร่งแสงบางส่วน การแยกช่องอัลฟ่าอาจก่อให้เกิดผลลัพธ์บางอย่างดังนี้

  • สีอาจเปลี่ยนแปลง องค์ประกอบเป้าหมายที่มีความโปร่งใสบางส่วนซึ่งวาดบนพื้นหลังสีอ่อนอาจดูเข้มขึ้นเมื่อนำแชแนลอัลฟ่าออก และองค์ประกอบที่วาดบนพื้นหลังสีเข้มอาจดูอ่อนลง
  • สีที่ผู้ใช้มองไม่เห็นหรือมองไม่ออกเมื่อตั้งค่าแชแนลอัลฟาเป็นค่าสูงสุดจะปรากฏขึ้นเมื่อนำแชแนลอัลฟาออก ตัวอย่างเช่น การดำเนินการนี้อาจทําให้เฟรมที่จับภาพมีบริเวณสีดําที่ไม่คาดคิด หากส่วนที่เป็นพื้นโปร่งใสมีรหัส RGBA rgba(0, 0, 0, 0)
ภาพหน้าจอของผลลัพธ์จากเป้าหมายการจับภาพแบบโปร่งใสที่ไม่ใช่สี่เหลี่ยมผืนผ้า
สตรีมวิดีโอเป้าหมายการจับภาพแบบโปร่งใสที่ไม่ใช่สี่เหลี่ยมผืนผ้า (ขวา) คือสี่เหลี่ยมผืนผ้าพื้นหลังสีดําที่มีวงกลมสีน้ําเงินทึบ

เป้าหมายการบันทึกที่ไม่มีสิทธิ์

คุณเริ่มจํากัดแทร็กไปยังเป้าหมายการบันทึกที่ถูกต้องได้ทุกเมื่อ อย่างไรก็ตาม ระบบจะไม่สร้างเฟรมภายใต้เงื่อนไขบางอย่าง เช่น หากองค์ประกอบหรือบรรพบุรุษเป็น display:none เหตุผลทั่วไปคือข้อจำกัดจะมีผลกับองค์ประกอบที่ประกอบด้วยพื้นที่สี่เหลี่ยมผืนผ้า 2 มิติที่เหนียวแน่นเพียงรายการเดียว ซึ่งพิกเซลสามารถกำหนดได้อย่างมีเหตุผลโดยแยกจากองค์ประกอบหลักหรือองค์ประกอบที่เกี่ยวข้อง

สิ่งสําคัญอย่างหนึ่งที่ควรพิจารณาเพื่อให้แน่ใจว่าองค์ประกอบมีสิทธิ์ได้รับการจํากัดคือองค์ประกอบต้องสร้างบริบทการซ้อนของตนเอง คุณสามารถระบุพร็อพเพอร์ตี้ CSS isolation เพื่อตรวจสอบว่าเป็นไปตามข้อกำหนดนี้ โดยตั้งค่าเป็น isolate

<div id="captureTarget" style="isolation: isolate;"></iframe>

โปรดทราบว่าองค์ประกอบเป้าหมายสามารถสลับระหว่างการมีสิทธิ์และไม่มีสิทธิ์ในการจำกัดได้ทุกเมื่อ เช่น หากแอปเปลี่ยนพร็อพเพอร์ตี้ CSS ขึ้นอยู่กับแอปที่จะใช้เป้าหมายการจับภาพที่สมเหตุสมผลและหลีกเลี่ยงการเปลี่ยนแปลงพร็อพเพอร์ตี้โดยไม่คาดคิด หากองค์ประกอบเป้าหมายไม่มีสิทธิ์ ระบบจะไม่ส่งเฟรมใหม่ในแทร็กจนกว่าองค์ประกอบเป้าหมายจะมีสิทธิ์ใช้การจำกัดอีกครั้ง

การเปิดใช้การจับภาพองค์ประกอบ

Element Capture API พร้อมใช้งานใน Chrome บนเดสก์ท็อปหลัง Flag Element Capture และเปิดใช้ได้ที่ chrome://flags/#element-capture

ฟีเจอร์นี้ยังเข้าสู่ช่วงทดลองใช้แหล่งที่มาจาก Chrome 121 บนเดสก์ท็อปด้วย ซึ่งช่วยให้นักพัฒนาแอปเปิดใช้ฟีเจอร์นี้ให้ผู้เข้าชมเว็บไซต์ของตนเพื่อรวบรวมข้อมูลจากผู้ใช้จริงได้ ดูข้อมูลเพิ่มเติมเกี่ยวกับช่วงทดลองใช้ต้นทางได้ที่เริ่มต้นใช้งานช่วงทดลองใช้ต้นทาง

ความปลอดภัยและความเป็นส่วนตัว

หากต้องการทำความเข้าใจข้อเสียด้านความปลอดภัย โปรดดูส่วนข้อควรพิจารณาด้านความเป็นส่วนตัวและความปลอดภัยของข้อกำหนดเฉพาะการจับองค์ประกอบ

เบราว์เซอร์ Chrome จะวาดเส้นขอบสีน้ำเงินรอบขอบของแท็บที่บันทึกไว้

สาธิต

คุณเล่นกับเครื่องมือจับองค์ประกอบได้โดยเรียกใช้เดโมใน Glitch อย่าลืมตรวจสอบซอร์สโค้ด

ความคิดเห็น

ทีม Chrome และชุมชนมาตรฐานเว็บอยากทราบความคิดเห็นของคุณเกี่ยวกับฟีเจอร์การจับองค์ประกอบ

บอกเราเกี่ยวกับการออกแบบ

ฟีเจอร์การจับภาพพื้นที่ทำงานไม่ทำงานตามที่คาดไว้ใช่ไหม หรือมีเมธอดหรือพร็อพเพอร์ตี้ที่ขาดหายไปซึ่งคุณต้องนำไปใช้กับไอเดียของคุณ หากมีคำถามหรือความคิดเห็นเกี่ยวกับรูปแบบการรักษาความปลอดภัย

  • แจ้งปัญหาเกี่ยวกับข้อกำหนดใน GitHub repo หรือแสดงความคิดเห็นในปัญหาที่มีอยู่

พบปัญหาในการติดตั้งใช้งานใช่ไหม

หากพบข้อบกพร่องในการใช้งาน Chrome หรือการติดตั้งใช้งานแตกต่างจากข้อมูลจำเพาะหรือไม่

  • รายงานข้อบกพร่องที่ https://new.crbug.com โปรดระบุรายละเอียดให้มากที่สุดและวิธีการจำลองข้อบกพร่อง Glitch เหมาะอย่างยิ่งสำหรับการแชร์การจำลองข้อบกพร่องที่รวดเร็วและง่ายดาย

บริการรับรองคำให้การ

รูปภาพโดย Paul Skorupskas จาก Unsplash