От Skype до WebRTC: как мы организовали видеосвязь через веб


    Видеосвязь — основной способ общения преподавателя и студента на платформе Vimbox. Мы давно отказались от Skype, перепробовали несколько сторонних решений и в итоге остановились на связке WebRTC — Janus-gateway. Некоторое время нас все устраивало, но все же некоторые негативные моменты продолжали вылезать. В итоге было создано отдельное направление по видео.


    Я попросил Кирилла Рогового, руководителя нового направления, рассказать об эволюции видеосвязи в Skyeng, обнаруженных проблемах, решениях и костылях, которые мы в итоге применяли. Надеемся, статья будет полезна для компаний, также поднимающих своими силами видео через веб-приложение.


    Немного истории


    Летом 2017 года глава разработки Skyeng Сергей Сафонов выступил на Backend Conf с рассказом про то, как мы «отказались от Skype и внедрили WebRTC». Желающие могут посмотреть запись выступления по ссылке (~45 мин), а здесь я кратко изложу его суть.


    Для школы Skyeng видеосвязь всегда была приоритетным способом общения учитель-ученик. Поначалу использовался «Скайп», но он категорически не устраивал по целому ряду причин, в первую очередь из-за отсутствия логов и невозможности интеграции непосредственно в веб-приложение. Поэтому мы проводили всякие эксперименты.


    Собственно, требования к видеосвязи у нас были примерно такие:
    — стабильность;
    — низкая цена за урок;
    — запись уроков;
    — отслеживание, кто сколько говорит (нам важно, чтобы ученики говорили на уроках больше преподавателя);
    — линейное масштабирование;
    — возможность использовать и UDP, и TCP.


    Первым в 2013-м попробовали внедрить Tokbox. Все было хорошо, но получалось очень дорого – 113 рублей за урок – и съедало прибыль.


    Затем в 2015-м интегрировали Voximplant. Здесь была необходимая нам функция отслеживания, кто сколько говорит, и при этом решение было значительно дешевле: при условии записи только звука выходило 20 руб за урок. Однако работало оно только через UDP, переключаться на TCP не умело. Тем не менее, в итоге около 40% учеников им пользовались.


    Через год у нас начали появляться корпоративные клиенты со своими специфическими требованиями. Например, все должно работать через браузер, в компании открыты только http и https; т. е. никаких «Скайпов» и UDP. Корпоративные клиенты = деньги, поэтому вернулись к Tokbox, но проблема цены никуда не делась.


    Решение — WebRTC и Janus


    Приняли решение использовать браузерную платформу для peer-to-peer видеосвязи WebRTC. Она отвечает за установку соединения, кодирование и декодирование потоков, синхронизацию дорожек и контроль качества с обработкой сетевых глюков. Со своей стороны мы должны обеспечить считывание потоков с камеры и микрофона, отрисовку видео, управление соединением, установку WebRTC-подключения и передачу ему потоков, а также передачу сигнальных сообщений между клиентами для установки соединения (сам WebRTC описывает только формат данных, но не механизм их передачи). В случае, если клиенты находятся за NAT, WebRTC подключает STUN-серверы, если это не помогает, TURN-серверы.


    Обычного p2p соединения нам недостаточно, ведь мы хотим записывать уроки для дальнейшего анализа в случае жалоб. Поэтому мы отправляем потоки WebRTC через ретранслятор Janus Gateway от Meetecho. В результате клиенты не знают адресов друг друга, видя только адрес сервера Janus; он же выполняет и функции сигнального сервера. Janus обладает множеством нужных нам фич: автоматически переходит в TCP, если у клиента заблокирован UDP; умеет записывать потоки и UDP, и TCP; масштабируется; есть даже встроенный плагин для эхо-тестов. В случае необходимости автоматически подключаются STUN и TURN серверы от Twilio.


    Летом 2017-го года у нас работало два сервера Janus плюс дополнительный сервер для обработки записанных сырых файлов аудио и видео, чтобы не занимать процессоры основных. При подключении серверы Janus выбирались по принципу чет-нечет (номер соединения). На тот момент этого хватало, по нашим ощущениям давало примерно четырехкратный запас прочности, процент внедрения составил около 80. При этом цена сократилась до ~2 рублей за урок, плюс разработка и поддержка.



    Возвращение к теме видеосвязи


    Мы постоянно мониторим фидбек от учеников и преподавателей, чтобы вовремя выявлять и купировать проблемы. К лету 2018-го на первом месте среди жалоб уверенно закрепилось качество связи. С одной стороны, это значило, что мы успешно справились с иными недостатками. С другой, нужно было срочно что-то делать: при срыве урока мы рискуем потерять его стоимость, иногда вместе со стоимостью покупки следующего пакета, а при срыве вводного занятия – и вовсе потерять потенциального клиента.


    На тот момент видеосвязь у нас по-прежнему находилась в режиме MVP. Проще говоря, запустили, оно заработало, один раз масштабировали, поняли, как это делать – ну и славно. If it works, don’t fix it. Никто целенаправленно вопросом качества связи не занимался. К августу стало ясно, что дальше так продолжаться не может, и мы запустили отдельное направление, чтобы разобраться, что же все-таки у нас не так с WebRTC и Janus.


    На входе это направление получило: решение MVP, метрик нет, целей нет, процессов по улучшению нет, при этом 7% учителей жалуются на качество связи (данных по ученикам тоже не было).



    Новое направление берется за работу


    Команда выглядит примерно так:


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

    Для начала настроили относительно надежную метрику, которая отслеживала изменения оценки качества связи (среднее по дням, неделям, месяцам). На тот момент это были оценки от учителей, в дальнейшем к ним добавили оценки от студентов. Дальше стали строить гипотезы, что работает не так, исправлять и смотреть на изменения в динамике. Пошли по низковисящим фруктам: например, заменили кодек vp8 на vp9, показатели улучшились. Пробовали играться с настройками Janus, проводить прочие эксперименты – в большинстве случаев ни к чему не приводившие.


    На втором этапе появилась гипотеза: WebRTC – решение peer-to-peer, а мы используем сервер посередине. Быть может, проблема кроется здесь? Начали копать и нашли здесь пока наиболее значительное улучшение.


    В тот момент сервер из пула выбирался по довольно тупому алгоритму: у каждого был свой «вес», зависящий от канала и мощности, и мы старались отправить пользователя на тот, где «вес» больше, не обращая внимание на то, где географически находится пользователь. В результате учитель из Питера мог общаться с учеником из Сибири через Москву, а не через наш Janus-сервер в СПб.


    Алгоритм переделали: теперь, когда пользователь открывает нашу платформу, мы с помощью Ajax собираем пинги от него до всех серверов. При установке связи мы выбираем пару пингов (учитель-сервер и ученик-сервер) с наименьшей суммой. Меньше пинг – меньше сетевое расстояние до сервера; меньше расстояние — ниже вероятность потерять пакеты; потеря пакетов — самый большой отрицательный фактор в видеосвязи. Доля негатива за три месяца упала в два раза (справедливости ради, в это время проводились и другие эксперименты, но этот почти наверняка повлиял больше всего).




    Недавно мы обнаружили еще одну неочевидную, но, судя по всему, важную вещь: вместо одного мощного Janus-сервера на толстом канале лучше два попроще с пропускной способностью пожиже. Выяснилось это после того, как мы купили именно мощные машины в надежде запихнуть туда как можно больше комнат (сеансов связи) одновременно. У серверов есть лимит пропускной способности, который мы можем точно переводить в количество комнат — мы знаем, сколько можно открыть, например, на 300 мбит/с. Как только на сервере открыто слишком много комнат — мы перестаем выбирать его для новых занятий, пока нагрузка не снизится. Идея была в том, что, купив мощную машину, мы загрузим канал до него по максимуму, чтобы в итоге упираться в процессор и память, а не в пропускную способность. Но выяснилось, что после определенного количества открытых комнат (420), несмотря на то что загрузка процессора, памяти и диска еще очень далека от лимитов, в техподдержку начинает прилетать негатив. Судя по всему, что-то становится хуже внутри Janus, возможно, там тоже есть какие-то ограничения. Стали экспериментировать, снизили лимит пропускной способности с 300 до 200 мбит/с, проблемы ушли. Теперь купили сразу три новых сервера с невысокими лимитами и характеристиками, думаем, что это приведет к стабильному улучшению качества связи. Разбираться, в чем там было дело, мы, конечно, не стали, костыли — наше все. В свое оправдание скажем, что в тот момент надо было максимально быстро решить насущную проблему, а не сделать это красиво; к тому же Janus для нас — черный ящик, написанный на C, копаться с ним очень дорого.



    Ну и в процессе мы:


    • обновили все зависимости, которые можно было обновить, как на сервере, так и на клиенте (это тоже были эксперименты, следили за результатом);
    • починили все выявленные баги, касавшиеся конкретных случаев, например, когда связь падала и не восстанавливалась автоматически;
    • провели массу встреч с компаниями, работающими в области видеосвязи и знакомыми с нашими проблемами: стримящими игры, устраивающими вебинары; опробовали все, что нам показалось полезным;
    • провели техническое ревью железа и качества связи у учителей, от которых исходило больше всего жалоб.

    Проведенные эксперименты и последовавшие за ними изменения позволили снизить недовольство связью среди преподавателей с 7,1% в январе 2018 до 2,5% в январе 2019.


    Что дальше


    Стабилизация нашей платформы Vimbox — один из главных проектов компании на 2019 год. У нас большие надежды на то, что удастся сохранить динамику и больше не видеть видеосвязь в топе жалоб. Мы понимаем, что значительная часть этих жалоб связана с лагами компьютеров и интернета пользователей, но мы должны определить эту часть и решить все остальное. Все остальное — техническая проблема, кажется, мы должны уметь с ней справляться.


    Основная сложность в том, что мы не знаем, до какого уровня вообще реально повысить качество. Выяснение этого потолка – главная задача. Поэтому были запланированы два эксперимента:


    1. сравнить видео через Janus с обычным p2p в боевых условиях. Этот эксперимент уже проведен, никакой статистически значимой разницы между нашим решением и p2p не обнаружено;
    2. поставим (дорогие) сервисы от компаний, зарабатывающих исключительно на решениях в области видеосвязи, и сравним количество негатива от них с имеющимся.

    Эти два эксперимента позволят нам определить достижимую цель и сконцентрироваться на ней.


    Кроме того, есть ряд задач, решаемых в рабочем порядке:


    • создаем техническую метрику качества связи вместо субъективных отзывов;
    • делаем более подробные логи сессий, чтобы точнее анализировать случающиеся сбои, понимать, когда и где именно они произошли, какие на первый взгляд не связанные события имели место в этот момент;
    • готовим автоматический тест качества связи перед уроком, а также дадим возможность клиенту вручную протестировать связь, чтобы уменьшить количество негатива, вызванного его железом и каналом;
    • разработаем и будем проводить больше нагрузочных тестов видеосвязи в плохих условиях, с переменной потерей пакетов и т. д.;
    • меняем поведение серверов в случае проблем для повышения отказоустойчивости;
    • будем предупреждать пользователя, если у него что-то не так вообще со связью, как это делает тот же «Скайп», чтобы он понимал, что проблема на его стороне.

    С апреля направление видеосвязи становится полноценным отдельным проектом внутри Skyeng, занимающимся собственным продуктом, не просто частью Vimbox. А это значит, что мы начинаем искать людей на работу с видео в режиме фултайм. Ну и как всегда ищем много хороших людей.


    Ну и, конечно, продолжаем активно общаться с людьми и компаниями, работающими с видеосвязью. Если вы хотите обменяться с нами опытом — мы будем рады! Комментируйте, связывайтесь — ответим всем.

    Skyeng
    361,88
    Компания
    Поделиться публикацией

    Комментарии 13

      +1
      Спасибо, интересная статья! Еще очень интересен ваш доклад об использовании Janus www.youtube.com/watch?v=0BiE1Rt-bak.
      Доводилось сталкиваться с кодом Janus, не очень понравилось именно что он сделан в виде готового сервера, реализацию некоторых специфичных задач через его систему плагинов было не очень удобно колхозить. Но вещь, конечно, очень и очень достойная! Основным пожеланием было чтобы в нем был выделен код для работы webrtc в отдельную библиотеку и уже поверх нее реализация сервера и плагинов. Лично для меня, подобная библиотека была бы удобнее готового сервера типа Janus, Kurento, licode, easyrtc и похожих. Также где-то год назад в них не было поддержки нескольких треков в рамках одного подключения. Многие из них сделаны поверх libnice. Было бы классно собрать минимальные webrtc демки поверх libnice и оставить на память в виде статьи/заметки, как-то эта библиотека слабо представлена статьями и примерами. Кстати, еще есть реализация webrtc в составе библиотек gstreamer, пробовал использовать и ее.
      Также с самого начала проекта наблюдаю за реализацией webrtc на golang github.com/pions/webrtc Проект классный и активно развивается! Собирал pions для armv5, запускал на чипах hisilicon камер видеонаблюдения, заводилось и работало!) Сейчас уже можно работать с rtp и даже голыми h264 nal'ами. Надеюсь добавление/удаление треков в рантайме добавят в следующем релизе, как запланировано. Для онлайн школ, сервисов онлайн конференций возможно будет интересное решение. Немного расстраивает что это на golang, все же там GC и есть некоторый оверхед, а железко камер это 32-64 Мб оперативки на все про все + 8-16Мб spi флешки) Но это проблемы камер, на нормальном железе все отлично!
      В 2019 уже хочется иметь возможность через p2p webrtc смотреть потоки с камер в браузерах/мобильном софте… если кому-то интересна эта область, то оставлю контакты нашего проекта с открытой прошивкой для камер видеонаблюдения на базе openwrt openipc.org/contacts там есть активный телеграм чат, есть некоторые наработки, репозитории, очень рады будем видеть всех заинтересованных! Тематика webrtc не основная в чате, но все же тема важна и актуальна для камер…
        0
        Простому человеку в статье самое интересное — это альтернативы Скайпу. Я так понял, что всё сравнимое со Скайпом по пользовательским качествам (а уж лучшее, чем Скайп, и подавно) — платное. А фриварного нет?
        По слухам, есть ещё какой-то Скайп-Про для бизнеса. Он вроде платный, но я не понял — платный повремённо или это разовая оплата при покупке клиентского софта. В статье про него ни слова.
          0
          Мы особо не рассматривали альтернативы, которые нельзя встроить в платформу.

          Так-то есть Скайп, Hangouts (free), Hangouts Meet (paid), Zoom и все они хороши в плане качества. Про Скайп-Про ничего не слышал. :)

          На WebRTC есть масса решений, от платных Voximplant и Tokbox до бесплатных Janus, Kurento, Jitsi, licode. А если устраивает базовый p2p и нет групповых звонков, то все еще проще.
          +1
          А у вас за время работы обновления браузеров webrtc не ломало? ребята из trueconf часто к этой проблемы аппелируют…
            0
            Массово — нет. Иногда бывают проблемы со свежими версиями, особенно с Safari.

            Если речь про unified-plan и Chrome 72, то тут нас пронесло — SDK Janus-а был готов. :)
            0
            А можете чуть подробнее про Janus, Twilio и S3 рассказать?

            Правильно понимаю, что Janus выступает в качестве входной точки, дальше трафик идет через turn и параллельно заливается на s3?

            еще вопросик — смотрели в сторону coturn в качестве своего turn/stun сервера вместо Twilio?
              0
              Не знаю их схемы, но Janus это поддерживает, поэтому логично использовать его возможности.
              То-есть с turn и записью должно происходить примерно так:
              1. Json API запрос на Janus для входа участника или смотрящего.
              2. Создается новый ICE канал через libnice, работают turn сервера, что указаны в конфигурации, если напрямую клиента соединить нельзя.
              3. Janus получает пакеты от libnice и может залогировать потоки на диск в mjr формате. Утилитой janus-pp-rec можно потом перекодировать.

              Проблем с наличием реализации turn мне кажется нет, проблема что эти сервера надо где-то хостить и иметь хорошее географическое покрытие.
                0
                Janus — медиасервер в середине. Клиенты (браузеры) общаються только с ним, а он внутри пересылает пакеты партнеру.

                Так как Janus — это публичный сервер без NAT, доля использования TURN у нас в районе 1% (против 30%+ в p2p варианте), поэтому не заморачиваемся с оптимизацией TURN.

                Но опыт с coturn есть в рамках одного из экспериментов. Подняли быстро, сервер не падал — мы довольны. :)

                Записи звонков пишутся на диск (встроенная фича Janus), а дальше отдельный daemon перекладывает их на S3 в сыром формате. По запросу бизнеса, на отдельной машине выкачиваем нужные записи, конвертируем их в mp4 и заливаем на S3 для последующего просмотра живыми людьми.

                Сами Janus Gateway сервера хостим в Москве и Питере, т.к. это покрывают большую часть учеников.
                  0
                  В каких случаях используется TURN?
                    0
                    Использовать TURN или нет решает код WebRTC под капотом в браузере.

                    Могу ошибаться, но в нашем случае TURN используется только в случае злостных файрволов и NAT, из-за которых наш Janus сервер не может слать трафик клиенту.

                    Эта тема отлично раскрыта в докладе Александра Тоболя из Одноклассников — www.youtube.com/watch?v=MnEXuKHjIOU :)
                      0
                      Насколько я понял, клиенты всегда устанавливают соединение к вашему серверу. Зачем в таком случае TURN?
                      Или клиенты устанавливают соединение одновременно и между собой (p2p), и через ваш сервер, чтобы записывать данные?
                        0
                        Зачем в таком случае TURN?


                        В идеальном мире — незачем. Но в реальном находятся случаи, когда напрямую с сервером обмениваться данными не выходит.

                        Как я написал выше, это для сильно редкий случай и мы попросту не паримся. :)

                        Дополнительного p2p соединения между клиентами нет.
                0
                del

                Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                Самое читаемое