С помощью API захвата экрана вы можете захватить всю текущую вкладку. API захвата элементов позволяет захватывать и записывать определенный элемент HTML. Он преобразует захват всей вкладки в захват определенного поддерева DOM, захватывая только прямых потомков целевого элемента. Другими словами, он обрезает и удаляет как перекрывающий, так и перекрытый контент.
Зачем использовать захват элементов?
Рассмотрение требований приложения для видеоконференций может помочь вам понять, где полезен Element Capture. Если у вас есть приложение для видеоконференций, которое позволяет встраивать сторонние приложения в iframe, иногда вам может потребоваться захватить этот iframe как видео и передать его удаленным участникам.
Вызов getDisplayMedia()
и предоставление пользователю возможности выбрать текущую вкладку приведет к передаче всей текущей вкладки. Скорее всего, это приведет к передаче собственного видео людей обратно. Вы можете обрезать это с помощью «Захвата региона» .
Однако что, если докладчик взаимодействует с приложением для видеоконференций, а некоторый контент, например раскрывающийся список, отображается поверх контента, предназначенного для захвата?
Захват региона вам здесь не поможет. Часть раскрывающегося списка может оказаться видимой на экранах удаленных участников.
Тот факт, что Region Capture захватывает части элементов таким способом (известным как перекрытие контента ), создает множество проблем:
- Закрытие контента может помешать просмотру контента, которым пользователь намеревался поделиться.
- Закрывающий контент может быть конфиденциальным (например, уведомления чата).
- Закрытие контента может сбить с толку. (Например, перепланировка приложения может на короткое время перенести собственные видео удаленных участников поверх захваченной цели.)
API 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)
. В случае успеха возвращенное обещание будет разрешено с помощью нового объекта RestrictionTarget
. В противном случае он будет отклонен, если вы создали необоснованное количество объектов RestrictionTarget
.
const captureTarget = document.querySelector("#captureTarget");
const restrictionTarget = await RestrictionTarget.fromElement(captureTarget);
В отличие от элемента, объект 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. Приложение должно использовать разумные цели захвата и избегать неожиданного изменения их свойств. Если целевой элемент становится неприемлемым, новые кадры просто не будут отправляться на дорожку до тех пор, пока целевой элемент снова не станет доступным для ограничения.
Включение захвата элементов
API Element Capture доступен в Chrome на рабочем столе под флагом Element Capture и может быть включен по адресу chrome://flags/#element-capture
.
Эта функция также проходит пробную версию Chrome 121 для настольных компьютеров , что позволяет разработчикам включить эту функцию для посетителей своих сайтов для сбора данных от реальных пользователей. Дополнительную информацию о пробных версиях оригинального продукта см. в разделе Начало работы с пробными версиями оригинального продукта.
Безопасность и конфиденциальность
Чтобы понять компромиссы в области безопасности, ознакомьтесь с разделом «Вопросы конфиденциальности и безопасности» спецификации Element Capture.
Браузер Chrome рисует синюю рамку по краям захваченных вкладок.
Демо
Вы можете поиграть с Element Capture, запустив демо-версию на Glitch. Обязательно ознакомьтесь с исходным кодом .
Обратная связь
Команда Chrome и сообщество веб-стандартов хотят услышать о вашем опыте работы с Element Capture.
Расскажите о дизайне
Что-то в функции «Захват региона» работает не так, как вы ожидали? Или вам не хватает методов или свойств, необходимых для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности?
- Сообщите о проблеме спецификации в репозитории GitHub или добавьте свои мысли к существующей проблеме.
Проблема с реализацией?
Вы нашли ошибку в реализации Chrome? Или реализация отличается от спецификации?
- Сообщите об ошибке на https://new.crbug.com . Обязательно включите как можно больше деталей и простые инструкции по воспроизведению. Glitch отлично подходит для быстрого и простого обмена репродукциями.
Полезные ссылки
Благодарности
Фото Пола Скорупскаса на Unsplash