---
# System prepended metadata

title: Video — Tech review — VID-204

---

# Video — Tech review — VID-204

JIRA: https://devjira.skyeng.ru/browse/VID-204

## 1/4 — Блиц опрос про бизнес

- мне четко понятен Definition of done
- мне четко понятна корневая бизнес-задача
- мне четко понятно почему это важней, чем другие доступные задачи
- я согласен решать бизнес-задачу именно так

<!-- Удалить кого не было на ревью -->
Состав (галочка означает согласие со всеми утверждениями выше):
- [ ] Кирилл Роговой
- [ ] Илья Левин
- [ ] Антон Тейхриб
- [ ] Юрий Юрин

## 2/4 — Конечный результат

**Front end:**
1. Единый API для групповых звонков и 1-на-1
2. Поддержка simulcast и выбора получаемого качества
3. API для полного mute/unmute партнеров
4. Дополнительная информация в tech-summary

**Back end:**
1. У /get-video-config есть параметр, который отвечает за то, какой тип комнаты нужен
    - 1-на-1: максимум 2 участника, без simulcast, интеллектуальный выбор сервера, открыты все кодеки
    - групповой: много участников, simulcast, тупой выбор сервера, force vp8

**Записи:**
1. Конвертировать аудио по-умолчанию, совмещая все дорожки в один mp3
3. Видео пока не конвертируем, потому что сложно

## 3/4 — Шаги достижения

### Milestone 1 — video-backend

Добавить фичи групповой связи. Если group=1, то:
1. publishers должен быть не 2, а 10
2. единственный доступный кодек — vp8 (потому что есть у всех, а в группе договориться о лучшем кодеке — сложно)
3. включен simulcast
4. выбирается специальный сервер с флагом group=true
5. признак, что комната групповая должен сохраняться в БД

Использовать JanusGroupVideoConfigBuilder за основу.

### Milestone 1.1 — перевести фронт на использование серверного эндпоинта

Научить текущий клиент в group-video ходить на правильный серверный эндпоинт, не меняя остальную логику

### Milestone 2.1 — видео-либа на фронте

План:

_для выяснения точных отличий групповой либы от 1-на-1, диффнуть две папки_

- [x] Добавить групповые звонки в storybook используя текущий group-video, убедиться, что все ок
- [x] Добавить в IVideoClient и IVideoClientEvent все необходимые методы и события для поддержки групповых звонков. В конкретных имплементациях вставить "пустышки". Убедиться, что звонки 1-на-1 в storybook все еще работают.
    - У событий PartnerJoined, PartnerLeft, PartnerStreamAttached должны появиться поля publisherId
    - Руководствоваться диффом
- [x] Реализовать новые методы и события в clients/janus. Убедиться, что звонки 1-на-1 в storybook работают.
- [x] Добавить множественных партнеров в video-state
- [ ] Добавить поддержку групповых в SkyVideoService
    - partnerEvents и partnerState адаптировать под групповые звонки: e.g. `partnersState$: State<{ partnerId: number, state$: State<... тоже самое что сейчас partnerState ...> }>`
    - Перевести storybook со звонками 1-на-1 и убедиться, что они работают
- [ ] Перевести групповые звонки в storybook с group-video на video
    - Убедиться, что все работает как раньше
    - Дропнуть group-video
- [ ] Перевести групповые звонки в vimbox и убедиться, что все работает
- [ ] JanusClientBuilder?


### Milestone 2.2 — mute/unmute

Добавить возможность отписываться и подписываться заново на потоки клиентов в комнате. Должно прекращать получение от них медиа данных.

Дока: https://janus.conf.meetecho.com/docs/videoroom.html

1. Добавить в IVideoClient методы
    1. `unsubscribeFromPublisher(publisherId: number): void`
    2. `subscribeToPublisher(publisherId: number): void` — ведет к IVideoClientEventPartnerStreamAttached
3. Вставить пустышки в остальные клиенты
4. Добавить фичу в storybook для звонков 1-на-1

### Milestone 2.3 — simulcast (quality selector)

1. Добавить в IJanusVideoClientConfig параметр `simulcast` (false по-умолчанию). Если true и кодек — vp8, врубать simulcast
2. Добавить в IVideoClient метод `setReceivingQuality(publisherId: number, quality: 'high' | 'medium' | 'low')`. Если publisher не simulcast-ит, ничего не делать
3. Добавить фичу в storybook для звонков 1-на-1

### Milestone 2.4 — tech-summary

1. не трогаем tech-summary для звонков 1-на-1
2. для групповых делаем два события: tech-summary-sender, tech-summary-partner
    - в отдельном файле: libs/shared/video/src/webrtc-incident-monitor/tech-summary-split.ts
    - старый переименовываем на `tech-summary-singular.ts`
4. добавить в IJanusVideoClientConfig: `techSummaryType: 'singular' | 'split'` (не опциональный, нужно задавать явно)
5. добавить if в logVideoRoomEventsToServer — startCollectingSingularSummary или startCollectingSplitSummary в зависимости от techSummaryType
    - событие для split называем `tech-summary-sender` / `tech-summary-partner` и объект помещаем в `techSummarySender` / `techSummaryPartner` в теле лога
7. написать имплементацию для Split версии
8. протестить в storybook

**tech-summary-sender**

```typescript=
export interface IVideoCallSummarySender {
  type: 'sender'; // появляется тип
  userAgent: string;
  webrtcSupport: boolean;

  durationMs: number;
  durationM: number;
  localStreamReady: boolean;
  publishedSuccessfully: boolean;

  slowLinkCount: {
    toServer: number;
  };
  incidentCount: IIncidentCount;
  incidentDuration: IIncidentDuration;
  lastWebrtcReport?: IWebrtcReport;

  error?: Error;
}

```

**tech-summary-partner**

```typescript=
export interface IVideoCallSummaryPartner {
  type: 'partner';
  partnerId: number; // у partner есть id

  durationMs: number;
  durationM: number;
  remoteStreamReady: boolean;

  slowLinkCount: {
    fromServer: number;
  };
  incidentCount: IIncidentCount;
  incidentDuration: IIncidentDuration;
  lastWebrtcReport?: IWebrtcReport;

  error?: Error;
}

```

### Milestone 3 — конвертация аудио

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

## 4/4 — Блиц опрос про решение

- задачу нельзя или нет смысла декомпозировать далее
- будущий исполнитель проставил Original Estimate и мы пересмотрим задачу, если превысим его

<!-- Удалить кого не было на ревью -->
Состав (галочка означает согласие со всеми утверждениями выше):
- [ ] Кирилл Роговой
- [ ] Илья Левин
- [ ] Антон Тейхриб
- [ ] Юрий Юрин