На CSSConf AU 2016 Соледад Пенадес выступила с докладом Алхимия фронтенда в реальном времени. Было полно примеров совмещения MediaStreams с манипуляциями с аудио и видео.

Чего я не знал, так это того, что вы можете записывать аудио и видео в браузере без каких-либо плагинов. Вы можете комбинировать звук с микрофона, видео с холста, динамически генерируемый контент… что угодно. Даже запись окна или всего экрана и экспорт в виде видео.

Лучший способ учиться — это практиковаться и, цитируя Соледад, нам нужно, чтобы вы поиграли с этим, внесли свой вклад и помогли нам сделать его лучше. Опробовав эти новые API, мы сообщаем поставщикам браузеров, что эти инструменты полезны, и мы можем протестировать их и предоставить предварительный отзыв.

Проект

У меня была идея создать прототип в стиле ScreenFlow. Я показывал свою веб-камеру в углу экрана и генерировал видео, объединяющее звук с микрофона и изображение с экрана.

Я немного погуглил и нашел очень мало сайтов, говорящих об этих API. Практически только MDN и другой пост Соледад. Я подумал, что этот небольшой эксперимент также поможет тем, кто ищет примеры.

Примечание. По состоянию на декабрь 2016 года эта демонстрация поддерживается только в Firefox. Chrome не поддерживается по умолчанию, требуется расширение и много пользовательского кода (см. этот эксперимент WebRTC для получения дополнительной информации. Он покажет вашу камеру, но ничего не запишет.

Код

Код проекта находится на странице JMPerez/screenflow на GitHub, а демоверсия доступна на странице jmperezperez.com/screenflow.

Рассмотрим наиболее важные фрагменты кода. Прежде всего, мы определяем функции для запроса доступа к различным источникам мультимедиа:

Теперь мы выполняем их, один за другим. Я пробовал выполнять оба параллельно, полагая, что браузер объединит оба запроса в диалоге разрешений, но это не сработало. Итак, идея состоит в том, чтобы запросить доступ к веб-камере, вставить элемент <video> с медиа с камеры, а затем запросить доступ к окну и записать его.

Теперь нам, наконец, нужно вызывать this.recorder.stop() всякий раз, когда мы хотим остановить запись, что заставит браузер автоматически сохранять файл. В моем примере я прикрепляю прослушиватель ключевых событий для клавиши «escape».

Примечание о разрешениях

Чтобы это работало, вам нужно внести в белый список домен, пытающийся записать ваш экран. В Firefox localhost будет работать из коробки. Если вы хотите опубликовать код где-то еще, например на GitHub Pages, убедитесь, что вы внесли его в белый список.

В Firefox перейдите к about:config и найдите ключ media.getusermedia.screensharing.allowed_domains. Добавьте свой домен в список и перезапустите браузер.

Затем при запуске кода пользователь сможет предоставить доступ как к веб-камере, так и к окну.

Обратите внимание, что вам не нужно записывать окно браузера, в котором запущен скрипт. Вы можете выбрать другое окно или весь экран (с запросом «экран» вместо «окно» как mediasource.

Неясно, будет ли это то, как пользователь позволяет сайту записывать свой экран, но на данный момент это работает именно так.

Еще один шаг, сделав это встраиваемым

Пример кода работал нормально, но я хотел пойти дальше. Что, если я захочу использовать эту функцию «записи» более чем в одном проекте? Кроме того, учитывая, что пользователь должен внести домен в белый список, мы могли бы использовать код из iframe в этом домене, поэтому нам не нужно было бы добавлять дополнительные домены в about:config.

Окончательная версия прототипа теперь основана на сценарии, который вы добавляете на страницу. Сценарий добавляет iframe, который выполняет код, который мы видели выше, и показывает вывод веб-камеры в полном размере. Помимо iframe, он также связывает несколько прослушивателей ключевых событий для переключения видимости и размера iframe.

Это клавиши, которые вы можете нажимать для выполнения некоторых действий:

  • Escape: завершает запись и сохраняет файл.
  • s: переключение камеры между полноэкранным режимом и режимом «картинка в картинке».
  • a: Переключает видимость камеры

Затем вы можете включить сценарий на любую страницу, чтобы получить эту функцию записи экрана. Например, мы можем включить https://jmperezperez.com/screenflow/lib/embed.js в Codepen и записать скринкаст.

Ограничения

Имейте в виду, что это только доказательство концепции и не имеет никакой реальной пользы. Если вы серьезно относитесь к записи скринкаста, не используйте этот лайфхак :)

Есть, конечно, некоторые ограничения:

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

Первоначально опубликовано на jmperezperez.com.