Совместное использование вкладок, окон и экранов уже возможно на веб-платформе с помощью API захвата экрана . Когда веб-приложение вызывает getDisplayMedia()
, Chrome предлагает пользователю поделиться вкладкой, окном или экраном с веб-приложением в виде видео MediaStreamTrack
.
Многие веб-приложения, использующие getDisplayMedia()
, показывают пользователю видеопревью захваченной поверхности. Например, приложения для видеоконференций часто транслируют это видео удаленным пользователям, одновременно отображая его в локальном HTMLVideoElement
, чтобы локальный пользователь постоянно видел превью того, чем он делится.
В этой документации представлен новый API управления захваченной поверхностью в 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()
, приложение захвата может пересылать события колеса из исходного элемента внутри самого приложения захвата в область просмотра захваченной вкладки. Эти события неотличимы для захваченного приложения от прямого взаимодействия с пользователем.
Предполагая, что приложение захвата использует элемент <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"
позволяет вам управлять тем, как ваше приложение захвата и встроенные сторонние iframes имеют доступ к Captured Surface Control. Чтобы понять компромиссы безопасности, ознакомьтесь с разделом " Соображения конфиденциальности и безопасности" в объяснении Captured Surface Control.
Демо
Вы можете поиграть с Captured Surface Control, запустив демо на Glitch. Обязательно ознакомьтесь с исходным кодом .
Обратная связь
Команда Chrome и сообщество веб-стандартов хотят услышать о вашем опыте использования Captured Surface Control.
Расскажите нам о дизайне
Есть ли что-то в Captured Surface Capture, что работает не так, как вы ожидали? Или отсутствуют методы или свойства, которые вам нужны для реализации вашей идеи? У вас есть вопрос или комментарий по модели безопасности? Отправьте запрос спецификации в репозиторий GitHub или добавьте свои мысли к существующему запросу.
Проблемы с реализацией?
Вы нашли ошибку в реализации Chrome? Или реализация отличается от спецификации? Сообщите об ошибке на https://new.crbug.com . Обязательно включите как можно больше подробностей, а также инструкции по воспроизведению.