С помощью API захвата экрана вы можете сделать снимок всей текущей вкладки. API захвата элементов позволяет сделать снимок и записать конкретный HTML-элемент. Он преобразует снимок всей вкладки в снимок определённого поддерева DOM, захватывая только прямых потомков целевого элемента. Другими словами, он обрезает и удаляет как перекрывающее, так и перекрытое содержимое.
Зачем использовать Element Capture?
Учитывая требования приложения для видеоконференций, вы сможете понять, где может быть полезен Element Capture. Если у вас есть приложение для видеоконференций, позволяющее встраивать сторонние приложения в iframe, иногда может возникнуть необходимость захватить этот iframe как видео и передать его удалённым участникам.

Вызов getDisplayMedia()
и предоставление пользователю возможности выбрать текущую вкладку приведут к передаче всей текущей вкладки. Это, вероятно, будет означать передачу обратно видео пользователя. Вы можете обрезать его с помощью Region Capture .
Однако что делать, если докладчик взаимодействует с приложением для видеоконференций, и какой-либо контент, например раскрывающийся список, случайно отображается поверх контента, предназначенного для захвата?

В этом случае функция Region Capture вам не поможет. Часть раскрывающегося списка может оказаться видна на экранах удалённых участников.

Тот факт, что функция Region Capture захватывает части элементов таким образом (это называется перекрытием содержимого ), создает несколько проблем:
- Перекрытие контента может затруднить просмотр контента, которым пользователь намеревался поделиться.
- Скрытый контент может быть конфиденциальным (например, уведомления чата).
- Перекрытие контента может сбивать с толку. (Например, изменение макета приложения может на короткое время привести к отображению собственных видео удаленных участников поверх захваченного объекта.)
API Element Capture решает все эти проблемы, позволяя вам выбрать элемент, которым вы хотите поделиться.

Как использовать Element Capture?
captureTarget
— это элемент на вашей странице, содержащий контент, который пользователь хочет захватить. Вам нужно, чтобы веб-приложение для видеоконференций захватывало captureTarget
и делилось им с удалёнными участниками. Поэтому вы создаёте RestrictionTarget
из captureTarget
. После ограничения видеодорожки с помощью RestrictionTarget
кадры на этой видеодорожке теперь состоят только из пикселей, являющихся частью captureTarget
и его прямых потомков DOM.
Если 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
. После выполнения последнего обещания все последующие кадры будут ограничены.
// 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)
. Возвращённый Promise будет разрешён с новым объектом RestrictionTarget
в случае успешного выполнения. В противном случае он будет отклонён, если вы создали слишком много объектов RestrictionTarget
.
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
В отличие от Element, объект 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
.
В случае неудачи обещание отклоняется. Неудачный вызов restrictTo()
может произойти по одной из следующих причин:
- Если
restrictionTarget
был создан на вкладке, отличной от той, которая захватывается. (Обратите внимание, что с помощью кнопки «Поделиться этой вкладкой» пользователи могут в любой момент времени изменить вкладку, которая будет захватываться.) - Если
restrictionTarget
был получен из элемента, который больше не существует. - Если у трека есть клоны. (См. выпуск 1509418 .)
- Если текущая дорожка не является видеодорожкой самозахвата.
- Если элемент, из которого был получен
restrictionTarget
, не подлежит ограничению.
Соображения относительно самозахвата
Когда приложение вызывает getDisplayMedia()
, и пользователь решает захватить собственную вкладку приложения, мы называем это «самозахватом».
Метод restrictTo()
доступен для любой видеодорожки с захватом вкладок, а не только для захвата самого себя. Однако захват элементов пока доступен только для захвата самого себя. Поэтому рекомендуется проверять, выбрал ли пользователь текущую вкладку, прежде чем пытаться ограничить дорожку. Это можно сделать с помощью Capture Handle . Также можно попросить браузер подтолкнуть пользователя к захвату самого себя с помощью preferCurrentTab
.
Прозрачность
Видеокадры, получаемые приложением через getDisplayMedia()
не содержат альфа-канала. Если приложение устанавливает частично прозрачную цель захвата, удаление альфа-канала может иметь некоторые последствия:
- Цвета могут измениться. Частично прозрачные целевые элементы, нарисованные на светлом фоне, могут выглядеть темнее при отключении альфа-канала, а нарисованные на темном фоне — светлее.
- Цвета, которые были невидимы или невоспринимаемы пользователем при максимальном значении альфа-канала, проявляются после его удаления. Например, это может привести к появлению неожиданных чёрных областей на захваченных кадрах, если прозрачные участки имеют код RGBA
rgba(0, 0, 0, 0)
.

Неприемлемые цели захвата
Всегда можно начать ограничивать трек любой допустимой целью захвата. Однако кадры не будут создаваться при определённых условиях , например, если элемент или его предок имеет свойство display:none
. Обоснование заключается в том, что ограничение применяется только к элементу, представляющему собой единую, связную, двумерную прямоугольную область, пиксели которой могут быть логически определены изолированно от любых родительских или родственных элементов.
Одним из важных факторов, гарантирующих, что элемент соответствует требованиям ограничения, является то, что он должен формировать собственный контекст наложения . Для этого можно указать CSS-свойство изоляции , установив его в isolate
.
<div id="captureTarget" style="isolation: isolate;"></iframe>
Обратите внимание, что целевой элемент может в любой момент переключиться между режимом ограничения и режимом, недоступным для него, например, если приложение изменит свои CSS-свойства. Приложение должно использовать разумные цели захвата и избегать неожиданного изменения их свойств. Если целевой элемент становится недоступным, новые кадры просто не будут создаваться на треке до тех пор, пока целевой элемент снова не станет доступен для ограничения.
Поддержка браузеров
Element Capture доступен только на настольных компьютерах, начиная с Chrome 132.
Безопасность и конфиденциальность
Чтобы понять компромиссы в области безопасности, ознакомьтесь с разделом « Вопросы конфиденциальности и безопасности» спецификации Element Capture.
Браузер Chrome рисует синюю рамку по краям захваченных вкладок.
Демо
Вы можете поэкспериментировать с Element Capture, запустив демо-версию .
Обратная связь
Команда Chrome и сообщество веб-стандартов хотят узнать о вашем опыте работы с Element Capture.
Расскажите нам о дизайне
Есть ли что-то в Element Capture, что работает не так, как вы ожидали? Или отсутствуют методы или свойства, необходимые для реализации вашей идеи? Есть вопросы или комментарии по модели безопасности?
- Опубликуйте спецификацию проблемы в репозитории GitHub или добавьте свои мысли к существующей проблеме.
Проблема с реализацией?
Вы обнаружили ошибку в реализации Chrome? Или реализация отличается от спецификации?
- Сообщите об ошибке по адресу https://new.crbug.com . Опишите её как можно подробнее и предоставьте простые инструкции по её воспроизведению.
Полезные ссылки
Благодарности
Фото Пола Скорупскаса на Unsplash