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

François Beaufort
François Beaufort

Bạn có thể chia sẻ các 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() hiển thị cho người dùng bản xem trước video của nền tảng đã chụp. Ví dụ: các ứng dụng hội nghị truyền hình thường truyền trực tuyến video này đến người dùng từ xa, đồng thời hiển thị video đó cho một HTMLVideoElement cục bộ để người dùng cục bộ liên tục xem 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 (API điều khiển giao diện đã chụp) mới trong Chrome. API này cho phép ứng dụng web của bạn cuộn một thẻ đã chụp, cũng như đọc và ghi mức thu phóng của thẻ đã chụp.

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

Tại sao nên sử dụng Captured Surface Control?

Tất cả ứng dụng hội nghị truyền hình đều gặp phải cùng một hạn chế. Nếu muốn tương tác với một thẻ hoặc cửa sổ đã chụp, người dùng phải chuyển sang giao diện đó, 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ể xem ứng dụng đã chụp 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ổ cạnh nhau riêng biệt cho thẻ hội nghị video và thẻ được chia sẻ. Trên màn hình nhỏ hơn, việc này có thể khó khăn.
  • Người dùng phải chuyển đổi giữa ứng dụng hội nghị truyền hình và nền tảng được chụp.
  • Người dùng mất quyền truy cập vào các chế độ điều khiển mà ứng dụng hội nghị truyền hình hiển thị khi họ 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 quyền điều khiển cho người tham gia từ xa. Điều này dẫn đến một tình huống quá quen thuộc, trong đó 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 Captured Surface Control?

Để sử dụng thành công tính năng Kiểm soát giao diện đã chụp, bạn cần thực hiện một vài bước, chẳng hạn như chụp rõ ràng một thẻ trình duyệt và nhận quyền của người dùng trước khi có thể cuộn và thu phóng thẻ đã chụp.

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

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

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 nền tảng đã chụp ở 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ì việc này hiện nằm ngoài phạm vi. 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ệnh 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 lời nhắc cấp quyền. Nếu người dùng cấp quyền, bạn có thể gọi các phương thức này thêm lần nữa.

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

Cuộn

Khi sử dụng forwardWheel(), ứng dụng chụp có thể chuyển tiếp các sự kiện xoay từ một phần tử nguồn trong chính ứng dụng chụp đến khung nhìn của thẻ đã chụp. Ứng dụng được ghi lại không thể 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 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 gửi con lăn đến thẻ đã 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 giá trị đầu vào duy nhất có thể là một trong các giá trị sau:

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

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)

Bạn có thể tương tác với cấp độ thu phóng của thẻ đã chụp thông qua các nền tảng API CaptureController sau:

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 nền tảng đang được chụp. Các giá trị trong danh sách này được biểu diễn 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 dần và chứa giá trị 100.

Phương thức này chỉ có thể được gọi cho các loại nền tảng 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 đây được đáp ứng:

  • controller được liên kết với một bản ghi đang hoạt động.
  • Ảnh chụp 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ó thể đọc này chứa mức thu phóng hiện tại của thẻ đã chụp. Đây là một thuộc tính rỗng và giữ null nếu loại nền tảng được chụp không có định nghĩa có ý nghĩa về mức thu phóng. Hiện tại, zoom-level chỉ được xác định cho các thẻ chứ không phải cho cửa sổ hoặc màn hình.

Sau khi quá trình chụp kết thúc, thuộc tính này sẽ giữ giá trị mức thu phóng gần đây nhất.

Bạn không cần có quyền "captured-surface-control" để đọc thuộc tính này.

onzoomlevelchange

Trình xử lý sự kiện này hỗ trợ việc theo dõi các thay đổi đối với mức thu phóng của thẻ đã chụp. Những sự cố 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ẻ đã 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 (như mô tả bên dưới).

Bạn không cần 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ẻ đã chụp.

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 lời hứa được phân giải nếu lệnh gọi thành công và bị từ chối nếu không. Có thể bạn bị từ chối vì một số lý do sau:

  • Thiếu quyền.
  • Được gọi trước khi quá trình chụp bắt đầu.
  • Được gọi sau khi quá trình chụp kết thúc.
  • Được gọi trên controller liên kết với một bản ghi của loại nền tảng 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ẻ.)
  • Tăng hoặc giảm giá trị vượt quá giá trị tối đa hoặc tối thiểu tương ứng.

Đáng chú ý là 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 thẻ đã chụp trực tiếp 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 thẻ đã chụp:

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

Phát hiện tính năng

Để kiểm tra xem các API Kiểm soát giao diện được chụp 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ỳ nền tảng API Kiểm soát giao diện đã chụp 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 nền tảng đó.

Hỗ trợ trình duyệt

Tính năng Điều khiển giao diện được chụp chỉ có trên máy tính từ Chrome 136.

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

Chính sách quyền của "captured-surface-control" cho phép bạn quản lý cách ứng dụng chụp và iframe nhúng của bên thứ ba có quyền truy cập vào Captured Surface Control. Để hiểu rõ những đá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ề tính năng Kiểm soát giao diện đã chụp.

Bản minh hoạ

Bạn có thể chơi với Captured Surface Control bằng cách chạy bản minh hoạ trên Glitch. Hãy nhớ xem mã nguồn.

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 Điều khiển giao diện được chụp.

Giới thiệu về thiết kế

Có điều gì về tính năng Quay video màn hình không hoạt động như mong đợi không? Hay bạn thiếu phương thức hoặc thuộc tính cần thiết để triển khai ý tưởng của mình? Bạn có câu hỏi hoặc nhận xét về mô hình bảo mật? Gửi vấn đề về thông số kỹ thuật 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 lỗi khi triển khai Chrome không? Hay cách triển khai có khác với thông số kỹ thuật không? Gửi 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 cách tái tạo lỗi. Glitch rất hữu ích để chia sẻ các lỗi có thể tái hiện.