Улучшенный обмен вкладками с помощью Capture Handle

Франсуа Бофор
François Beaufort

Browser Support

  • Хром: 102.
  • Край: 102.
  • Firefox: не поддерживается.
  • Safari: не поддерживается.

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

Несколько примеров иллюстрируют преимущества.

Пример 1: Если веб-приложение для видеоконференций захватывает веб-приложение для презентации, оно может предоставить пользователю элементы управления для навигации между слайдами. Поскольку элементы управления встроены непосредственно в веб-приложение для видеоконференций, пользователю не приходится постоянно переключаться между вкладкой видеоконференции и вкладкой с представленным материалом. Благодаря устранению этой нагрузки пользователь может более полно сосредоточиться на презентации.

Пример 2: Эффект «зеркальной стены» возникает, когда захваченная поверхность визуализируется обратно в место съёмки. В частности, если пользователь выбирает захват вкладки, в которой происходит видеозвонок, а веб-приложение для видеоконференций отображает локальный предварительный просмотр, будет наблюдаться этот неприятный эффект. С помощью функции захвата можно обнаружить и предотвратить самозахват, например, подавив локальный предварительный просмотр в веб-приложении.

Иллюстрация эффекта зеркального зала

О захвате ручки

Ручка захвата состоит из двух взаимодополняющих частей:

  • Захваченные веб-приложения могут разрешить предоставление определенной информации некоторым источникам с помощью navigator.mediaDevices.setCaptureHandleConfig() .
  • Затем захватывающие веб-приложения могут считывать эту информацию с помощью getCaptureHandle() на объектах MediaStreamTrack .

Захваченная сторона

Веб-приложения могут предоставлять информацию потенциальным веб-приложениям, которые будут перехватывать данные. Это осуществляется посредством вызова navigator.mediaDevices.setCaptureHandleConfig() с необязательным объектом, состоящим из следующих элементов:

  • handle : может быть любой строкой длиной до 1024 символов.
  • exposeOrigin : Если true , источник захваченного веб-приложения может быть раскрыт для захватывающих веб-приложений.
  • permittedOrigins : Допустимые значения: (i) пустой массив, (ii) массив с единственным элементом "*" или (iii) массив источников. Если permittedOrigins состоит из единственного элемента "*" , то CaptureHandle доступен для наблюдения всем веб-приложениям, осуществляющим захват. В противном случае он доступен только для веб-приложений, источник которых указан в permittedOrigins .

В следующем примере показано, как предоставить случайно сгенерированный UUID в качестве идентификатора и источника любому захватывающему веб-приложению.

const config = {
  handle: crypto.randomUUID(),
  exposeOrigin: true,
  permittedOrigins: ['*'],
};
navigator.mediaDevices.setCaptureHandleConfig(config);

Обратите внимание, что захваченное веб-приложение не знает, захватывается ли оно. За исключением случаев, когда захватывающее веб-приложение использует информацию CaptureHandle для установления связи с захваченным веб-приложением (например, посредством обмена сообщениями через воркер или общую облачную инфраструктуру).

Захватывающая сторона

Веб-приложение, осуществляющее захват, содержит видеопоток MediaStreamTrack и может прочитать информацию о дескрипторе захвата, вызвав метод getCaptureHandle() для этого MediaStreamTrack . Этот вызов возвращает значение null , если дескриптор захвата недоступен или если веб-приложению, осуществляющему захват, не разрешено его читать. Если дескриптор захвата доступен и веб-приложение, осуществляющее захват, добавлено в permittedOrigins , этот вызов возвращает объект со следующими членами:

  • handle : строковое значение, установленное захваченным веб-приложением с помощью navigator.mediaDevices.setCaptureHandleConfig() .
  • origin : Источник захваченного веб-приложения, если exposeOrigin имеет значение true . В противном случае он не определен.

В следующем примере показано, как считывать информацию о дескрипторе захвата с видеодорожки.

// Prompt the user to capture their display (screen, window, tab).
const stream = await navigator.mediaDevices.getDisplayMedia();

// Check if the video track is exposing information.
const [videoTrack] = stream.getVideoTracks();
const captureHandle = videoTrack.getCaptureHandle();
if (captureHandle) {
  // Use captureHandle.origin and captureHandle.handle...
}

Отслеживайте изменения CaptureHandle , прослушивая события "capturehandlechange" объекта MediaStreamTrack . Изменения происходят, когда:

  • Захваченное веб-приложение вызывает navigator.mediaDevices.setCaptureHandleConfig() .
  • В захваченном веб-приложении происходит междокументная навигация .
videoTrack.addEventListener('capturehandlechange', event => {
  captureHandle = event.target.getCaptureHandle();
  // Consume new capture handle...
});

Безопасность и конфиденциальность

Совместная работа между веб-приложениями, осуществляющими захват, и веб-приложениями, осуществляющими захват, теоретически возможна уже сегодня, например, путём внедрения «волшебных пикселей» в захваченное веб-приложение или QR-кодов в видеопоток. Capture Handle предлагает более простой, надёжный и безопасный механизм. Он также позволяет веб-приложению, осуществляющему захват, выбирать аудиторию — либо отдельные источники, либо всю сеть.

Обратите внимание, что navigator.mediaDevices.setCaptureHandleConfig() доступен только для основных фреймов верхнего уровня в безопасных контекстах просмотра (только HTTPS).

Образец

Вы можете поэкспериментировать с Capture Handle, запустив образец .

Демо-версии

Некоторые демо-версии доступны по адресу:

Обнаружение особенностей

Чтобы проверить, поддерживается ли getCaptureHandle() , используйте:

if ('getCaptureHandle' in MediaStreamTrack.prototype) {
  // getCaptureHandle() is supported.
}

Чтобы проверить, поддерживается ли navigator.mediaDevices.setCaptureHandleConfig() , используйте:

if ('setCaptureHandleConfig' in navigator.mediaDevices) {
  // navigator.mediaDevices.setCaptureHandleConfig() is supported.
}

Что дальше?

Вот краткий обзор того, чего можно ожидать в ближайшем будущем и что улучшит совместное использование экрана в Интернете:

  • Функция захвата области позволит обрезать видеодорожку, полученную в результате захвата экрана текущей вкладки.
  • Условный фокус позволит захватывающему веб-приложению дать указание браузеру либо переключить фокус на захваченную поверхность дисплея, либо избежать такого изменения фокуса.

Обратная связь

Команда Chrome и сообщество веб-стандартов хотят узнать о вашем опыте работы с Capture Handle.

Расскажите нам о дизайне

Есть ли что-то в Capture Handle, что работает не так, как вы ожидали? Или отсутствуют методы или свойства, необходимые для реализации вашей идеи? Есть вопросы или комментарии по модели безопасности?

  • Отправьте сообщение о проблеме со спецификацией в репозиторий GitHub или добавьте свои мысли к существующей проблеме.

Проблема с реализацией?

Вы обнаружили ошибку в реализации Chrome? Или реализация отличается от спецификации?

  • Сообщите об ошибке по адресу https://new.crbug.com . Опишите её как можно подробнее и предоставьте простые инструкции по её воспроизведению.

Показать поддержку

Планируете ли вы использовать Capture Handle? Ваша публичная поддержка помогает команде Chrome расставлять приоритеты в отношении функций и показывает другим разработчикам браузеров, насколько важна их поддержка.

Отправьте твит @ChromiumDev и расскажите, где и как вы его используете.

Благодарности

Спасибо Джо Медли за рецензирование этой статьи.