Наше десктоп-приложение записывает встречи без бота и передаёт их в облако. Месяцами движок записи был самой сложной для надёжности частью продукта. Мы исправляли один класс граничных случаев, выпускали обновление — и на следующей неделе всплывал новый. Другие первопричины, тот же шаблон. Движок работал в процессе рендеринга нашего Electron-приложения. Мы пробовали очевидные исправления: более строгое управление жизненным циклом, вынос работы из основного потока, изоляцию от цикла рендеринга React. Каждое изменение давало лишь незначительное улучшение, но ни одно не решало настоящую проблему. Процесс рендеринга — неподходящее место для захвата аудио и видео в реальном времени. Движок захвата не может мириться с паузами GC, троттлингом и всем остальным, что делает браузерная среда, чтобы оставаться отзывчивой.
Поэтому мы перешли на нативные решения: Screen Capture Kit на macOS, libobs на Windows и общий слой на Swift, связывающий их. Мост между нативной средой и React обычно означает ручное написание биндингов нативных аддонов. А что, если каждое свойство @Published в Swift автоматически становилось бы Jotai-атомом в React? Именно это делает наш внутренний инструмент Atomic.
На macOS мы получаем сырые сэмпл-буферы из трёх независимых источников и собираем файл сами. На Windows захват, микширование, кодирование и мультиплексирование работают как единый граф. Мы используем Windows Graphics Capture (WGC) как основной метод, а если он не выдаёт кадры вовремя, переключаемся на Bit Blt. Мы также обнаруживаем полностью чёрные кадры и меняем метод прямо во время записи.
Сбой на 30-й минуте теряет максимум последнюю секунду. Сегменты одновременно отправляются в локальное хранилище и в облако. Если сеть пропадает, сегменты сохраняются локально, и загрузка автоматически возобновляется при восстановлении соединения. Запись с рабочего стола была одним из самых частых источников обращений в поддержку. Теперь это скучная часть приложения, которая просто работает.
Источник: Hacker News · Сводку подготовил HeadlinesBriefing