(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; m[i].l=1*new Date(); for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) (window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); ym(93807279, "init", { defer: true, clickmap:true, trackLinks:true, accurateTrackBounce:true }); ym(93807279, 'hit', window.location.href);

Мы разработали корпоративную звонилку, но не выпустили её на рынок Статьи редакции

Привет, это небольшая история о том, как продуктовая команда vc.ru в свободное время занялась сторонним проектом, но переоценила свою экспертизу в разработке кросс-платформенных приложений и неправильно определила MVP. Наша очередь делиться неудачными кейсами.

Как родилась гипотеза

То, что стало повсеместным с появлением коронавируса — дистанционная коммуникация — для нас, как и для многих других ИТ-компаний, уже давно является обыденностью. 80% коллектива распределены по России и СНГ, то есть вся работа строится виртуально: Slack, Jira, корпоративный портал (на платформе, на которой мы запускаем медиа) и звонилки. Нас устраивали все инструменты, кроме тех, в которых мы проводили голосовые совещания.

Два года назад, когда о пандемии ещё даже не шло речи и рынок не был завален большим количеством разнообразных звонилок, мы стали искать для себя удобный инструмент нетекстовой коммуникации. Zoom никому в команде не нравился по самым разным причинам, а встроенные звонки в Slack, который мы используем как мессенджер, сильно тормозили. Чаще всего мы созванивались через лаконичную веб-версию Whereby.

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

В большинстве случаев мы общаемся с одними и теми же людьми на одни и те же темы.

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

Таким образом, например, бэкенд-разработчики будут находиться на связи, как по рации. Именно они собрали себе прототип на NodeJS, назвали его Heyka («приветик» по-польски):

Прототип всем понравился

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

Всё это навело на мысль попробовать обличить его в нормальный интерфейс и раздать на тестирование нескольким командам. Мы наняли и выделили в отдельную команду троих разработчиков.

Как устроена Heyka

Взаимодействие с Heyka начинается с экрана логина. Мы задумывали его как расширение для корпоративных систем вроде Slack, MS Teams и прочих. Авторизация через них позволяет быстро пригласить коллег и даже продублировать каналы или чаты:

В уже рабочем виде компактное (это было для нас важно) приложение по своей структуре напоминает привычные, но уменьшенные в размере, инструменты коммуникации: Slack, Telegram, Discord. Слева находятся публичные и приватные каналы, список коллег для индивидуальной коммуникации:

Пользователь выбирает канал, видит список участников и заходит в него через кнопку Connect. Для приглашения внешних гостей есть возможность сгенерировать временную ссылку для входа через веб-версию:

После входа в канал, если активируется другое окно в системе, Heyka сворачивается до маленькой плашки с основными элементами управления:

Конечно, звонок можно быстро развернуть:

Например, чтобы посмотреть чей-то шеринг экрана.

Хотя смотреть можно и фоном, в компактном режиме. Видео переключается на того, кто говорит:

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

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

Конечно, никакая коммуникация невозможна без мобильных приложений.

Где начались ошибки

Начались они на стандартной и распространённой для неопытных команд развилке: выпустить продукт с минимальной функциональностью — каналы и голосовое общение — или допилить «ещё немного фишек, так ведь будет круче». Мы не успели заметить, как стали больше думать, что мы делаем, а не зачем. А видео? А шеринг экрана? А рисование? А приватные каналы? А текстовый чат?

Менеджерские ошибки повлекли за собой в том числе проблемы в коде. Мы традиционно являлись веб-разработчиками — это наша специализация. Поэтому не очень ясно, о чем мы думали, когда говорили друг другу «Heyka будет работать на всех платформах: Mac, Windows, iOS, Android, Web, Linux». Нам достаточно было сделать веб и мобильные приложения.

В итоге эксперимент превратился в сложный долгострой, каждый шаг только усложнял его, и наступила пандемия, которая в буквальном смысле взорвала рынок. Голосовой коммуникацией занялись все, в итоге их сделал и сам Slack и, наконец-то, Telegram.

В конце концов, было наивно полагать, что без опыта в архитектуре, просто на готовой технологии WebRTC, мы сможем построить глобальный продукт. Хотя представленная функциональность уже работает.

Что будет дальше

О самом эксперименте, конечно, не жалеем — было интересно, многому по ходу дела научились. Эксперименты проводить полезно, но ещё полезнее — вовремя их останавливать. Мы в этом году привлекли небольшие инвестиции, поэтому хотим сейчас сфокусироваться на развитии нашей основной платформы, а уже потом, с учётом ошибок, вернуться к теме корпоративной коммуникации, которая нам очень интересна. Пока что продолжаем пользоваться Heyka внутри компании — наши нужды она покрывает.

Для продукта сейчас видим несколько сценариев

  1. Продажа тем, кто умеет и хочет делать такие продукты.
  2. Поиск технических партнёров, с которыми мы сможем продолжить в качестве продуктовых менторов.
  3. Если ни то, ни другое не случится до нового года, то мы просто опубликуем на ProductHunt её исходный код — вдруг кому-то пригодятся наши наработки.

Какие технологии использовали

  • Фронтенд: Electron, Vue, Vuex, Stylus
  • Бэкенд: NodeJS, Hapi, Postgres, Redis
  • WebRTC: Janus (в этой части мы, похоже, с выбором ошиблись)

У невыпущенного продукта есть сайт, который мы не доделали — heyka.app. Писать письма и вопросы можно на [email protected].

0
160 комментариев
Написать комментарий...
Anton Kuzmichev

А что не так с выбором Janus? Конкретно он или весь стек SFU решений не оправдывают ожиданий?)

Ответить
Развернуть ветку
Michael Nalbandyan

Тут мы почему-то еще с первого MVP решили выбрать AudioBridgePlugin (MCU). Идея казалась классной. Всего два соединения на клиент вне зависимости от кол-ва участников. Следующим слоем наложили VideoRoom, и видео потоки пошли по SFU.

С течением времени начали задумываться о качестве звука. В принципе, качество звука было лучше чем в Слаке на порядок, но когда два и более человек одновременно начинают говорить (понятно что это абсурд, но все равно такое часто случается) в аудио потоке появляются артефакты (громкие трески), довольно не приятные, особенно если сидишь в наушниках. Долго дебажили в чем проблема, и оказалось дело в алгоритме софтверного микшера, и Lorenzo в каком-то треде писал, что тут ничего не поделать, они выбрали оптимальный алгоритм по трудозатратности/качеству.

Стали думать, что нужно перевести Audio в тот же VideoRoom и потестить как оно будет. Параллельно мы оптимизировали код, чтобы шаринг видео не отжирал много ресурсов. И заметили такую штуку, что тот же Google Meat использует один PeerConnection для нескольких потоков. Janus при этом на каждый видео поток создает отдельный PeerConnection, что на ровном месте с каждым новом потоком создает нормальный такой оверхед в ~15% от ядра, даже если видео уже перестало стримится, а ты забыл задестроить его.

Про кривые доки, API и JS клиент вообще молчу.

Вообще mediasoup.org очень нравится с виду. В демке видео потоки так же, как в Google Meet группируются в одном PeerConnection'е.

Ответить
Развернуть ветку
Anton Kuzmichev

Вот да, тоже пришёл к выводу, что залог успеха, особенно для клиентской стороны - минимум PeerСonnection'ов при "любом" числе участников конфы. А это значит - либо дорогущий (по процууу) MCU, который всё равно ляжет на десятках участников, либо уже лютый кастом с соединениями и обработкой медиа (опорные кадры, вот это всё, кстати ВК недавно писал на хабре про свои свежие видеоконфы), который обычно не могут себе позволить не-FAANG'и. Причём там поле непаханное, и зачастую не только с серверном стороны, но и какие-нибудь WebAssembly для клиентов с соственной реализацией чего-нибудь из WebRTC.
А в 5-10 участников любой опенсорс смогёт, это да)

Ответить
Развернуть ветку
157 комментариев
Раскрывать всегда