Với Screen Capture API (API chụp màn hình), bạn có thể chụp toàn bộ thẻ hiện tại. Element Capture API (API chụp phần tử) cho phép bạn chụp và ghi lại một phần tử HTML cụ thể. Phương thức này chuyển đổi bản ghi toàn bộ thẻ thành bản ghi một cây con DOM cụ thể, chỉ ghi lại các phần tử con trực tiếp của phần tử mục tiêu. Nói cách khác, công cụ này sẽ cắt và xoá cả nội dung che khuất và bị che khuất.
Tại sao nên sử dụng tính năng Chụp phần tử?
Việc xem xét các yêu cầu của ứng dụng hội nghị truyền hình có thể giúp bạn hiểu được trường hợp sử dụng tính năng Chụp thành phần. Nếu có một ứng dụng hội nghị truyền hình cho phép bạn nhúng các ứng dụng bên thứ ba vào một iframe, đôi khi bạn có thể muốn chụp iframe đó dưới dạng video và truyền video đó đến những người tham gia từ xa.
Việc gọi getDisplayMedia()
và cho phép người dùng chọn thẻ hiện tại sẽ truyền toàn bộ thẻ hiện tại. Điều này có thể khiến video của người dùng được truyền lại cho họ. Bạn có thể cắt bỏ phần này bằng tính năng Chụp vùng.
Tuy nhiên, nếu người trình bày tương tác với ứng dụng hội nghị truyền hình và một số nội dung (chẳng hạn như danh sách thả xuống) vô tình được vẽ lên trên nội dung cần ghi lại thì sao?
Tính năng Chụp vùng sẽ không giúp bạn trong trường hợp này. Một phần của danh sách thả xuống có thể hiển thị trên màn hình của người tham gia từ xa.
Việc tính năng Chụp vùng lấy một phần của các phần tử theo cách này (được gọi là che khuất nội dung) sẽ gây ra nhiều vấn đề:
- Nội dung che khuất có thể khiến người dùng không xem được nội dung mà họ muốn chia sẻ.
- Nội dung bị che khuất có thể là nội dung riêng tư (ví dụ: thông báo trò chuyện).
- Việc che khuất nội dung có thể gây nhầm lẫn. (Ví dụ: việc bố cục lại ứng dụng có thể đưa video của người tham gia từ xa lên mục tiêu đã chụp trong thời gian ngắn.)
Element Capture API giải quyết tất cả các vấn đề này bằng cách cho phép bạn nhắm đến phần tử mà bạn muốn chia sẻ.
Làm cách nào để sử dụng tính năng Chụp phần tử?
captureTarget
là một Thành phần trên trang của bạn, chứa nội dung mà người dùng muốn chụp. Bạn muốn ứng dụng web hội nghị truyền hình ghi lại captureTarget
và chia sẻ với những người tham gia từ xa. Vì vậy, bạn sẽ lấy RestrictionTarget
từ captureTarget
. Sau khi hạn chế kênh video bằng RestrictionTarget
này, các khung trên kênh video đó hiện chỉ bao gồm các pixel thuộc captureTarget
và các phần tử con DOM trực tiếp của captureTarget
.
Nếu captureTarget
thay đổi kích thước, hình dạng hoặc vị trí, thì kênh video sẽ thay đổi theo mà không cần bất kỳ dữ liệu đầu vào nào khác từ ứng dụng web. Tương tự, việc che khuất nội dung xuất hiện, biến mất hoặc di chuyển xung quanh cũng không cần xử lý đặc biệt.
Hãy xem lại các bước sau:
Bắt đầu bằng cách cho phép người dùng chụp thẻ hiện tại.
// Ask the user for permission to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();
Xác định RestrictionTarget
bằng cách gọi RestrictionTarget.fromElement()
với một phần tử mà bạn chọn làm dữ liệu đầu vào.
// Associate captureTarget with a new RestrictionTarget
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
Sau đó, gọi restrictTo()
trên kênh video với RestrictionTarget
làm dữ liệu đầu vào. Sau khi lời hứa cuối cùng được giải quyết, tất cả các khung hình tiếp theo sẽ bị hạn chế.
// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);
// Enjoy! Transmit remotely.
Tìm hiểu chuyên sâu
Phát hiện tính năng
Để kiểm tra xem RestrictionTarget.fromElement()
có được hỗ trợ hay không, hãy sử dụng:
if ("RestrictionTarget" in self && "fromElement" in RestrictionTarget) {
// Deriving a restriction target is supported.
}
Trích xuất RestrictionTarget
Đặt tiêu điểm vào Phần tử có tên là captureTarget
. Để lấy RestrictionTarget
từ đó, hãy gọi RestrictionTarget.fromElement(captureTarget)
. Lời hứa được trả về sẽ được phân giải bằng đối tượng RestrictionTarget
mới nếu thành công. Nếu không, yêu cầu này sẽ bị từ chối nếu bạn đã tạo một số lượng đối tượng RestrictionTarget
không hợp lý.
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
Không giống như Phần tử, đối tượng RestrictionTarget
là có thể chuyển đổi tuần tự. Bạn có thể chuyển giá trị này đến một tài liệu khác bằng cách sử dụng Window.postMessage()
.
Hạn chế
Khi bạn chụp một thẻ, kênh video sẽ hiển thị restrictTo()
. Khi chụp thẻ hiện tại, bạn có thể gọi restrictTo()
bằng null
hoặc bất kỳ RestrictionTarget
nào bắt nguồn từ một Phần tử trong thẻ hiện tại.
Các lệnh gọi đến restrictTo(restrictionTarget)
sẽ biến đổi kênh video thành một bản ghi của captureTarget
, như thể kênh video đó được tự vẽ, độc lập với phần còn lại của DOM. Mọi phần tử con của captureTarget
cũng được thu thập; các phần tử đồng cấp của captureTarget
sẽ bị loại bỏ khỏi quá trình thu thập. Kết quả là mọi khung hình được phân phối trên kênh sẽ xuất hiện như thể chúng được cắt theo đường viền của captureTarget
, đồng thời mọi nội dung che khuất và bị che khuất sẽ bị xoá.
// Start restricting the self-capture video track using the RestrictionTarget.
await track.restrictTo(restrictionTarget);
Lệnh gọi đến restrictTo(null)
sẽ khôi phục bản nhạc về trạng thái ban đầu.
// Stop restricting.
await track.restrictTo(null);
Nếu lệnh gọi đến restrictTo()
thành công, Lời hứa được trả về sẽ được phân giải khi có thể đảm bảo rằng tất cả các khung hình video tiếp theo sẽ bị hạn chế ở captureTarget
.
Nếu không thành công, Lời hứa sẽ bị từ chối. Lệnh gọi đến restrictTo()
không thành công là do một trong những lý do sau:
- Nếu
restrictionTarget
được tạo trong một thẻ khác với thẻ đang được chụp. (Lưu ý rằng khi sử dụng nút "chia sẻ thẻ này", người dùng có thể thay đổi thẻ được chụp tại bất kỳ thời điểm nào.) - Nếu
restrictionTarget
được lấy từ một Phần tử không còn tồn tại. - Nếu bản nhạc có bản sao. (Xem vấn đề 1509418.)
- Nếu bản nhạc hiện tại không phải là bản nhạc video tự quay.
- Nếu Phần tử mà
restrictionTarget
được lấy từ đó không đủ điều kiện để bị hạn chế.
Những điều cần cân nhắc khi tự quay
Khi một ứng dụng gọi getDisplayMedia()
và người dùng chọn chụp thẻ của chính ứng dụng đó, chúng ta gọi đó là "tự chụp".
Phương thức restrictTo()
được hiển thị trên mọi kênh video quay lại thẻ, chứ không chỉ dành cho tính năng tự quay. Tuy nhiên, tính năng Chụp phần tử hiện chỉ được bật cho tính năng tự chụp. Do đó, bạn nên kiểm tra xem người dùng đã chọn thẻ hiện tại hay chưa trước khi tìm cách hạn chế bản nhạc. Bạn có thể thực hiện việc này bằng cách sử dụng Tên người dùng chụp. Bạn cũng có thể yêu cầu trình duyệt nhắc người dùng tự chụp bằng preferCurrentTab
.
Sự minh bạch
Các khung hình video mà ứng dụng nhận được thông qua getDisplayMedia()
không bao gồm kênh alpha. Nếu một ứng dụng đặt mục tiêu chụp có độ trong suốt một phần, thì việc loại bỏ kênh alpha có thể dẫn đến một số hậu quả:
- Màu sắc có thể thay đổi. Các phần tử mục tiêu trong suốt một phần được vẽ trên nền sáng có thể trông tối hơn khi kênh alpha bị xoá và các phần tử được vẽ trên nền tối có thể trông sáng hơn.
- Những màu mà người dùng không nhìn thấy hoặc không nhận thấy khi kênh alpha được đặt ở mức tối đa sẽ xuất hiện sau khi kênh alpha bị xoá. Ví dụ: điều này có thể dẫn đến các vùng màu đen không mong muốn trong các khung hình đã chụp, nếu các phần trong suốt có mã RGBA
rgba(0, 0, 0, 0)
.
Mục tiêu thu thập không đủ điều kiện
Bạn luôn có thể bắt đầu hạn chế một kênh cho bất kỳ mục tiêu quay video hợp lệ nào. Tuy nhiên, khung sẽ không được tạo trong một số điều kiện nhất định, chẳng hạn như nếu phần tử hoặc phần tử cấp trên là display:none
. Lý do chung là quy tắc hạn chế này chỉ áp dụng cho một phần tử bao gồm một vùng hình chữ nhật, hai chiều, có tính liên kết, mà các điểm ảnh của phần tử đó có thể được xác định một cách logic tách biệt với mọi phần tử mẹ hoặc phần tử đồng cấp.
Một điều quan trọng cần cân nhắc để đảm bảo phần tử đủ điều kiện bị hạn chế là phần tử đó phải tạo thành ngữ cảnh xếp chồng riêng. Để đảm bảo điều này, bạn có thể chỉ định thuộc tính CSS isolation (phân tách), đặt thuộc tính này thành isolate
.
<div id="captureTarget" style="isolation: isolate;"></iframe>
Xin lưu ý rằng phần tử mục tiêu có thể chuyển đổi giữa trạng thái đủ điều kiện và không đủ điều kiện để bị hạn chế tại bất kỳ thời điểm tuỳ ý nào, ví dụ: nếu ứng dụng thay đổi các thuộc tính CSS của phần tử đó. Ứng dụng có thể sử dụng các mục tiêu chụp hợp lý và tránh thay đổi các thuộc tính của mục tiêu đó một cách đột ngột. Nếu phần tử mục tiêu không đủ điều kiện, thì các khung hình mới sẽ không được phát trên kênh cho đến khi phần tử mục tiêu đó đủ điều kiện để bị hạn chế trở lại.
Bật tính năng Chụp phần tử
Element Capture API có trong Chrome trên máy tính đằng sau cờ Element Capture và có thể được bật tại chrome://flags/#element-capture
.
Tính năng này cũng đang bước vào giai đoạn thử nghiệm theo nguồn gốc từ Chrome 121 trên máy tính. Tính năng này cho phép nhà phát triển bật tính năng này cho khách truy cập trang web của họ để thu thập dữ liệu từ người dùng thực. Hãy xem bài viết Bắt đầu thử nghiệm nguồn gốc để biết thêm thông tin về thử nghiệm nguồn gốc.
Bảo mật và quyền riêng tư
Để 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 thông số kỹ thuật của tính năng Chụp phần tử.
Trình duyệt Chrome vẽ đường viền màu xanh dương xung quanh các cạnh của thẻ đã chụp.
Bản minh hoạ
Bạn có thể thử nghiệm tính năng Chụp phần tử 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 Chụp phần tử.
Giới thiệu về thiết kế
Có điều gì về tính năng Chụp vùng không hoạt động như mong đợi không? Hay 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 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 và hướng dẫn đơn giản để tái tạo lỗi. Glitch rất hữu ích để chia sẻ các bản tái hiện nhanh chóng và dễ dàng.
Đường liên kết hữu ích
Thư cảm ơn
Ảnh chụp của Paul Skorupskas trên Unsplash