Совместное использование вкладок, окон и экранов уже возможно на веб-платформе с помощью API захвата экрана . Когда веб-приложение вызывает getDisplayMedia()
, Chrome предлагает пользователю поделиться вкладкой, окном или экраном с веб-приложением в виде видео MediaStreamTrack
.
Многие веб-приложения, использующие getDisplayMedia()
показывают пользователю предварительный просмотр захваченной поверхности. Например, приложения для видеоконференций часто передают это видео в потоковом режиме удаленным пользователям, а также визуализируют его в локальный HTMLVideoElement
, чтобы локальный пользователь постоянно видел предварительный просмотр того, чем они делятся.
В этой документации представлен новый API Captured Surface Control в Chrome, который позволяет вашему веб-приложению прокручивать захваченную вкладку, а также считывать и записывать уровень масштабирования захваченной вкладки.
Зачем использовать Captured Surface Control?
Все приложения для видеоконференций страдают одним и тем же недостатком. Если пользователь хочет взаимодействовать с захваченной вкладкой или окном, он должен переключиться на эту поверхность, убрав его из приложения для видеоконференций. Это создает некоторые проблемы:
- Пользователь не может видеть захваченное приложение и видеопотоки удаленных пользователей одновременно, если они не используют функцию «Картинка в картинке» или отдельные параллельные окна для вкладок «Видеоконференция» и «Общий доступ». На маленьком экране это может быть сложно.
- Пользователь отягощен необходимостью переключаться между приложением для видеоконференций и захваченной поверхностью.
- Пользователь теряет доступ к элементам управления, предоставляемым приложением для видеоконференций, пока он находится вдали от него; например, встроенное приложение чата, реакции с помощью смайликов, уведомления о пользователях, предлагающих присоединиться к звонку, элементы управления мультимедиа и макетом, а также другие полезные функции видеоконференций.
- Докладчик не может делегировать управление удаленным участникам. Это приводит к слишком знакомому сценарию, когда удаленные пользователи просят докладчика сменить слайд, немного прокрутить вверх и вниз или отрегулировать уровень масштабирования.
API Captured Surface Control решает эти проблемы.
Как использовать Captured Surface Control?
Для успешного использования Captured Surface Control требуется несколько шагов, таких как явный захват вкладки браузера и получение разрешения от пользователя, прежде чем он сможет прокручивать и масштабировать захваченную вкладку.
Захват вкладки браузера
Начните с предложения пользователю выбрать поверхность для совместного использования с помощью getDisplayMedia()
и в процессе свяжите объект CaptureController
с сеансом захвата. Вскоре мы будем использовать этот объект для управления захваченной поверхностью.
const controller = new CaptureController();
const stream = await navigator.mediaDevices.getDisplayMedia({ controller });
Далее создайте локальный предварительный просмотр захваченной поверхности в виде элемента <video>
:
const previewTile = document.querySelector('video');
previewTile.srcObject = stream;
Если пользователь решит поделиться окном или экраном, на данный момент это выходит за рамки, но если он решил поделиться вкладкой, мы можем продолжить.
const [track] = stream.getVideoTracks();
if (track.getSettings().displaySurface !== 'browser') {
// Bail out early if the user didn't pick a tab.
return;
}
Запрос разрешения
Первый вызов метода forwardWheel()
, increaseZoomLevel()
, decreaseZoomLevel()
или resetZoomLevel()
для данного объекта CaptureController
вызывает запрос на разрешение. Если пользователь дает разрешение, дальнейшие вызовы этих методов разрешены.
Жест пользователя необходим для отображения запроса на разрешение пользователю, поэтому приложение должно вызывать вышеупомянутые методы только в том случае, если у него уже есть разрешение или в ответ на жест пользователя, например click
соответствующей кнопки в веб-приложении.
Прокрутка
ИспользуяforwardWheel forwardWheel()
, приложение захвата может пересылать события колеса из исходного элемента внутри самого приложения захвата в область просмотра захваченной вкладки. Эти события неотличимы для захваченного приложения от прямого взаимодействия с пользователем.
Предполагая, что приложение захвата использует элемент <video>
под названием "previewTile"
, следующий код показывает, как ретранслировать события колеса отправки на захваченную вкладку:
const previewTile = document.querySelector('video');
try {
// Relay the user's action to the captured tab.
await controller.forwardWheel(previewTile);
} catch (error) {
// Inspect the error.
// ...
}
Метод forwardWheel()
принимает один входной сигнал, который может быть одним из следующих:
- Элемент HTML, из которого события колеса будут пересылаться на захваченную вкладку.
-
null
, указывающий, что пересылка должна быть остановлена.
Успешный forwardWheel()
отменяет предыдущие вызовы.
Промис, возвращаемый функцией forwardWheel()
может быть отклонен в следующих случаях:
- Если сеанс захвата еще не начался или уже остановлен.
- Если пользователь не предоставил соответствующее разрешение.
Увеличить
Взаимодействие с уровнем масштабирования захваченной вкладки осуществляется через следующие поверхности API CaptureController
:
getSupportedZoomLevels()
Этот метод возвращает список уровней масштабирования, поддерживаемых браузером для типа захватываемой поверхности. Значения в этом списке представлены в процентах относительно «уровня масштабирования по умолчанию», который определяется как 100%. Список монотонно увеличивается и содержит значение 100.
Этот метод можно вызывать только для поддерживаемых типов поверхностей отображения, что на данный момент означает только для вкладок.
controller.getSupportedZoomLevels()
можно вызвать, если выполняются следующие условия:
-
controller
связан с активным захватом. - Захват представляет собой вкладку.
В противном случае будет выдана ошибка.
Разрешение "captured-surface-control"
не требуется для вызова этого метода.
zoomLevel
Этот атрибут только для чтения содержит текущий уровень масштабирования захваченной вкладки. Это атрибут, допускающий значение NULL, и он имеет значение null
если тип захваченной поверхности не имеет значимого определения уровня масштабирования. В настоящее время уровень масштабирования определяется только для вкладок, а не для окон или экранов.
После завершения захвата атрибут будет содержать последнее значение уровня масштабирования.
Для чтения этого атрибута не требуется разрешение "captured-surface-control"
.
onzoomlevelchange
Этот обработчик событий облегчает прослушивание изменений уровня масштабирования захваченной вкладки. Это происходит либо:
- Когда пользователь взаимодействует с браузером, чтобы вручную изменить уровень масштабирования захваченной вкладки.
- В ответ на вызовы приложения захвата методов настройки масштаба (описанных ниже).
Для чтения этого атрибута не требуется разрешение "captured-surface-control"
.
increaseZoomLevel()
, decreaseZoomLevel()
и resetZoomLevel()
Эти методы позволяют манипулировать уровнем масштабирования захваченной вкладки.
increaseZoomLevel()
и decreaseZoomLevel()
изменяют уровень масштабирования на следующий или предыдущий уровень масштабирования соответственно в соответствии с порядком, возвращаемым getSupportedZoomLevels()
. resetZoomLevel()
устанавливает значение 100.
Для вызова этих методов требуется разрешение "captured-surface-control"
. Если у приложения для захвата нет этого разрешения, пользователю будет предложено предоставить или отклонить его.
Все эти методы возвращают обещание, которое выполняется, если вызов успешен, и отклоняется в противном случае. К возможным причинам отказа относятся:
- Отсутствует разрешение.
- Вызывается до начала захвата.
- Вызывается после окончания захвата.
- Вызывается на
controller
, связанном с захватом неподдерживаемого типа поверхности дисплея. (То есть что угодно, кроме захвата табуляции.) - Попытки увеличить или уменьшить значение, превышающее максимальное или минимальное значение соответственно.
Примечательно, что рекомендуется избегать вызова decreaseZoomLevel()
если controller.zoomLevel == controller.getSupportedZoomLevels().at(0)
, и защищать вызовы increaseZoomLevel()
аналогично .at(-1)
.
В следующем примере показано, как разрешить пользователю увеличивать уровень масштабирования захваченной вкладки непосредственно из приложения для захвата:
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.
// ...
}
});
В следующем примере показано, как реагировать на изменения уровня масштабирования захваченной вкладки:
controller.addEventListener('zoomlevelchange', (event) => {
const zoomLevelLabel = document.querySelector('#zoomLevelLabel');
zoomLevelLabel.textContent = `${controller.zoomLevel}%`;
});
Обнаружение функций
Чтобы проверить, поддерживаются ли API Captured Surface Control, используйте:
if (!!window.CaptureController?.prototype.forwardWheel) {
// CaptureController forwardWheel() is supported.
}
В равной степени можно использовать любые другие поверхности API Captured Surface Control, такие как increaseZoomLevel
или decreaseZoomLevel
, или даже проверить их все.
Поддержка браузера
Captured Surface Control доступен только в Chrome 136 на настольном компьютере.
Безопасность и конфиденциальность
Политика разрешений "captured-surface-control"
позволяет вам управлять тем, как ваше приложение для захвата и встроенные сторонние iframe имеют доступ к Captured Surface Control. Чтобы понять компромиссы в области безопасности, ознакомьтесь с разделом « Вопросы конфиденциальности и безопасности» в пояснении «Контроль захваченных поверхностей».
Демо
Вы можете поиграть с Captured Surface Control, запустив демо-версию на Glitch. Обязательно ознакомьтесь с исходным кодом .
Обратная связь
Команда Chrome и сообщество веб-стандартов хотят услышать о вашем опыте использования Captured Surface Control.
Расскажите о дизайне
Есть ли что-то в Captured Surface Capture, что работает не так, как вы ожидали? Или вам не хватает методов или свойств, необходимых для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности? Сообщите о проблеме спецификации в репозитории GitHub или добавьте свои мысли к существующей проблеме.
Проблема с реализацией?
Вы нашли ошибку в реализации Chrome? Или реализация отличается от спецификации? Сообщите об ошибке на https://new.crbug.com . Обязательно включите как можно больше деталей, а также инструкции по воспроизведению. Glitch отлично подходит для обмена воспроизводимыми ошибками.