Общее описание
Easy Planer Recorder — расширение для Chrome/Chromium (Manifest V3), предназначенное для записи аудио встреч на поддерживаемых платформах. Оно смешивает звук вкладки встречи и микрофон, кодирует аудио в PCM 16-bit little-endian mono и отправляет поток на WebSocket API сервера Easy Planer. На сервере собирается запись, в том числе сохраняется WAV в хранилище.
Установка для разработки
- Откройте
chrome://extensions(илиbrowser://extensionsв Яндекс.Браузере). - Включите режим разработчика.
- Нажмите «Загрузить распакованное» и выберите папку
apps/extension-recorderиз репозитория. - После изменения кода нажмите «Обновить» у карточки расширения.
- При ошибках вида «Extension context invalidated» перезагрузите вкладку встречи (F5).
Поддерживаемые платформы (Content Script)
Content-скрипт подключается автоматически на страницах, указанных в manifest.json → content_scripts → matches:
- Яндекс Телемост:
https://telemost.yandex.ru/*,https://*.telemost.yandex.ru/* - ВКС СИБУР (включая Телемост на доменах СИБУР):
https://sibur.ru/*,https://*.sibur.ru/* - Google Meet:
https://meet.google.com/* - Zoom в браузере:
https://zoom.us/*,https://*.zoom.us/* - Контур.Толк:
https://ktalk.ru/*,https://*.ktalk.ru/*
На других сайтах панель не встраивается, запись с них не предусмотрена.
Popup (иконка расширения)
Popup содержит только управление видимостью панели на текущей активной вкладке:
- Показать виджет — сохраняет настройку видимости, при необходимости внедряет
content_widget.jsи показывает панель. - Скрыть — прячет панель на этой вкладке (запись при этом не останавливается автоматически; остановите её кнопкой Stop в виджете, если нужно).
Открывайте popup, находясь на вкладке с встречей из таблицы выше.
Виджет на странице встречи
Панель реализована в Shadow DOM (стили изолированы от сайта), закреплена в углу экрана.
- Заголовок (не кнопки): перетаскивание; положение и режим «свёрнуто» сохраняются в
chrome.storage.local. - ▾ / ‣: свернуть / развернуть основной блок; блок Status / Meeting / Last остаётся видимым и в свёрнутом виде.
- Ссылка «Мои задачи» ведёт в веб-приложение (после входа подставляется slug воркспейса, если он известен).
Подключение к Easy Planer (продакшен)
В коде зафиксированы продакшен-эндпоинты (см. content_widget.js):
- Приложение:
https://go.easyplaner.ru - WebSocket записи:
wss://go.easyplaner.ru/recordings/ws
Поля URL приложения и WS URL в интерфейсе заполняются ими при загрузке; менять их вручную в обычном режиме не требуется.
Логин
Логин выполняется через GraphQL в service worker (без CORS со страницы встречи):
- Введите email и пароль от аккаунта Easy Planer → нажмите Войти.
- После успешного входа токен и при необходимости workspace сохраняются в
chrome.storage.local; форма входа скрывается, отображается строка «Вход: …».
Разрешённый хост приложения для логина и запросов воркспейса: только go.easyplaner.ru (HTTPS). В манифесте нет прав на произвольные сайты и нет localhost: виджет и API работают в рамках перечисленных в manifest.json origin встреч + портала Easy Planer.
Кнопка «Настройки подключения» показывает служебные поля (в т.ч. workspaceId); для типового сценария достаточно входа по email/паролю.
Запись: пошаговая инструкция
- Откройте встречу на одном из поддерживаемых сайтов.
- По иконке расширения нажмите Показать виджет (если панель не видна).
- В виджете выполните Войти (если ещё не входили в этом браузере).
- При необходимости измените Title (название встречи для записи) и sample rate (по умолчанию 16000 Гц;
AudioContextсоздаётся с этим значением). - Нажмите Start:
- Chrome может запросить доступ к аудио вкладки для origin встречи — разрешите.
- Иногда для
tabCaptureнужен «живой» контекст расширения: если в статусе подсказка про иконку расширения — откройте popup и нажмите Start ещё раз. - Микрофон запрашивается в offscreen-документе; при отказе появится кнопка открытия окна разрешения микрофона (
mic-grant.html).
- Stop — останавливает захват и сессию на сервере; после успешного завершения можно открыть запись по ссылке из виджета (если известны
meetingIdиslugворкспейса).
Запись выполняется в offscreen + service worker; вкладку встречи и popup можно не держать открытыми, но не закрывайте браузер до окончания записи.
Локальная разработка API
Чтобы ходить на локальный бэкенд, временно добавьте в свой клон:
- В
manifest.json→host_permissionsстроки:http://localhost/*,http://127.0.0.1/*,ws://localhost/*,ws://127.0.0.1/*. - В
service_worker.jsвернитеlocalhostи127.0.0.1вALLOWED_ORBIT_HOSTSи веткуhttp:вisAllowedOrbitOriginпо аналогии с прежней логикой.
В поставке по умолчанию этого нет, чтобы не расширять поверхность доступа расширения.
Технические заметки
- Разрешения: нет
tabsи нет глобального перечисления вкладок — используетсяactiveTab(доступ к текущей вкладке при открытии popup) плюсhost_permissionsтолько на домены встреч иhttps://go.easyplaner.ru/*. - Обновление списка записей в открытом портале делается через
chrome.tabs.query({ url: '<origin приложения>/*' }), безquery({}). - На сервер уходит PCM 16-bit little-endian, mono; частота дискретизации задаётся полем
sample rateв виджете (иAudioContext). - Состояние записи дублируется в
chrome.storage.local(orbitRecState), чтобы после сна service worker (MV3) виджет мог снова показать актуальный статус. - Для качества звука на встречах лучше использовать наушники, чтобы микрофон не подхватывал звук из колонок.