Как мы делаем онлайн‑конференции: доклад Николая Молчанова с DotNext
Какие разработки нужны, когда проводишь конференции для самих разработчиков?
Фото: DotNext
Николай Молчанов
Руководитель разработки JUG Ru Group. Ранее работал в «Альфа-Банке» и телекоммуникационной компании LaNetroZed. Фулстэк-разработчик на .NET и JavaScript. Ментейнер проекта Flurl. Придерживается принципов разработки TDD и BDD.
Компания JUG Ru Group проводит конференции уже девять лет: сначала в офлайне, потом, из-за пандемии, в онлайне, а теперь совмещает оба формата. Их организаторы не только дают программистам площадку для выступлений, но и сами пишут код.
На конференции DotNext руководитель разработки Николай Молчанов рассказал о том, как у них всё устроено:
- какие этапы проходит доклад от заявки до трансляции на портале;
- какие части системы за что отвечают;
- на каких технологиях они описаны;
- как всё вместе работает.
Что происходит до трансляции
Три года назад, когда я пришёл в компанию, я думал, что в организации конференций нет ничего сложного — берёшь Microsoft Excel, указываешь там доклады и проводишь:
На самом деле всё куда сложнее. Вот схема, которая упрощённо описывает процесс создания конференции:
Мы кратко поговорим о блоках, которые соединяются, чтобы доклад стал трансляцией или выступлением в офлайне.
Вот как выглядит весь процесс:
- спикер подаёт заявку;
- она попадает в специальную SRM‑систему (Speaker Relationship Management);
- её оценивает программный комитет конференции;
- спикер тренируется;
- описание доклада попадает на сайт конференции;
- из докладов формируется программа конференции;
- спикер выступает с докладом.
Рассмотрим все этапы поочерёдно.
Call for papers: как происходит регистрация на конференции и подача заявки
Раньше на сайте каждой нашей конференции был свой CFP (call for papers, приём заявок). Теперь мы стараемся унифицировать интерфейсы, чтобы у всех был единый опыт. Подача заявки выглядит так:
Так как мы поддерживаем систему авторизации SSO (single sign‑on), то часть полей можем заполнить за спикера.
После подачи заявка попадает в систему SRM. Там у спикера есть личный кабинет (ЛК), где он видит все свои текущие и прошлые заявки. Это выглядит так (на моём примере):
В феврале мы столкнулись с вынужденным импортозамещением: пришлось мигрировать с CMS Contentful на внутреннюю систему. Мы импортировали туда контент по 145 конференциям, 3605 активностям и 2207 участникам.
Личный кабинет спикера — это ERP‑система, где он может править свою биографию, описания докладов, подгружать презентации, менять фото. Программный комитет конференции, координаторы и редакторы также могут корректировать эту информацию и публиковать её на сайте.
Для наших «онлайново-офлайновых» времён очень важны формат выступления (офлайн, онлайн удалённо или из нашей студии), поездки, локации для эфирной команды и прочее.
Если спикер обновляет свою биографию, правки вносятся только на сайтах конференции текущего сезона, а на сайтах прошедших сезонов остаётся соответствующая им версия (их можно править отдельно).
Как организована публикация доклада
После того как спикер внёс информацию, редактор проверяет данные по заявкам и спикерам и публикует доклады на сайте.
На изображении выше видно, что у записей есть статус: «Ожидает ревью» или «Опубликован». После редактирования доклад попадает на сайт.
Ниже представлена схема публикации:
Спикер создаёт биографию в SRM (или использует готовую, если ранее уже выступал у нас). Команда проверяет и редактирует её. При помощи специального фасадного сервиса Core API, который объединяет все наши сервисы и бэкенды под одним API, контент публикуется в виде блоков.
Теперь о наших конференционных сайтах. У нас есть целый ряд конференций, и у каждой — свой сайт со всей информацией о ней. А ещё есть единый сайт live.jugru.org («Лайв»), на котором проходят все онлайн-трансляции.
Раньше эти сайты жили собственной жизнью: создавались в разное время, разными людьми, совершенно на разных технологиях. Их правка, а тем более внесение изменений в одинаковые блоки либо добавление одинакового логотипа на все сайты были большой болью.
Мы ушли от этого и сделали conference site engine:
Это единый движок для наших сайтов, своеобразный монорепозиторий, собранный на Next.js, с кэшем на Node.js. Все конференционные сайты занимают 42 контейнера на среду. Так мы поддерживаем их все одновременно.
Вот схема сборки сайта для конференции JUG Ru Group:
Есть Core API как фасадная система. При помощи специальных build jobs код из Git‑репозитория соединяется с кэшем, и собирается определённый инстанс. После этого он публикуется в трёх средах. Внесение изменений в кодовую базу порождает изменения на всех сайтах одновременно.
Именно поэтому все сайты выглядят примерно одинаково: есть стандартная авторизация и однотипные блоки. При условии готовности маркетинговых материалов мы можем выгрузить сайт новой конференции за полдня.
Мы придерживаемся следующих принципов:
- единство терминологии;
- единый опыт участников конференции и команды;
- SSO на всех сайтах;
- похожая визуализация однотипных блоков;
- доступ участников к трансляции в два действия.
Интерфейсы наших сайтов очень похожи. Везде поддерживаются светлая и тёмная темы и однотипные блоки. Карточки докладов тоже выглядят одинаково на сайте конференции и на «Лайве»:
Чтобы карточки появились на сайтах, нужно сформировать расписание. Чаще всего это делают с помощью редактора:
Он формирует программу по трекам простым перетаскиванием. Этим инструментом пользуются координатор и программный комитет. Здесь довольно много метаинформации для редактирования сущностей, проставления тегов, сложности, языка активности и так далее. Также здесь можно прописать спикеров и зал, в котором пройдёт конференция.
Трансляция: что под капотом
Итак, программа опубликована — пора проводить конференцию. Давайте подключим спикеров. Они присоединяются на время доклада через Speaker Room — наш собственный инструмент для подключения спикеров. Это WebRTC‑решение, в прошлом работавшее на основе решения Voximplant, а теперь — на движке «VK Звонков». Оно позволяет демонстрировать экран с презентацией и подключать экран удалённых спикеров.
У нас есть студии в Санкт‑Петербурге. При желании участник может прийти в студию и выйти оттуда в эфир:
Как соединить всё в одном видео
Есть ПТС — передвижные телевизионные станции, которые монтируют видео и отгружают его в транскодер. Видео воспроизводится в плеере — мы написали его сами поверх HLS.js.
Сверху на схеме — Speaker Room, где подключаются удалённые спикеры. Внизу — студии, куда приходят участники. Видео через WebRTC или сырой видеосигнал поступает в ПТС, там монтируется и проходит дальше по пайплайну. ПТС представляют собой большие комнаты с кучей компьютеров с мощными видеокартами, там и происходит рендеринг и монтаж видео.
Как видео попадает в ПТС
Студия может дать изображение из эфира или изображение продюсера эфира. ПТС при помощи специального веб-клиента подключаются к тому же самому Speaker Room через специальные receive-only-клиенты, которые не показывают видео, а только забирают его. После этого видео попадает в ПТС, при помощи которого можно переключать шаблоны веб-страниц и что-то добавлять в видео. Можно также настраивать звук, микшировать его и устранять огрехи.
После того как видео обработано в ПТС, сжато и готово к продакшену, оно отправляется через протокол SRT в сервисе Amazon MediaConnect.
В Amazon видео транскодируется в 4K-разрешение. Затем пакуется в контейнер HLS и отправляется сначала в S3, а затем в CloudFront для распространения по всему миру — чтобы участники быстро получали доступ к видео в любой точке планеты. С помощью стрим-сервиса и «Лайва» клиентский плеер получает специальные плейлисты, которые генерируются на лету, чтобы клиентская часть знала, какой чанк нужно подгружать.
Когда пользователь пытается скачать видео, в игру вступают HTTP Cookies. В них мы заранее записываем подписанный объект, содержащий информацию о правах доступа пользователя. Благодаря подписи, на CloudFront можно проверить права и авторизовать доступ к конкретному контенту.
Если пользователь сменил конференцию или права на билет были изменены, то он будет приходить на CloudFront с новым значением Cookie.
Плеер общается с бэкендом — Java-сервисом на основе Hazelcast. Каждые пять секунд плеер отправляет информацию о том, какой пользователь какой кусочек видео смотрит в определённый момент. Это нужно для статистики, аналитики, графиков просмотра и прочей информации, собираемой в реальном времени. Таким образом бэкенд пересчитывает количество пользователей на докладах, статистику по пользователям, оценки доклада и дискуссии.
Раньше у нас был один большой стрим, разбитый на несколько участков: «Доклад 1», «Доклад 2» и так далее. Всё было привязано к конкретному времени. С этого лета все доклады «плавающие» — нет жёсткого расписания, согласно которому доклад должен закончиться в определённое время, чтобы уступить место следующему. То же самое с дискуссиями — были случаи, когда они продолжались по четыре часа.
Как мы управляем эфиром
У эфирной команды есть свой инструмент с управляющими элементами, которые позволяют остановить доклад, выключить его и так далее. Данные из онлайн‑бэкенда попадают в аналитическое хранилище, где много данных из разных систем соединяются и при помощи джобов материализуются во много разных представлений. Они помогают нам составить статистическую картину.
Теперь мы можем увидеть на графиках количество посещений каждой конференции, узнать, какие оценки зрители поставили докладам и какие из них добавили в избранное. Можно отправить фидбэк спикерам и сделать наши следующие конференции и доклады интереснее.
Как устроена авторизация и что такое SSO
Авторизация в JUG Ru Group работает по принципу single sign-on. Это значит, что пользователю достаточно зайти в одну из наших систем, чтобы авторизоваться во всех остальных.
Есть два личных кабинета: кабинет, где пользователь получает билет и авторизуется на сервере, и кабинет для хранения коротких кодов доступа к видео. Мы ещё не использовали их в продакшене, но планируем в будущем, чтобы упростить пользователю доступ и авторизовывать по одной ссылке.
В центре — фронтенд-бэкенд-сервис, который соединяет авторизацию OIDC (OpenID Connect) и личный кабинет со всеми сайтами конференций, Speaker Room, SRM, внутренними инструментами и «Лайвом». Пользователь может авторизоваться через сервисы Google, «Яндекса» или Apple, если ему неудобно авторизоваться с помощью почты.
У нас был выбор: делать собственный инструмент или использовать готовые сервисы вроде Okta или OAuth. Мы решили сделать своё. И не прогадали: в апреле 2022 года оба сервиса перестали работать в России.
Какие технологии используют в JUG Ru Group
Мы многопрофильная компания, поэтому используем много всего.
«Лайв» и личный кабинет написаны на Java, а сервисы вокруг них содержат компоненты на .NET. Те же сервисы, что поближе к Speaker Room, написаны на Node.js.
Для хранения данных во фронтенде используем MobX, а от Redux по разным причинам отказались. В веб-сокетах применяем Socket.IO. И в DevOps всё достаточно обычно. С облаками работали практически со всеми, с лета 2020 года — в основном с Yandex Cloud.
Этой весной мы опробовали режим, когда первые дни конференции проходят в онлайне, а в последний участники могут собраться вместе на офлайновой площадке. Так что теперь мы сочетаем и описанную выше онлайн-специфику (чтобы у всех всё хорошо запускалось в видеоплеере), и офлайновую (чтобы с реальной физической сцены для зрителей в зале всё тоже хорошо звучало).
Осенью планируем снова провести подобное, но уже с другим набором конференций — полный календарь можно будет увидеть на jugru.org.