Chia sẻ màn hình tốt hơn nhờ tính năng Lấy nét có điều kiện

François Beaufort
François Beaufort

Browser Support

  • Chrome: 109.
  • Edge: 109.
  • Firefox: not supported.
  • Safari: not supported.

Source

Screen Capture API cho phép người dùng chọn một thẻ, cửa sổ hoặc màn hình để chụp dưới dạng luồng nội dung nghe nhìn. Sau đó, bạn có thể ghi lại hoặc chia sẻ luồng này với những người khác qua mạng. Tài liệu này giới thiệu về Lấy tiêu điểm có điều kiện, một cơ chế cho phép các ứng dụng web kiểm soát việc thẻ hoặc cửa sổ được ghi hình sẽ được lấy tiêu điểm khi bắt đầu ghi hình hay trang ghi hình sẽ vẫn được lấy tiêu điểm.

Hỗ trợ trình duyệt

Tính năng Lấy nét có điều kiện có trong Chrome 109.

Thông tin khái quát

Khi một ứng dụng web bắt đầu ghi lại một thẻ hoặc cửa sổ, trình duyệt sẽ phải đưa ra quyết định: có nên đưa bề mặt được ghi lại lên hàng đầu hay nên giữ cho trang ghi lại ở trạng thái tập trung? Câu trả lời tuỳ thuộc vào lý do gọi điện getDisplayMedia() và vào nền tảng mà người dùng chọn.

Hãy xem xét một ứng dụng hội nghị truyền hình giả định. Bằng cách đọc track.getSettings().displaySurface và có thể kiểm tra Capture Handle, ứng dụng hội nghị truyền hình trên web có thể biết người dùng đã chọn chia sẻ nội dung gì. Sau đó:

  • Nếu thẻ hoặc cửa sổ được ghi hình có thể được điều khiển từ xa, hãy giữ cho hội nghị truyền hình ở chế độ lấy nét.
  • Nếu không, hãy đặt tiêu điểm vào thẻ hoặc cửa sổ được ghi hình.

Trong ví dụ trên, ứng dụng web hội nghị truyền hình sẽ giữ tiêu điểm nếu chia sẻ một bộ trang trình bày, cho phép người dùng lật các trang trình bày từ xa; nhưng nếu người dùng chọn chia sẻ một trình chỉnh sửa văn bản, thì ứng dụng web hội nghị truyền hình sẽ ngay lập tức chuyển tiêu điểm sang thẻ hoặc cửa sổ được chụp.

Sử dụng Conditional Focus API

Tạo một thực thể CaptureController rồi truyền thực thể đó đến getDisplayMedia(). Bằng cách gọi setFocusBehavior() ngay sau khi lời hứa getDiplayMedia() được trả về sẽ phân giải, bạn có thể kiểm soát việc thẻ hoặc cửa sổ được chụp có được lấy tiêu điểm hay không. Bạn chỉ có thể làm việc này nếu người dùng chia sẻ một thẻ hoặc cửa sổ.

const controller = new CaptureController();  // Prompt the user to share a tab, a window or a screen. const stream =     await navigator.mediaDevices.getDisplayMedia({ controller });  const [track] = stream.getVideoTracks(); const displaySurface = track.getSettings().displaySurface; if (displaySurface == "browser") {   // Focus the captured tab.   controller.setFocusBehavior("focus-captured-surface"); } else if (displaySurface == "window") {   // Do not move focus to the captured window.   // Keep the capturing page focused.   controller.setFocusBehavior("focus-capturing-application"); } 

Khi quyết định có nên lấy tiêu điểm hay không, bạn có thể cân nhắc Capture Handle.

// Retain focus if capturing a tab dialed to example.com. // Focus anything else. const origin = track.getCaptureHandle().origin; if (displaySurface == "browser" && origin == "https://example.com") {   controller.setFocusBehavior("focus-capturing-application"); } else if (displaySurface != "monitor") {   controller.setFocusBehavior("focus-captured-surface"); } 

Bạn thậm chí có thể quyết định có nên lấy nét hay không trước khi gọi getDisplayMedia().

// Focus the captured tab or window when capture starts. const controller = new CaptureController(); controller.setFocusBehavior("focus-captured-surface");  // Prompt the user to share their screen. const stream =     await navigator.mediaDevices.getDisplayMedia({ controller }); 

Bạn có thể gọi setFocusBehavior() tuỳ ý nhiều lần trước khi lời hứa được thực hiện hoặc tối đa một lần ngay sau khi lời hứa được thực hiện. Lần gọi cuối cùng sẽ ghi đè tất cả các lần gọi trước đó.

Chính xác hơn: - Lời hứa getDisplayMedia() được trả về sẽ phân giải trên một vi tác vụ. Việc gọi setFocusBehavior() sau khi vi tác vụ đó hoàn tất sẽ gây ra lỗi. – Việc gọi setFocusBehavior() hơn một giây sau khi quá trình chụp bắt đầu sẽ không có tác dụng.

Tức là cả hai đoạn mã sau đây sẽ không thành công:

// Prompt the user to share their screen. const stream =     await navigator.mediaDevices.getDisplayMedia({ controller });  // Too late, because it follows the completion of the task // on which the getDisplayMedia() promise resolved. // This will throw. setTimeout(() => {   controller.setFocusBehavior("focus-captured-surface"); }); 
// Prompt the user to share their screen. const stream =     await navigator.mediaDevices.getDisplayMedia({ controller });  const start = new Date(); while (new Date() - start <= 1000) {   // Idle for ≈1s. }  // Because too much time has elapsed, the browser will have // already decided whether to focus. // This fails silently. controller.setFocusBehavior("focus-captured-surface"); 

Lệnh gọi setFocusBehavior() cũng sẽ gặp lỗi trong các trường hợp sau:

  • đường tiếng của video trong luồng do getDisplayMedia() trả về không phải là "live".
  • sau khi lời hứa được trả về getDisplayMedia() được giải quyết, nếu người dùng chia sẻ màn hình (không phải thẻ hoặc cửa sổ).

Mẫu

Bạn có thể thử tính năng Lấy nét có điều kiện bằng cách chạy bản minh hoạ.

Phát hiện đối tượng

Để kiểm tra xem CaptureController.setFocusBehavior() có được hỗ trợ hay không, hãy sử dụng:

if (   "CaptureController" in window &&   "setFocusBehavior" in CaptureController.prototype ) {   // CaptureController.setFocusBehavior() is supported. } 

Phản hồi

Nhóm Chrome và cộng đồng tiêu chuẩn web muốn biết trải nghiệm của bạn với tính năng Lấy tiêu điểm có điều kiện.

Cho chúng tôi biết về thiết kế

Có điều gì về tính năng Lấy nét có điều kiện không hoạt động như bạn mong đợi không? Hoặc có phương thức hoặc thuộc tính nào bị thiếu mà bạn cần triển khai ý tưởng của mình không? Bạn có câu hỏi hoặc bình luận về mô hình bảo mật?

  • Gửi vấn đề về quy cách trên kho lưu trữ GitHub hoặc thêm ý kiến của bạn vào một vấn đề hiện có.

Bạn gặp vấn đề khi triển khai?

Bạn có phát hiện thấy lỗi trong quá trình triển khai của Chrome không? Hoặc việc triển khai có khác với quy cách không?

  • Báo cáo lỗi tại https://new.crbug.com. Hãy nhớ cung cấp càng nhiều thông tin chi tiết càng tốt và hướng dẫn đơn giản để tái hiện lỗi.

Thể hiện sự ủng hộ

Bạn có dự định sử dụng tính năng Lấy nét có điều kiện không? Sự ủng hộ công khai của bạn giúp nhóm Chrome ưu tiên các tính năng và cho các nhà cung cấp trình duyệt khác thấy tầm quan trọng của việc hỗ trợ các tính năng này.

Gửi một tweet đến @ChromiumDev và cho chúng tôi biết bạn đang sử dụng tính năng này ở đâu và như thế nào.

Lời cảm ơn

Hình ảnh chính của Elena Taranenko.

Cảm ơn Rachel Andrew đã xem xét bài viết này.