Cuộn và thu phóng thẻ đã ghi lại

François Beaufort
François Beaufort

Bạn đã có thể chia sẻ thẻ, cửa sổ và màn hình trên nền tảng web bằng Screen Capture API. Khi một ứng dụng web gọi getDisplayMedia(), Chrome sẽ nhắc người dùng chia sẻ một thẻ, cửa sổ hoặc màn hình với ứng dụng web dưới dạng video MediaStreamTrack.

Nhiều ứng dụng web sử dụng getDisplayMedia() cho người dùng xem trước video về bề mặt được ghi lại. Ví dụ: các ứng dụng hội nghị truyền hình thường sẽ truyền trực tuyến video này cho người dùng từ xa, đồng thời kết xuất video đó vào một HTMLVideoElement cục bộ, để người dùng cục bộ liên tục thấy bản xem trước nội dung họ đang chia sẻ.

Tài liệu này giới thiệu Captured Surface Control API mới trong Chrome. API này cho phép ứng dụng web của bạn cuộn một thẻ được ghi lại, cũng như đọc và ghi mức thu phóng của một thẻ được ghi lại.

Người dùng cuộn và thu phóng một thẻ đã chụp (bản minh hoạ).

Tại sao nên dùng Captured Surface Control?

Tất cả các ứng dụng hội nghị truyền hình đều có cùng một nhược điểm. Nếu muốn tương tác với một thẻ hoặc cửa sổ đã ghi lại, người dùng phải chuyển sang thẻ hoặc cửa sổ đó, khiến họ rời khỏi ứng dụng hội nghị truyền hình. Điều này gây ra một số thách thức:

  • Người dùng không thể thấy ứng dụng đã ghi và nguồn cấp dữ liệu video của người dùng từ xa cùng một lúc, trừ phi họ sử dụng chế độ Hình trong hình hoặc các cửa sổ riêng biệt cạnh nhau cho thẻ hội nghị truyền hình và thẻ được chia sẻ. Trên màn hình nhỏ, việc này có thể khó thực hiện.
  • Người dùng gặp khó khăn khi phải chuyển đổi giữa ứng dụng hội nghị truyền hình và màn hình được ghi lại.
  • Người dùng sẽ mất quyền truy cập vào các chế độ điều khiển do ứng dụng hội nghị truyền hình cung cấp khi rời khỏi ứng dụng đó; ví dụ: ứng dụng trò chuyện được nhúng, biểu tượng cảm xúc, thông báo về người dùng yêu cầu tham gia cuộc gọi, chế độ điều khiển bố cục và nội dung đa phương tiện, cũng như các tính năng hội nghị truyền hình hữu ích khác.
  • Người trình bày không thể uỷ quyền kiểm soát cho người tham gia từ xa. Điều này dẫn đến tình huống quen thuộc là người dùng từ xa yêu cầu người trình bày thay đổi trang trình bày, cuộn lên và xuống một chút hoặc điều chỉnh mức thu phóng.

Captured Surface Control API giải quyết những vấn đề này.

Làm cách nào để sử dụng chế độ kiểm soát vùng được chụp?

Để sử dụng thành công Captured Surface Control, bạn cần thực hiện một số bước, chẳng hạn như chụp rõ ràng một thẻ trình duyệt và được người dùng cấp quyền trước khi có thể cuộn và thu phóng thẻ đã chụp.

Ghi lại một thẻ trình duyệt

Bắt đầu bằng cách nhắc người dùng chọn một bề mặt để chia sẻ bằng cách sử dụng getDisplayMedia(), đồng thời liên kết một đối tượng CaptureController với phiên chụp. Chúng ta sẽ sử dụng đối tượng đó để kiểm soát bề mặt được chụp trong thời gian tới.

const controller = new CaptureController();
const stream = await navigator.mediaDevices.getDisplayMedia({ controller });

Tiếp theo, hãy tạo bản xem trước cục bộ của bề mặt được chụp dưới dạng phần tử <video>:

const previewTile = document.querySelector('video');
previewTile.srcObject = stream;

Nếu người dùng chọn chia sẻ một cửa sổ hoặc màn hình, thì điều đó hiện không thuộc phạm vi xử lý. Tuy nhiên, nếu họ chọn chia sẻ một thẻ, thì chúng ta có thể tiếp tục.

const [track] = stream.getVideoTracks();

if (track.getSettings().displaySurface !== 'browser') {
  // Bail out early if the user didn't pick a tab.
  return;
}

Lời nhắc cấp quyền

Lần gọi đầu tiên của forwardWheel(), increaseZoomLevel(), decreaseZoomLevel() hoặc resetZoomLevel() trên một đối tượng CaptureController nhất định sẽ tạo ra một lời nhắc về quyền. Nếu người dùng cấp quyền, thì các lệnh gọi tiếp theo của những phương thức này sẽ được phép.

Bạn phải có một cử chỉ của người dùng để cho người dùng thấy lời nhắc cấp quyền. Vì vậy, ứng dụng chỉ nên gọi các phương thức nêu trên nếu đã có quyền hoặc để phản hồi một cử chỉ của người dùng, chẳng hạn như một click trên một nút có liên quan trong ứng dụng Web.

Cuộn

Bằng cách sử dụng forwardWheel(), một ứng dụng chụp có thể chuyển tiếp các sự kiện bánh xe từ một phần tử nguồn trong chính ứng dụng chụp đến khung nhìn của thẻ được chụp. Ứng dụng đã ghi lại không phân biệt được các sự kiện này với lượt tương tác trực tiếp của người dùng.

Giả sử ứng dụng chụp sử dụng một phần tử <video> có tên là "previewTile", mã sau đây cho biết cách chuyển tiếp các sự kiện bánh xe gửi đến thẻ được chụp:

const previewTile = document.querySelector('video');
try {
  // Relay the user's action to the captured tab.
  await controller.forwardWheel(previewTile);
} catch (error) {
  // Inspect the error.
  // ...
}

Phương thức forwardWheel() nhận một đầu vào duy nhất có thể là một trong những đầu vào sau:

  • Một phần tử HTML mà từ đó các sự kiện bánh xe sẽ được chuyển tiếp đến thẻ được ghi lại.
  • null, cho biết cần dừng chuyển tiếp.

Lệnh gọi thành công đến forwardWheel() sẽ ghi đè các lệnh gọi trước đó.

Lời hứa do forwardWheel() trả về có thể bị từ chối trong các trường hợp sau:

  • Nếu phiên chụp chưa bắt đầu hoặc đã dừng.
  • Nếu người dùng không cấp quyền liên quan.

Zoom (thu phóng)

Việc tương tác với mức thu phóng của thẻ được ghi lại được thực hiện thông qua các giao diện API CaptureController sau đây:

getSupportedZoomLevels()

Phương thức này trả về danh sách các mức thu phóng mà trình duyệt hỗ trợ cho loại bề mặt đang được chụp. Các giá trị trong danh sách này được biểu thị dưới dạng tỷ lệ phần trăm so với "mức thu phóng mặc định", được xác định là 100%. Danh sách này tăng đơn điệu và chứa giá trị 100.

Phương thức này chỉ có thể được gọi cho các loại bề mặt hiển thị được hỗ trợ, hiện tại chỉ dành cho các thẻ.

controller.getSupportedZoomLevels() có thể được gọi nếu các điều kiện sau được đáp ứng:

  • controller được liên kết với một bản ghi đang hoạt động.
  • Nội dung được ghi lại là một thẻ.

Nếu không, lỗi sẽ xảy ra.

Bạn không cần có quyền "captured-surface-control" để gọi phương thức này.

zoomLevel

Thuộc tính chỉ đọc này lưu giữ mức thu phóng hiện tại của thẻ được ghi lại. Đây là một thuộc tính có thể rỗng và giữ null nếu loại bề mặt được chụp không có định nghĩa có ý nghĩa về mức thu phóng. Hiện tại, cấp độ thu phóng chỉ được xác định cho các thẻ, chứ không phải cho các cửa sổ hoặc màn hình.

Sau khi quá trình chụp kết thúc, thuộc tính sẽ giữ giá trị cấp độ thu phóng cuối cùng.

Bạn không bắt buộc phải có quyền "captured-surface-control" để đọc thuộc tính này.

onzoomlevelchange

Trình xử lý sự kiện này giúp theo dõi những thay đổi đối với mức thu phóng của thẻ được ghi lại. Những trường hợp này xảy ra khi:

  • Khi người dùng tương tác với trình duyệt để thay đổi mức thu phóng của thẻ được chụp theo cách thủ công.
  • Để phản hồi các lệnh gọi của ứng dụng chụp đến các phương thức cài đặt thu phóng (được mô tả bên dưới).

Bạn không bắt buộc phải có quyền "captured-surface-control" để đọc thuộc tính này.

increaseZoomLevel(), decreaseZoomLevel()resetZoomLevel()

Các phương thức này cho phép thao tác với mức thu phóng của thẻ được ghi lại.

increaseZoomLevel()decreaseZoomLevel() lần lượt thay đổi mức thu phóng thành mức thu phóng tiếp theo hoặc trước đó, theo thứ tự do getSupportedZoomLevels() trả về. resetZoomLevel() đặt giá trị thành 100.

Bạn phải có quyền "captured-surface-control" để gọi các phương thức này. Nếu ứng dụng chụp không có quyền này, người dùng sẽ được nhắc cấp hoặc từ chối quyền.

Tất cả các phương thức này đều trả về một promise được phân giải nếu lệnh gọi thành công và bị từ chối nếu không. Sau đây là một số nguyên nhân có thể khiến yêu cầu bị từ chối:

  • Thiếu quyền.
  • Được gọi trước khi quá trình ghi hình bắt đầu.
  • Được gọi sau khi quá trình chụp kết thúc.
  • Được gọi trên một controller được liên kết với một hoạt động ghi lại loại bề mặt hiển thị không được hỗ trợ. (Tức là mọi thứ ngoại trừ tính năng chụp lại thông tin thẻ.)
  • Cố gắng tăng hoặc giảm quá giá trị tối đa hoặc tối thiểu tương ứng.

Đặc biệt, bạn nên tránh gọi decreaseZoomLevel() nếu controller.zoomLevel == controller.getSupportedZoomLevels().at(0) và bảo vệ các lệnh gọi đến increaseZoomLevel() theo cách tương tự với .at(-1).

Ví dụ sau đây cho biết cách cho phép người dùng tăng mức thu phóng của một thẻ đã chụp ngay từ ứng dụng chụp:

const zoomIncreaseButton = document.getElementById('zoomInButton');
zoomIncreaseButton.addEventListener('click', async (event) => {
  if (controller.zoomLevel >= controller.getSupportedZoomLevels().at(-1)) {
    return;
  }
  try {
    await controller.increaseZoomLevel();
  } catch (error) {
    // Inspect the error.
    // ...
  }
});

Ví dụ sau đây cho thấy cách phản ứng với các thay đổi về mức thu phóng của một thẻ được ghi lại:

controller.addEventListener('zoomlevelchange', (event) => {
  const zoomLevelLabel = document.querySelector('#zoomLevelLabel');
  zoomLevelLabel.textContent = `${controller.zoomLevel}%`;
});

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

Để kiểm tra xem Captured Surface Control API có được hỗ trợ hay không, hãy sử dụng:

if (!!window.CaptureController?.prototype.forwardWheel) {
  // CaptureController forwardWheel() is supported.
}

Bạn cũng có thể sử dụng bất kỳ giao diện Captured Surface Control API nào khác, chẳng hạn như increaseZoomLevel hoặc decreaseZoomLevel, hoặc thậm chí kiểm tra tất cả các giao diện đó.

Hỗ trợ trình duyệt

Tính năng Điều khiển bề mặt được ghi lại chỉ có trên Chrome 136 dành cho máy tính.

Bảo mật và quyền riêng tư

Chính sách về quyền của "captured-surface-control" cho phép bạn quản lý cách ứng dụng ghi hình và iframe được nhúng của bên thứ ba truy cập vào Captured Surface Control. Để hiểu rõ những điểm đánh đổi về bảo mật, hãy xem phần Những điểm cần cân nhắc về quyền riêng tư và bảo mật trong phần giải thích về Chế độ kiểm soát bề mặt được ghi lại.

Bản minh hoạ

Bạn có thể dùng thử Captured Surface Control bằng cách chạy bản minh hoạ.

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 Captured Surface Control.

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

Có vấn đề gì về tính năng Chụp bề mặt được ghi lại mà bạn thấy không hoạt động như 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, cũng như hướng dẫn về cách tái hiện lỗi.