не удается установить webrtc подключение на телефоне
WebRTC на Android: как включить аппаратное кодирование на множестве устройств
Для видеозвонков в Badoo мы используем стандарт WebRTC и кодек H.264. Если верить документации, этот кодек должен без проблем работать на любых устройствах Android начиная с Android 5.0. Но на практике всё оказалось не совсем так. В этой статье я расскажу про особенности реализации аппаратного кодирования для кодека H.264 в WebRTC и о том, как заставить его работать на большем количестве устройств.
Почему именно H.264?
При соединении по WebRTC все устройства, участвующие в сеансе, передают различные параметры связи, в том числе видео- и аудиокодеки. Если устройства поддерживают несколько кодеков (например, VP8 и H.264), приоритетные для платформы кодеки указываются первыми. Эти данные используются на этапе согласования в WebRTC, после которого остаются только кодеки, поддерживаемые всеми устройствами. Пример таких данных с расшифровкой можно увидеть в этом документе.
В случае с видеозвонками при отсутствии на одном из устройств поддержки кодека H.264 оба устройства могут перейти, например, на кодек VP8, который не зависит от аппаратной реализации на устройстве. Но наше приложение доступно на самых разных гаджетах, в том числе на смартфонах предыдущих поколений. Поэтому для видеосвязи мы хотели по возможности использовать аппаратное кодирование: оно снижает нагрузку на процессор и не так сильно ест батарею, что критично для устаревших гаджетов. Поддержка аппаратного кодирования H.264 реализована на большом количестве устройств, в отличие от того же VP8.
Поддержка H.264 на Android
Если верить описанию поддержки форматов мультимедиа, декодирование H.264 Baseline Profile должно работать на всех Android-устройствах, а кодирование — начиная с Android 3.0. В Badoo мы поддерживаем устройства начиная с Android 5.0, так что у нас не должно было возникнуть проблем. Но всё оказалось не так просто: даже в гаджетах с пятой версией мы обнаружили большое количество особенностей.
С чем это может быть связано?
Как известно, при разработке нового устройства на Android любому производителю необходимо пройти набор тестов Compatibility Test Suite. Он запускается на подключённом к устройству ПК, а его результаты необходимо отправить в Google для подтверждения того, что устройство соответствует требованиям ОС Android указанной версии. Только после этого гаджет можно выпустить на рынок.
Нас в этом наборе тестов интересуют мультимедиа-тесты, а конкретнее — тесты на кодирование и декодирование видео. Я решил остановиться на тестах EncodeDecodeTest, MediaCodecTest, DecoderTest и EncoderTest, так как они присутствуют на всех версиях Android начиная с 4.3. График количества строк кода в этих тестах выглядит так:
До версии 4.3 большинства из этих тестов просто не существовало, и значительный их прирост пришёлся на версии 5 и 7. Поэтому можно говорить о том, что до версии Android 4.3 Google никак не проверяла соответствие устройств своей спецификации по кодированию и декодированию видео, а в версии 5.0 значительно улучшила эту проверку.
Казалось бы, это указывает на то, что начиная с версии 5.0 с кодированием всё должно быть в порядке. Но, учитывая предыдущий мой опыт работы с декодированием потокового видео на Android, я был уверен, что это не так. Достаточно было посмотреть на количество топиков про кодирование в Google-группе discuss-webrtc.
Искать подводные камни нам помогали исходные файлы WebRTC, которые находятся в свободном доступе. Рассмотрим их подробнее.
Поддержка H.264 в WebRTC
Тут есть метод с говорящим названием isHardwareSupportedInCurrentSdkH264:
Как мы видим, поддержка аппаратного кодирования на Android реализована только для чипсетов Qualcomm и Exynos. Почему же в стандартной реализации WebRTC нет поддержки других чипсетов? Вероятнее всего, это связано с особенностями реализации аппаратных кодеков производителей. И выявить эти особенности часто можно только на продакшене, поскольку найти те или иные устройства не всегда представляется возможным.
Все описания кодеков на устройстве хранятся в файле media_codecs.xml. Вот, например, этот файл для Pixel XL и для HUAWEI P8 lite. При получении списка кодеков с помощью метода getCodecInfos() объекта MediaCodecList этот файл парсится — и возвращаются кодеки, хранящиеся в нём. Эта операция и правильность заполнения этого файла производителем покрываются в CTS тестом MediaCodecListTest, который также увеличился со 160 строк кода в Android 4.3 до 740 строк в Android 10.
В Badoo мы поменяли код метода isHardwareSupportedInCurrentSdkH264, отказавшись от «белого» списка кодеков и заменив его «чёрным» списком префиксов программных кодеков, которые перечислены в WebRTC:
Но нельзя просто так взять и реализовать поддержку всех кодеков, не обращая внимания на особенности производителей. Из названий топиков, посвящённых аппаратному кодированию на Android в группе discuss-webrtc, можно понять, что в этом случае у нас точно возникнут ошибки. В основном они появляются на этапе конфигурации кодека.
Параметры конфигурации кодека
Инициализация кодека для кодирования выглядит так:
В некоторых из этих параметров легко допустить ошибку, что вызовет исключение при конфигурации кодека и нарушит работу приложения. Также при работе с кодеком может понадобиться регулировать его битрейт в зависимости от различных факторов, так как сам кодек делает это неправильно. За это в WebRTC отвечает класс BaseBitrateAdjuster, у которого есть два наследника:
Разрешение потока
После получения для кодека объекта MediaCodecInfo можно изучить кодек подробнее, получив его возможности в классе CodecCapabilities. Из них можно узнать, поддерживает ли кодек выбранные разрешение и частоту кадров. Если он поддерживает эти параметры, их можно устанавливать безопасно.
Однако иногда это правило не работает. Мы столкнулись с тем, что кодеки с префиксом “OMX.MARVELL.” кодировали неправильно, показывая зелёные полосы по краям экрана, если разрешение потока отличалось от 4:3. При этом сам кодек утверждал, что выбранные разрешение и частота кадров поддерживаются.
Режим битрейта
Стандартный режим для всех видеокодеков — постоянный битрейт. Однако однажды нам пришлось использовать переменный битрейт:
Произошло это на устройстве Lenovo A1000 с чипсетом компании Spreadtrum (теперь Unisoc), начинающимся с префикса “OMX.sprd.”. Поиск в Интернете привёл нас к посту шестилетней давности о Firefox OS, описывающему эту проблему и способ её решения.
Цветовой формат
При использовании кодека в режиме байт-буферов необходимо выбрать правильный формат. Обычно это делается с помощью функции следующего вида:
Грубо говоря, всегда выбирается первый из поддерживаемых цветовых форматов.
Однако в случае с кодеками HUAWEI, начинающимися с префиксов «OMX.IMG.TOPAZ.», «OMX.hisi.» и «OMX.k3.», это не работало, и после долгих поисков мы нашли решение: вне зависимости от того, какой формат возвращают эти кодеки, необходимо использовать формат COLOR_FormatYUV420SemiPlanar. Разобраться в этом нам помог тред на одном китайском форуме.
Регулировка битрейта
Стандартный код WebRTC содержит следующее:
Как видно из этого кода, для всех чипсетов, кроме Exynos, регулировка битрейта выключена. Но это относится только к Qualcomm, так как в стандартном коде поддерживаются только Exynos и Qualcomm. Поэкспериментировав с различными значениями этой настройки, а также поискав в Интернете, мы выяснили, что для кодеков с префиксами «OMX.MTK.» её тоже нужно включить. Также необходимо сделать это для кодеков HUAWEI, начинающихся с префикса «OMX.IMG.TOPAZ.», «OMX.hisi.» или «OMX.k3.». Это связано с тем, что эти кодеки не используют временные метки кадров для регулировки битрейта, считая, что все кадры приходят с одинаковой частотой, установленной при конфигурации кодека.
В завершение приведу список кодеков, которые мы получили для устройств на Android 5.0 и 5.1. Они были нам интересны в первую очередь потому, что на более новых версиях Android ситуация улучшается и нестандартных кодеков становится всё меньше.
Это видно на графике ниже. Шкала логарифмическая, чтобы лучше показать редкие случаи.
Как мы видим, у большинства устройств были чипсеты Spreadtrum, MediaTek, HUAWEI и MARVELL — поэтому наши изменения помогли включить аппаратное кодирование на этих гаджетах.
Результат
Хотя мы и предполагали, что на некоторых устройствах при работе с H.264 будут возникать проблемы, Android опять смог нас удивить. Как мы видим из статистики пользователей Badoo, на руках у пользователей ещё достаточно много устройств 2014–2016 года выпуска, которые они не хотят или не могут обновлять. И хотя ситуация с выходом обновлений Android для новых устройств уже гораздо лучше, чем несколько лет назад, доля гаджетов предыдущего поколения сокращается довольно медленно и поддерживать их придётся ещё достаточно долго.
Сейчас WebRTC активно развивается Google из-за его использования в проекте Stadia (вот видео с подробностями на эту тему), поэтому он будет становиться всё лучше и лучше и, скорее всего, станет стандартом для реализации видеосвязи. Надеюсь, что эта статья поможет вам понять особенности работы с H.264 в WebRTC и использовать это в своих проектах.
Как включить технологию WebRTC в браузере
Если вы хотите проводить вебинары, видеоконференции или онлайн-встречи, то вам не обойтись без технологии WebRTC в вашем браузере. Ведь ее использует подавляющее большинство сервисов для вебинаров. Сегодня мы поделимся несколькими способами, как включить эту технологию, если по каким-то причинам она оказалась отключенной.
WebRTC — зачем он нужен?
WebRTC (Real Time Communication) — технология, которая передает аудио и видео между мобильными приложениями и браузерами. Если WebRTC отключен в вашем браузере, то он не сможет передать от вас звук и видео, то есть вы не сможете выступать на вебинаре или видеоконференции.
Обычно, эта технология включена по умолчанию и вам ничего не нужно делать, чтобы присоединиться к эфиру. Но бывают ситуации, когда администрация запрещает использовать WebRTC или в вашем браузере установлены специальные расширения, блокирующие технологию.
Далее мы покажем, как включить технологию WebRTC в популярных браузерах.
Как включить технологию WebRTC?
Google Chrome
Проверьте, установлен ли в Хроме плагины, блокирующие WebRTC. Например, это WebRTC Leak Prevent, WebRTC Control, Easy WebRTC Block, WebRTC Network Limiter и другие. Для этого в строке меню выберите Дополнительные инструменты, а затем перейдите во вкладку Расширения.
В списке найдите перечисленные программы. Деактивируйте их на время вебинара или удалите вовсе, если они вам больше не нужны.
Opera
В Opera WebRTC может быть отключен 2 способами: с помощью расширения или в настройках.
В первую очередь вам нужно найти расширения, которые отключают технологию WebRTC. Для этого в меню браузера выберите вкладку Вид и выпавшем списке кликните на Показать расширения.
В поиске найдите все расширения со словом WebRTC (WebRTC Leak Prevent, WebRTC Control, Easy WebRTC Block, WebRTC Network Limiter). Отключите или удалите их.
Чтобы включить WebRTC в настройках браузера, наведите на название Опера в левом верхнем углу и откройте Настройки.
Теперь в поиске введите WebRTC и поставьте галочку напротив первого пункта.
В некоторых случаях браузер Opera блокирует технологию WebRTC и для решения этой проблемы достаточно проверить вышеуказанные настройки WebRTC.
Яндекс.Браузер
Перейдите в меню и откройте Дополнения.
Найдите в списке WebRTC Control, Easy WebRTC Block, WebRTC Protect, WebRTC Leak Prevent или подобные плагины со словом WebRTC.
Отключите расширения на время вебинара или вовсе удалите.
Microsoft Edge
Откройте список ваших расширений.
Найдите среди них WebRTC Control или другое расширение со словом WebRTC. Отключите их на время или удалите.
Safari
Наведите мышкой на Safari в верхнем левом углу и выберите Настройки в раскрывающемся меню.
Перейдите во вкладку Дополнения и установите галочку напротив пункта Показывать меню Разработка в строке меню.
Теперь перейдите в меню Разработка и выберите пункт Экспериментальные функции.
Mozilla Firefox
В адресной строке введите набор символов about:config и нажмите enter. Система уведомит вас о том, что вносить изменения нужно с осторожностью. Нажмите на кнопку Принять риск и продолжить.
После этого в поисковой строке введите media.peerconnection.enabled
Нажмите на переключатель, так чтобы false поменялось на true.
Теперь WebRTC включен и вы можете выступать на вебинаре.
Что делать, если включить WebRTC не удалось?
Вы все попробовали, а активировать WebRTC не удалось? Так бывает. Иногда невозможно распознать, какой плагин блокирует эту технологию. Возможно, использование WebRTC заблокировано системным администратором.
Но провести вебинар вам все равно удастся. Для таких случаев у нас есть альтернативная технология. Это специальный плагин в вебинарной комнате, который нужно установить на компьютер. О том, как его загрузить, установить и использовать вы можете почитать здесь. Или свяжитесь с нашей службой поддержки.
5 ошибок при разработке WebRTC звонков из браузера
Почему у нас не получается с WebRTC?
Нет такой вещи, как новая идея. Это невозможно. Мы просто берем кучу старых идей и помещаем их в мысленный калейдоскоп. Вращаем его, и идеи создают новые занимательные комбинации. Продолжаем вращает и создавать новые комбинации бесконечно; но это все те же кусочки цветного стекла, которые мы использовали веками.
Это высказывание о корне многих детских ошибок с WebRTC. Технология такая же «новая», как узоры в калейдоскопе Марка Твена. Просто набор старых идей, замешанных в свежую, интересную комбинацию. Мы знаем это, и полагаем, что умеем работать с такими штуками.
Бизнесмены? Скайпу 14 лет. Это не должно быть очень сложно создать что-то наподобие скайпа в наши дни.
Разработчики VoIP? Мы знаем SIP. WebRTC похож на SIP без сигнализации. Так что мы прикрутим туда SIP и все готово.
Web разработчики? WebRTC является частью HTML5. Несколько строк JavaScript кода и почти готово для релиза.
Разработчики видеосервисов? Мы же можем просто взять WebRTC видеопоток и положить на CDN?
Выбора у нас, кстати, особо не осталось. Flash умирает, и другой серьезной альтернативы WebRTC нет. Если вы хотите использовать WebRTC в своих проектах, то вот пять типовых ошибок, которые лучше не совершать.
Ошибка №1: Неправильно настроенный STUN/TURN
Вы не поверите, насколько часто разработчикам не удается настроить сервера для обхода NAT. Вчера кто-то спросил через чат-виджет моего сайта как они могут развернуть свое приложение и сигнализацию с помощью HostGator без использования STUN/TURN серверов.
Простой ответ: никак. За исключением нескольких эзотерических случаев вам понадобятся STUN сервера. А для большинства практических применений еще и TURN сервера, если вы хотите, чтобы ваши сессии соединялись друг с другом. Только за предыдущий месяц я рассказывал о NAT traversal следующее:
Ошибка №2: Выбор неправильного фреймворка для сигнализации
PeerJS? Выглядит как типичная «ловушка для туриста»:
У проекта 1’693 звезды и 499 форков, это один из самых популярных репозиториев на github, относящихся к WebRTC. Что может пойти не так?
Возможно, то, что проект чуть менее старый, чем интернет?
Проект, относящийся к WebRTC, последний коммит в который сделан более трех лет назад, просто не может быть использован в 2018 году. То же относится к примерам кода от Muaz Khan — не стоит рассчитывать, что они коммерческого уровня, стабильны и масштабируемые. Нет. Просто полезные примеры кода.
Планируете использовать какой-нибудь другой open source проект? Убедитесь, что:
Ошибка №3: Не использовать медиа сервер когда это нужно
Я знаю, о чем думают разработчики, использующие WebRTC. Технология умеет peer-to-peer, поэтому сервера не нужны. Некоторые даже считают, что можно обойтись без сигнализации и веб серверов. Надеюсь, они могут при этом объяснить, как браузеры участников в таком случае найдут друг друга, чтобы совершить peer-to-peer звонок.
Для многих концепция peer-to-peer также означает, что можно создавать сессии с большим количеством участников без серверов для передачи медиаданных. У меня даже есть два примера такой «архитектуры»:
Сферический меш в вакууме. Круто. Но не думайте, что получится заставить такую штуку работать как надо в этом или следующем году. Двигаемся дальше:
Броадкаст в реальном времени с помощью форвардинга. Такое можно сделать, но результат будет далек от ожидаемой масштабируемости на миллионы участников с нулевой задержкой.
На практике нам нужны медиа сервера для передачи медиа данных: голоса и видео. Теперь, когда вы об этом знаете, можно поискать open source или коммерческое решение.
Ошибка №4: Тактика без стратегии
Вы нашли хорошего аутсорсера, скормили ему требования к продукту, заплатили и получили на выходе работающее решение. Все проблемы позади?
Сама технология WebRTC еще очень молода. Официальная спецификация меняется. Ее имплементация в браузерах меняется. Все это находится в постоянном движении. Если вы хотите использовать WebRTC, то я рекомендую вам остановиться на одном из двух вариантов:
Ошибка №5: Непонимание как работает WebRTC
Они говорят, что допущение — это причина всех ошибок. Гугл с этим вроде бы согласен. Вроде бы.
WebRTC не самая тривиальная технология, расположенная где-то на пересечении VoIP и веба. Она новая, и по ней не так много информации. А та, что есть, меняется очень часто (вывод: большая часть этой информации уже успела устареть).
Если вы собираетесь использовать WebRTC, то убедитесь, что понимаете технологию и область ее применения. Какие требуется развернуть сервера. Как WebRTC взаимодействует с сигнализацией (signaling — обмен данными между браузерами или другими WebRTC устройствами чтобы понять кто где в сети находится и какие медиа данные куда надо передавать). Как обрабатываются и передаются по сети медиа данные: голос, видео и «пользовательские». Какие есть готовые решения для работы с WebRTC.
Много разных штук для изучения. Не полагайтесь на свои знания Web, VoIP или видео-технологий. WebRTC сможет вас удивить.
WebRTC не может подключиться к кому-то в разных сетях
Итак, у меня небольшая проблема с webRTC.
Мне удалось успешно установить браузер видеосвязи в браузере на одном компьютере и на другой компьютер в той же сети с помощью firefox в ночное время, но у меня проблема. Если я попытаюсь подключиться к тому, кто находится в другой сети.
Я считаю, что это проблема с Ice-серверами: это то, что я до сих пор
Любой может помочь?
Кстати, у него также есть проблема при запуске на хроме, он просто случайно не показывает видео (добавляется добавочный поток, но ничего не происходит).
Вы можете проверить исходный код (уродливый) по адресу: http://bndr.me/chat/
(человек без запроса является вызывающим, человек с querystring является вызываемым)
Да, я также обнаружил, что это проблема. Фактически, я нашел, что это комбинация многих элементов, но сеть большая. Я уверен, что другие обнаружат, что это тоже проблема, и ее необходимо будет устранить, прежде чем большинство коммерческих приложений будут выпущены. Я думаю, что большинство из них не понимают проблему, поскольку они тестируют на одном ПК или, возможно, в локальной сети, и они просто не видят проблемы. Все мои тесты были в Chrome. Вот некоторые детали, которые я нашел:
Элементы, которые могут повлиять на то, насколько хорошо соединяются две (или более) конечные точки.
1. Сеть. Я упоминаю, что это большой. У меня две сети. AT & T и кабель Comcast. AT & T работает хорошо, а Comcast – плохо. Ниже я расскажу о некоторых примерах.
2. Какое устройство подключается в первую очередь к различным сетям, типам ПК и т.д.
3. Тип используемого ПК. Windows XP работает лучше, чем Windows 7. Лучший из них – Ubuntu. На самом деле у меня не было никаких проблем, пока один из концов Ubuntu.
4. Расстояние. Как правило, чем ближе, тем легче подключаться. Это имеет смысл. Более конкретно, если вы находитесь на одном ПК или в той же локальной сети, у меня не было никаких проблем. Если я тестирую одну из своих сетей на другую (соединение выходит на локальную WAN, а затем обратно в другой маршрутизатор/сеть. У меня могут быть некоторые проблемы. Если я тестирую по всему миру, то у меня может быть больше проблем. часто проверяют между Южной Флоридой в США и Индией. Это проблема.
Теперь позвольте мне подробнее остановиться на некоторых особенностях. Во-первых, позвольте мне подробно остановиться на проблеме Индии и некоторых особенностях. Если я использую Comcast на конце Флориды, а конец Индии использует свою сеть, я могу подключиться некоторое время, пока я подключаюсь первым, и они соединяются вторым. Если я переключусь на ATT, большую часть времени он будет подключаться в любом случае. Если Индия использует ПК Ubuntu, мы всегда можем подключиться независимо от того, что мой компьютер или какую сеть я использую. Очень странно. Все наши испытания находятся в Chrome и используют расположение сервера Google STUN.
Вот очень специфический тест, который я использовал на ПК с Windows 7 (фактически два из них, хотя результаты были идентичными) и сети Comcast и ATT. Сначала я начал с подключения Windows 7 и Comcast; затем XP и ATT. Нет проблем. Повторяется и снова нет проблем. Затем я сделал это в обратном порядке – начиная с XP и ATT, а затем подключая Windows 7 (Comcast). Не соединился бы. Я сделал обновление в Windows 7. Не лучше. Повторные. Нет соединения. Затем я пошел в XP и попытался обновиться. Подключено прямо вверх. Я выполнил эту же точную последовательность еще два раза с тем же результатом. По крайней мере, это было непротиворечиво.
Затем я отменил сетевые подключения на двух компьютерах. Я получил тот же результат, но просто изменил ситуацию. То есть, если ПК, который имел соединение ATT, был вторым, чтобы подключиться, он работал и работал последовательно каждый раз. Если Comcast был вторым соединением, он никогда не подключался.
Мой вывод: сеть Comcast или, возможно, маршрутизатор, с которым я работал, не позволяли подключиться. Я проверил все без успеха. Затем я использовал ПК Ubuntu. Проблема сети внезапно решена. Это не проблема сети.
Это настоящая проблема, и ее необходимо устранить до того, как будет выпущена коммерческая разработка. Проблема, похоже, связана с рядом вещей, которые я не понимаю. Любая помощь приветствуется.
Фред Кларк
Bjoern, я использовал приложение appspot с аналогичными результатами. Я использовал три или четыре разных компьютера из этого места и несколько из Индии. Если вы хотите протестировать сервер, который я обычно использую, вы можете перейти на www.connectuscom.com/wordpress/. В правой части страницы находится столбец демо-приложений. Это первый в списке. Фред
Еще один элемент, который я должен был включить в начале. Я не уверен, что это проблема соединения, но, возможно, что-то после подключения. Мы воспроизводим звуковое оповещение, когда удаленная сторона присоединяется к конференции. Это предупреждение играет ли мы получить связь или нет (позвольте мне сказать, что это было раньше). Мы внесли некоторые изменения в наш код, и теперь это не так. Мы также фиксируем диагностику. Я собирался показать это и отправить диагностику, но я вижу, что она больше не делает этого. В любом случае, я покажу вам диагностику. Прежде чем я это сделаю, вы упомянули тестирование на AppSpot. Я упомянул, что я сделал это с такими же результатами. Я также тестирую вчера на Bistri.com с теми же результатами.
В этом тесте используются два компьютера под управлением Windows 7, которые связаны друг с другом, но подключены к двум различным сетям. Я начал работу с сетью ATT, а затем подключил сеть Comcast. Нет соединения. Затем я сделал обновление с компьютера ATT и подключился в первый раз. Это последовательный результат. Я не собираюсь отображать диагностику с ПК Comcast.