https://habrahabr.ru/company/flashphoner/blog/339396/- Программирование
- Браузеры
- Safari
- JavaScript
- Блог компании Flashphoner
Пару недель назад состоялся релиз новых айфонов и iOS 11, который невозможно было не заметить. C релизом произошло еще одно, безусловно важное для разработчиков, событие: в браузере Safari появилась долгожданная поддержка WebRTC.
Вообразите на минуту, миллионы айфонов и айпадов по всему миру стали уметь реалтаймовое аудио и видео в браузере. Пользователям iOS и Mac стали доступны полнофункциональные браузерные видеочаты, воспроизведение живых трансляций с низкой (менее секунды) реалтаймовой задержкой, звонки, конференции и многое другое. К этому долго шли и наконец это случилось.
Было
Ранее
мы писали про способ играть видео с минимальной задержкой в iOS Safari, и этот способ до сих пор актуален для iOS 9 и iOS 10, где нет поддержки технологии WebRTC. Мы предлагали воспользоваться подходом под кодовым названием «WSPlayer», который позволяет доставить живой видеопоток с сервера по протоколу Websocket, далее декодировать поток с помощью JavaScript и отрисовать видеопоток в Canvas HTML5 элементе с использованием WebGL.Пришедший звуковой поток отыгрывался через Web Audio API браузера, и вот как это выглядело:
Этот подход позволял и позволяет сейчас воспроизводить поток на странице браузера iOS Safari с задержкой около 3 секунд, но имеет следующие недостатки:
1. Производительность.
Видеопоток декодируется средствами JavaScript. Это создает достаточно высокую нагрузку на CPU мобильного устройства, не дает играть высокие разрешения и утилизирует заряд батареи.
2. TCP.
Транспортным протоколом, по которому идет видео и аудио, является Websocket / TCP. По этой причине невозможно таргетировать задержку, которая может расти в зависимости от флуктуаций сети.
Все это время, пока не вышла iOS 11, WSPlayer мог играть видео с относительно низкой задержкой (3 секунды), по сравнению с HLS (20 секунд). Сейчас же все изменилось в лучшую сторону, и на смену JavaScript-плееру приходит нативная технология WebRTC, которая делает всю работу средствами самого браузера без декодирования на JavaScript и без использования Canvas.
Стало
С приходом WebRTC, схема воспроизведения видео с низкой задержкой в iOS Safari 11 стала идентичной другим браузерам уже поддерживающим WebRTC, а именно Chrome, Firefox, Edge.
Микрофон и камера
Выше мы писали только про воспроизведение реалтаймового видео. Однако видеочат не запустить без камеры и микрофона, и это было главным препятствием и основной головной болью разработчиков, которые планировали поддержку браузера iOS Safari в их видеочате или другом веб-проекте с живым видео. Сколько человеко-часов было потрачено напрасно на поиски решения в iOS Safari 9 и 10, когда этого решения попросту не существовало — Safari не мог захватывать камеру и микрофон, и эта «небаганофича» была исправлена совсем недавно в iOS 11.
Запускаем iOS 11 Safari и запрашиваем доступ к камере и микрофону. Именно этой простой вещи мы ждали и как видите, дождались:
Браузер спрашивает камеру и микрофон и может как стримить живые потоки, так и играть звук и видео.
А еще можно заглянуть в настройки браузера Safari и повключать / выключать микрофон там:
Отображение камеры и воспроизведение потокового видео
Не обошлось и без «особенностей». Главной отличительной особенностью воспроизведения видео в video — элементе, является тот факт, что для воспроизведения по странице надо кликнуть (тапнуть).
Для разработчиков это явное ограничение и тормоз. Ведь если заказчик требует — «Я хочу чтобы видео начинало проигрываться автоматически после загрузки страницы», в iOS Safari этот фокус не пройдет и разработчику придется объяснять, что во всем виноват Safari и Apple с их такой-то политикой безопасности.
Для пользователей же это может быть благом, поскольку сайты не смогут играть поток без ведома пользователя, который кликом по UI-элементу страницы как-бы формально подтверждает свое желание проиграть данный видеопоток.
Что насчет Mac OS?
Есть хорошие новости и для обладателей макбуков и Mac OS. После обновления, в Safari 11 под Mac также заработал WebRTC. До этого в Mac Safari использовался старый добрый Flash Player, позволяющий делать работу, которую делает WebRTC — жать и играть аудио и видео по сети через протоколы RTMP и RTMFP. Но с приходом WebRTC, необходимость использовать Flash Player для видеочатов отпала. Поэтому для Safari 11+ используем WebRTC, а для Safari 10 и меньше продолжаем использовать Flash Player или WebRTC-плагины в качестве fallback-механизма.
Уточним статус
Как видите, в Safari 11 добавилась поддержка WebRTC, а для Safari 9 и 10 остались fallbacks в виде Fash Player и WebRTC плагинов в Mac OS, а также WSPlayer в iOS.
Mac, Safari 10
|
iOS 9, 10, Safari |
Mac, Safari 11 |
iOS 11, Safari |
Flash Player
WebRTC plugins
WSPlayer
|
WSPlayer |
WebRTC |
WebRTC
|
Тестируем трансляцию с браузера на браузер
Теперь проверим на деле основные кейсы, и начнем, пожалуй с плеера. Прежде всего установим обновление iOS 11.0.2 c новым Safari.
Итак, в качестве первого теста, Chrome под Windows будет транслировать видеопоток на сервер, а зритель на iOS Safari будет играть видеопоток по WebRTC.
Открываем пример Two Way Streaming в браузере Chrome и отправляем WebRTC видеопоток с названием 1ad5 на сервер. Chrome захватывает видео с камеры, жмет в кодек H.264 в данном случае и отправляет на сервер живой поток для последующей раздачи. Трансляция видеопотока выглядит
так:
Для воспроизведения указываем имя потока и плеер в iOS Safari начинает играть поток, который был прежде отправлен Chrome на сервер. Воспроизведение потока на iPhone в браузере Safari выглядит
так:
Задержка незаметна (менее секунды). Видеопоток отыгрывается ровно, без намеков на артефакты. Качество воспроизведения нормальное, можно разглядеть по скриншотам.
А так выглядит воспроизведение видео в том же примере
Two Way Streaming в блоке Play. Таким образом, один поток можно транслировать, а второй играть на этой же странице браузера. Если пользователи знают имена потоков друг друга, получаем простой видеочат.
Тестируем трансляцию с вебкамеры и микрофона средствами iOS Safari
Как мы писали выше, основная фича WebRTC — это возможность захватить камеру и микрофон в браузере и отправить по сети с таргетированной низкой задержкой. Проверяем, как это работает в iOS Safari 11.
Открываем в Safari тот же пример демо-стримера, что открывали в Chrome. Получаем доступ к камере и микрофону. Safari показывает диалог, в котором предлагается разрешить или запретить использование камеры и микрофона.
После разрешения доступа к камере и микрофону, мы увидим в левом верхнем углу браузера красный значок камеры. Так Safari показывает что камера активна и используется. При этом видеопоток отправляется на сервер.
Забираем этот поток в другом браузере, например Chrome. На воспроизведении мы видим поток с Safari с ругаемой вертикальной съемкой, а все потому, что девайс не перевернули в горизонтальное положение.
После смены ориентации iPhone, картинка воспроизведения потока приобретает нормальный вид:
Захват и трансляция видео всегда технологически интереснее воспроизведения, потому что именно здесь проходят важные RTCP-фидбеки, которые таргетируют задержку и качество видео.
На момент напсания статьи мы не нашли подходящих инструментов для мониторинга WebRTC в браузере для iOS Safari, похожего на webrtc-internals для Chrome. Посмотрим как сервер видит захваченный с Safari видеопоток. Для этого включаем мониторинг и проверяем основные графики, описывающие входящий с Safari трафик.
Первая нарезка графиков показывает такие метрики как NACK и PLI, которые являются индикаторами потери UDP пакетов. Для нормальной сети количество NACK, показанное на графиках, незначительно, около 15, поэтому считаем, что анализы в пределах нормы.
FPS видеопотока колеблется в интервале 29,30,31 и не проседает до низких значений (10-15). Это значит, что аппаратному ускорителю iPhone хватает производительности для кодирования видео в H.264 кодек, а процессора достаточно для стриминга этого видео в сеть. Для данного теста мы использовали iPhone 6, 16 GB.
Следующие графики показывают как меняется разрешение видео и битрейт. Видео битрейт меняется в диапазоне 1.2 — 1.6 Mbps, разрешение видео остается неизменным 640x480. Это говорит о том, что хватает полосы для кодирования видео и Safari жмет видео с максимальным битрейтом. При желании битрейт может быть зажат в нужных пределах.
Далее проверяем битрейт аудио составляющей потока и статистику аудио потерь. Из графика видно, что аудио не теряется, счетчик потерь стоит на нуле. Битрейт аудио составляет 30-34 kbps. Это кодек Opus, которым Safari жмет аудио поток захваченный с мирофона.
И последний график — это таймкоды. По нему мы оцениваем насколько синхронно заходит аудио и видео. Если синхронности нет, то становится заметной визуальная рассинхронизация, когда голос не успевает за губами, или наоборот идет вперед видео. В данном случае, поток с Safari заходит идеально синхронно и монотонно без малейших отклонений.
Из представленных графиков видна картина, типичная для WebRTC и поведение, очень похожее на поведение браузера Google Chrome: приходят фидбэки NACK и PLI, незначительно меняется FPS, плавает битрейт. Т.е получаем тот WebRTC, которого ждали.
Обратить внимание стоит на изменение высоты и ширины. Например, если поменять положение устройства на горизонтальное, разрешение потока изменится на противоположное, например с 640x480 на 480x640, как на графике ниже.
Оранжевой линией на графике показана ширина, а синей высота картинки. В 05:21:17 мы переворачиваем iPhone, который стримит поток, в горизонтальное положение и разрешение потока меняется ровно на противоположное 480 по ширине и 640 по высоте.
Тестируем воспроизведение видео с IP-камеры, в WebRTC для iOS Safari
IP-камера чаще всего представляет собой портативный Linux-сервер, отдающий потоки по протоколу RTSP. В этом тесте мы забираем видео с IP камеры с поддержкой H.264 и играем это видео в браузере iOS Safari по WebRTC. Для этого в плеере, который показывали выше, вводим вместо имени потока, его RTSP адрес.
Воспроизведение потока с IP-камеры в Safari по WebRTC выглядит
так:
Видео в данном случае отыгрывает плавно, без каких-либо проблем с картинкой. Но здесь еще много зависит от источника стрима — от того, как видео с камеры будет заходить на сервер.
В итоге мы успешно протестировали следующие 3 кейса:
- Трансляцию с Chrome браузера на Safari
- Захват камеры и микрофона с трансляцией с Safari на Chrome
- Воспроизведение видео с IP-камеры в iOS Safari
Немного про код
Для трансляции видеопотоков, мы используем универсальное API (
Web SDK), которое в части трансляции выглядит так:
session.createStream({name:'stream22',display:document.getElementById('myVideo')}).publish();
Здесь мы задаем уникальное имя потока stream22 и используем div-элемент:
<div id='myVideo'></div>
Для отображения захватываемой камеры на web-странице.
Воспроизведение этого же видеопотока в браузере работает так:
session.createStream({name:'stream22',display:document.getElementById('myVideo')}).play();
Т.е. снова обозначаем имя потока и указываем div-элемент, в котором требуется разместить видео для воспроизведения. С последующим вызовом метода play().
iOS Safari, на текущий момент является единственным браузером, в котором необходимо кликнуть по элементу страницы, чтобы видео заиграло.
Поэтому мы добавили небольшой код, специально для iOS Safari, который «активирует» video-элемент перед воспроизведением потока, путем вызова следующего
кода:
if (Flashphoner.getMediaProviders()[0] === "WSPlayer") {
Flashphoner.playFirstSound();
} else if ((Browser.isSafariWebRTC() && Flashphoner.getMediaProviders()[0] === "WebRTC") || Flashphoner.getMediaProviders()[0] === "MSE") {
Flashphoner.playFirstVideo(remoteVideo);
}
Этот код в стандартном плеере вызывается по клику на кнопку Play, и тем самым мы выполняем требование Apple и корректно начинаем воспроизведение.
Flashphoner.playFirstVideo(remoteVideo);
В завершение
iOS 11 Safari наконец получил поддержку WebRTC и вряд ли эта поддержка будет выпилена в следующих апдейтах. Поэтому смело пользуемся этой возможностью и делаем реалтаймовое потоковое видео и звонки в этом браузере. Устанавливаем дальнейшие обновления iOS 11.x и ждем новых фиксов и багов фич. Хорошего стриминга!
Ссылки
WCS — сервер, с которым тестировали трансляции на iOS 11 Safari
Two Way Streaming — пример транслятора
Source Two Way Streaming — исходники стримера
Player — пример плеера
Source Player — исходники плеера
WSPlayer — воспроизведение потоков с низкой задержкой в iOS 9, 10 Safari