Веб-платформа уже позволяет веб-приложению захватывать видеодорожку текущей вкладки. Теперь он поставляется с Region Capture — механизмом обрезки этих видеодорожек. Веб-приложение назначает часть текущей вкладки областью интереса, а браузер обрезает все пиксели за пределами этой области.
Раньше веб-приложения могли обрезать видеодорожки «вручную». То есть веб-приложения могут напрямую манипулировать каждым кадром. Это не было ни надежным, ни производительным. Region Capture устраняет эти недостатки. Веб-приложение теперь может поручить браузеру выполнить работу от его имени.
О захвате региона
Итак, вы создали веб-сайт с динамическим контентом™. Это лучшее веб-приложение на свете, и люди просто не могут перестать его использовать, часто совместно. Возможным следующим шагом является внедрение возможностей виртуальных конференций. Вы решаете пойти с этим. Вы объединяетесь с существующим поставщиком услуг видеоконференцсвязи и встраиваете его веб-приложение в виде iframe из разных источников. Веб-приложение для видеоконференций записывает текущую вкладку в виде видеодорожки и передает ее удаленным участникам.
Не так быстро… Вы ведь не хотите передавать им собственные видео людей, не так ли? Лучше обрезать эту часть. Но как? Встроенный iframe не знает, какой контент вы выставляете и где, поэтому не может обрезать его без посторонней помощи. Теоретически вы могли бы передать намеченные координаты. Но что произойдет, если пользователь изменит размер окна? Прокручивает область просмотра? Увеличивает или уменьшает масштаб? Взаимодействует со страницей таким образом, что приводит к изменению макета? Даже если вы отправите новые координаты в захватывающий iframe, проблемы с синхронизацией все равно могут привести к неправильной обрезке некоторых кадров.
Тогда давайте воспользуемся захватом региона. На вашей странице есть Element
, возможно, <div>
, который содержит основной контент. Назовем его mainContentArea
. Вы хотите, чтобы веб-приложение для видеоконференций удаленно захватывало и предоставляло общий доступ к области, определенной ограничивающей рамкой этого элемента. Таким образом, вы получаете CropTarget
из mainContentArea
. Вы передаете этот CropTarget
в веб-приложение для видеоконференций. После обрезки видеодорожки с помощью этого CropTarget
кадры на этой дорожке теперь состоят только из пикселей, попадающих в ограничивающую рамку mainContentArea
. Если mainContentArea
меняет размер, форму или местоположение, видеодорожка следует за ней, не требуя каких-либо дополнительных входных данных со стороны какого-либо веб-приложения.
Давайте еще раз пройдемся по этим шагам:
Вы определяете CropTarget
в своем веб-приложении, вызывая CropTarget.fromElement()
с выбранным вами элементом в качестве входных данных.
// In the main web app, associate mainContentArea with a new CropTarget
const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);
Вы передаете CropTarget
в веб-приложение для видеоконференций.
// Send the CropTarget to the video conferencing web app.
const iframe = document.querySelector("#videoConferenceIframe");
iframe.contentWindow.postMessage(cropTarget);
Веб-приложение для видеоконференций запрашивает браузер обрезать дорожку до области, определенной CropTarget
, вызывая функцию cropTo()
на видеодорожке самостоятельного захвата с целью обрезки, полученной из основного веб-приложения.
// In the embedded video conferencing web app, ask the user for permission
// to start capturing the current tab.
const stream = await navigator.mediaDevices.getDisplayMedia({
preferCurrentTab: true,
});
const [track] = stream.getVideoTracks();
// Start cropping the self-capture video track using the CropTarget
// received over window.onmessage.
await track.cropTo(cropTarget);
// Enjoy! Transmit remotely the cropped video track with RTCPeerConnection.
И вуаля! Все готово.
Глубокое погружение
Обнаружение функций
Чтобы проверить, поддерживается ли CropTarget.fromElement()
, используйте:
if ("CropTarget" in self && "fromElement" in CropTarget) {
// Deriving a target is supported.
}
Получение CropTarget
Давайте сосредоточимся на элементе под названием mainContentArea
. Чтобы получить из него CropTarget
, вызовите CropTarget.fromElement(mainContentArea)
. В случае успеха возвращенное обещание будет разрешено с помощью нового объекта CropTarget
. В противном случае он будет отклонен, если вы создали необоснованное количество объектов CropTarget
.
const mainContentArea = document.querySelector("#mainContentArea");
const cropTarget = await CropTarget.fromElement(mainContentArea);
В отличие от Element
, объект CropTarget
является сериализуемым . Его можно передать в другой документ, например, с помощью Window.postMessage()
.
Обрезка
При захвате табуляции видеодорожка создается как BrowserCaptureMediaStreamTrack
, который является подклассом MediaStreamTrack
. Этот подкласс предоставляет cropTo()
. Вызовите track.cropTo(cropTarget)
, чтобы начать обрезку по контурам mainContentArea
(элемент, из которого был получен CropTarget).
В случае успеха Promise будет разрешен, когда можно будет гарантировать, что все последующие видеокадры будут состоять из пикселей, попадающих в ограничивающую рамку mainContentArea
.
В случае неудачи обещание будет отклонено. Это произойдет, если:
-
CropTarget
был создан на другой вкладке. (Пока — следите за обновлениями.) -
CropTarget
был получен из элемента, который больше не существует. - У трека есть клоны . (См. выпуск 1509418. )
- Текущая дорожка не является видеодорожкой самозахвата; см. ниже.
cropTo()
доступен для любой видеодорожки захвата табуляции, а не только для самостоятельного захвата. Поэтому рекомендуется проверить, выбрал ли пользователь текущую вкладку, прежде чем пытаться обрезать дорожку. Это можно сделать с помощью Capture Handle . Также можно попросить браузер подтолкнуть пользователя к самозахвату с помощью preferCurrentTab
.
// Start cropping the self-capture video track using the CropTarget.
await track.cropTo(cropTarget);
Чтобы вернуться в необрезанное состояние, вызовитеcropTo cropTo()
с null
.
// Stop cropping.
await track.cropTo(null);
Перекрывающий и перекрытый контент
Для захвата региона имеют значение только положение и размер цели, а не z-index . Пиксели, закрывающие цель, будут захвачены. Закрытые части цели не будут захвачены.
Это следствие того, что захват региона по сути является обрезкой. Одной из альтернатив, которая в будущем станет отдельным API, является захват на уровне элемента; то есть захватывать только пиксели, связанные с целью, независимо от перекрытий. У такого API другой набор требований к безопасности и конфиденциальности, чем у простого обрезки.
Безопасность и конфиденциальность
Region Capture позволяет веб-приложению, которое уже отслеживает все пиксели на вкладке, добровольно удалить некоторые из этих пикселей. Это абсолютно безопасно, поскольку невозможно получить новую информацию.
Захват региона можно использовать для ограничения того, какая информация отправляется удаленным участникам. Например, возможно, вы хотите поделиться некоторыми слайдами, но не заметками докладчика.
Обратите внимание, что локально Region Capture не добавляет никаких гарантий безопасности. При передаче дорожки в другой документ принимающий документ все равно может отменить обрезку дорожки и получить доступ ко всем захваченным пикселям вкладки.
Chrome рисует синюю рамку по краям захваченных вкладок. При обрезке Chrome обычно рисует синюю рамку вокруг обрезанного объекта.
Демо
Вы можете поиграть с «Захватом региона», запустив демо-версию на Glitch. Обязательно ознакомьтесь с исходным кодом .
Поддержка браузера
Поддержка браузера
Захват региона доступен только в Chrome 104 на настольном компьютере.
Что дальше
Вот краткий обзор того, чего ожидать в ближайшем будущем, что улучшит совместное использование экрана в Интернете:
- Захват региона будет поддерживать захват других вкладок.
- Условный фокус позволит захватывающему веб-приложению дать браузеру указание либо переключить фокус на захваченную поверхность дисплея, либо избежать такого изменения фокуса.
- Может быть предоставлен API захвата на уровне элемента .
Обратная связь
Команда Chrome и сообщество веб-стандартов хотят услышать о вашем опыте использования Region Capture.
Расскажите о дизайне
Что-то в функции «Захват региона» работает не так, как вы ожидали? Или вам не хватает методов или свойств, необходимых для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности?
- Сообщите о проблеме спецификации в репозитории GitHub или добавьте свои мысли к существующей проблеме.
Проблема с реализацией?
Вы нашли ошибку в реализации Chrome? Или реализация отличается от спецификации?
- Сообщите об ошибке на https://new.crbug.com . Обязательно включите как можно больше деталей и простые инструкции по воспроизведению. Glitch отлично подходит для быстрого и простого обмена репродукциями.
Показать поддержку
Планируете ли вы использовать захват региона? Ваша публичная поддержка помогает команде Chrome расставлять приоритеты в функциях и показывает другим поставщикам браузеров, насколько важно их поддерживать.
Отправьте твит @ChromiumDev и сообщите нам, где и как вы его используете.
Полезные ссылки
Благодарности
Спасибо Джо Медли за рецензирование этой статьи.