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

François Beaufort
François Beaufort

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

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

การพิจารณาข้อกำหนดของแอปพลิเคชันการประชุมทางวิดีโอจะช่วยให้คุณทราบว่า 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 เท่านั้น

หาก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) ให้เรียกใช้ 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 แอปมีหน้าที่ต้องใช้เป้าหมายการจับภาพที่สมเหตุสมผลและหลีกเลี่ยงการเปลี่ยนแปลงพร็อพเพอร์ตี้โดยไม่คาดคิด หากองค์ประกอบเป้าหมายไม่มีสิทธิ์ ระบบจะไม่ปล่อยเฟรมใหม่ในแทร็กจนกว่าองค์ประกอบเป้าหมายจะมีสิทธิ์ถูกจำกัดอีกครั้ง

การสนับสนุนเบราว์เซอร์

การจับภาพองค์ประกอบพร้อมใช้งานใน Chrome 132 ขึ้นไปบนเดสก์ท็อปเท่านั้น

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

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

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

สาธิต

คุณสามารถทดลองใช้การจับภาพองค์ประกอบได้โดยเรียกใช้การสาธิต

ความคิดเห็น

ทีม Chrome และชุมชนมาตรฐานเว็บอยากทราบประสบการณ์การใช้งานการจับภาพองค์ประกอบของคุณ

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

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

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

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

หากพบข้อบกพร่องในการใช้งาน Chrome หรือการติดตั้งใช้งานแตกต่างจากข้อกำหนด

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

คำขอบคุณ

รูปภาพโดย Paul Skorupskas ใน Unsplash