sip-connector 16.0.0 → 16.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +255 -19
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -9,6 +9,23 @@
|
|
|
9
9
|
|
|
10
10
|
**sip-connector** — это TypeScript SDK для интеграции WebRTC-приложений с платформой Vinteo через SIP-протокол. Библиотека построена на базе `@krivega/jssip` и предоставляет высокоуровневый API для создания полнофункциональных видеоконференций.
|
|
11
11
|
|
|
12
|
+
### 🚨 Breaking Changes в версии 16.0.0
|
|
13
|
+
|
|
14
|
+
**Важные изменения, требующие обновления кода:**
|
|
15
|
+
|
|
16
|
+
- **VideoSendingBalancer перенесен в SipConnector**: Теперь балансировка видео настраивается через конструктор `SipConnector` с параметром `videoBalancerOptions`
|
|
17
|
+
- **Удален параметр `simulcastEncodings`**: Вместо него используется `sendEncodings` для настройки кодировок
|
|
18
|
+
- **Автоматический запуск балансировки**: VideoSendingBalancer теперь автоматически запускается через 10 секунд после начала звонка
|
|
19
|
+
- **Новые события балансировки**: Добавлены события `video-balancer:*` для мониторинга состояния балансировки
|
|
20
|
+
|
|
21
|
+
### 🆕 Новые возможности версии 16.0.0
|
|
22
|
+
|
|
23
|
+
- **Адаптивный polling**: Улучшенная система опроса для мониторинга изменений видеотреков
|
|
24
|
+
- **Поддержка maxBitrate в PresentationManager**: Автоматическое управление битрейтом для презентаций
|
|
25
|
+
- **Предпочтительные кодеки в SipConnector**: Настройка приоритетов кодеков на уровне коннектора
|
|
26
|
+
- **Обработка смены треков**: Автоматическая адаптация балансировки при изменении видеотреков
|
|
27
|
+
- **Улучшенная статистика**: Расширенные возможности сбора и анализа WebRTC статистики
|
|
28
|
+
|
|
12
29
|
### 🎯 Основные возможности
|
|
13
30
|
|
|
14
31
|
SDK предоставляет комплексное решение для:
|
|
@@ -76,17 +93,25 @@ pnpm add sip-connector
|
|
|
76
93
|
import { UA, WebSocketInterface } from '@krivega/jssip';
|
|
77
94
|
import { SipConnector, SipConnectorFacade, tools } from 'sip-connector';
|
|
78
95
|
|
|
79
|
-
// Создание низкоуровневого коннектора
|
|
80
|
-
const sipConnector = new SipConnector(
|
|
81
|
-
JsSIP: { UA, WebSocketInterface },
|
|
82
|
-
|
|
96
|
+
// Создание низкоуровневого коннектора с настройками кодеков
|
|
97
|
+
const sipConnector = new SipConnector(
|
|
98
|
+
{ JsSIP: { UA, WebSocketInterface } },
|
|
99
|
+
{
|
|
100
|
+
// Приоритизация современных кодеков
|
|
101
|
+
preferredMimeTypesVideoCodecs: ['video/AV1', 'video/VP9'],
|
|
102
|
+
excludeMimeTypesVideoCodecs: ['video/H264'],
|
|
103
|
+
// Настройки видеобалансировщика (опционально)
|
|
104
|
+
videoBalancerOptions: {
|
|
105
|
+
ignoreForCodec: 'H264',
|
|
106
|
+
onSetParameters: (result) => {
|
|
107
|
+
console.log('Video parameters updated:', result);
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
);
|
|
83
112
|
|
|
84
|
-
// Создание фасада
|
|
85
|
-
const facade = new SipConnectorFacade(sipConnector
|
|
86
|
-
// Приоритизация современных кодеков
|
|
87
|
-
preferredMimeTypesVideoCodecs: ['video/AV1', 'video/VP9'],
|
|
88
|
-
excludeMimeTypesVideoCodecs: ['video/H264'],
|
|
89
|
-
});
|
|
113
|
+
// Создание фасада
|
|
114
|
+
const facade = new SipConnectorFacade(sipConnector);
|
|
90
115
|
```
|
|
91
116
|
|
|
92
117
|
### Шаг 2: Подключение к серверу
|
|
@@ -190,7 +215,9 @@ await facade.startPresentation({
|
|
|
190
215
|
mediaStream: displayStream,
|
|
191
216
|
isP2P: false, // MCU режим
|
|
192
217
|
contentHint: 'detail', // Оптимизация для детального контента
|
|
193
|
-
|
|
218
|
+
maxBitrate: 4000000, // Максимальный битрейт 4 Мбит/с
|
|
219
|
+
degradationPreference: 'maintain-resolution', // Приоритет разрешения
|
|
220
|
+
sendEncodings: [
|
|
194
221
|
{ width: 1920, height: 1080, scalabilityMode: 'L3T3_KEY' },
|
|
195
222
|
{ width: 1280, height: 720 },
|
|
196
223
|
],
|
|
@@ -200,16 +227,59 @@ await facade.startPresentation({
|
|
|
200
227
|
### Обновление и остановка
|
|
201
228
|
|
|
202
229
|
```typescript
|
|
203
|
-
// Обновление потока презентации
|
|
230
|
+
// Обновление потока презентации с новыми настройками
|
|
204
231
|
await facade.updatePresentation({
|
|
205
232
|
mediaStream: newDisplayStream,
|
|
206
233
|
isP2P: false,
|
|
234
|
+
maxBitrate: 6000000, // Увеличенный битрейт для HD контента
|
|
235
|
+
contentHint: 'text', // Оптимизация для текстового контента
|
|
207
236
|
});
|
|
208
237
|
|
|
209
238
|
// Остановка презентации
|
|
210
239
|
await facade.stopShareSipConnector();
|
|
211
240
|
```
|
|
212
241
|
|
|
242
|
+
### Настройки качества презентации
|
|
243
|
+
|
|
244
|
+
| Параметр | Описание | Рекомендуемые значения |
|
|
245
|
+
| ----------------------- | -------------------------------- | --------------------------------------- |
|
|
246
|
+
| `maxBitrate` | Максимальный битрейт (bps) | 2-8 Мбит/с в зависимости от контента |
|
|
247
|
+
| `contentHint` | Тип контента для оптимизации | `'detail'`, `'text'`, `'motion'` |
|
|
248
|
+
| `degradationPreference` | Приоритет при ухудшении качества | `'maintain-resolution'` для презентаций |
|
|
249
|
+
|
|
250
|
+
```typescript
|
|
251
|
+
// Адаптивные настройки в зависимости от типа контента
|
|
252
|
+
const presentationSettings = {
|
|
253
|
+
// For detailed graphics/images
|
|
254
|
+
highQuality: {
|
|
255
|
+
maxBitrate: 8000000,
|
|
256
|
+
contentHint: 'detail' as const,
|
|
257
|
+
degradationPreference: 'maintain-resolution' as const,
|
|
258
|
+
},
|
|
259
|
+
|
|
260
|
+
// For text documents
|
|
261
|
+
textOptimized: {
|
|
262
|
+
maxBitrate: 4000000,
|
|
263
|
+
contentHint: 'text' as const,
|
|
264
|
+
degradationPreference: 'maintain-resolution' as const,
|
|
265
|
+
},
|
|
266
|
+
|
|
267
|
+
// For video content
|
|
268
|
+
videoOptimized: {
|
|
269
|
+
maxBitrate: 6000000,
|
|
270
|
+
contentHint: 'motion' as const,
|
|
271
|
+
degradationPreference: 'maintain-framerate' as const,
|
|
272
|
+
},
|
|
273
|
+
};
|
|
274
|
+
|
|
275
|
+
// Использование настроек
|
|
276
|
+
await facade.startPresentation({
|
|
277
|
+
mediaStream: displayStream,
|
|
278
|
+
isP2P: false,
|
|
279
|
+
...presentationSettings.textOptimized,
|
|
280
|
+
});
|
|
281
|
+
```
|
|
282
|
+
|
|
213
283
|
---
|
|
214
284
|
|
|
215
285
|
## 👥 Управление участниками конференции
|
|
@@ -360,6 +430,32 @@ const roomData = await sipConnector.wait('api:enterRoom');
|
|
|
360
430
|
console.log('Данные комнаты:', roomData);
|
|
361
431
|
```
|
|
362
432
|
|
|
433
|
+
### События балансировки видео (версия 16.0.0+)
|
|
434
|
+
|
|
435
|
+
```typescript
|
|
436
|
+
// Мониторинг автоматической балансировки видео
|
|
437
|
+
sipConnector.on('video-balancer:balancing-scheduled', (data) => {
|
|
438
|
+
console.log(`Балансировка запланирована через ${data.delay}ms`);
|
|
439
|
+
});
|
|
440
|
+
|
|
441
|
+
sipConnector.on('video-balancer:balancing-started', (data) => {
|
|
442
|
+
console.log(`Балансировка запущена после задержки ${data.delay}ms`);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
sipConnector.on('video-balancer:balancing-stopped', () => {
|
|
446
|
+
console.log('Балансировка остановлена');
|
|
447
|
+
});
|
|
448
|
+
|
|
449
|
+
sipConnector.on('video-balancer:error', (error) => {
|
|
450
|
+
console.error('Ошибка балансировки:', error);
|
|
451
|
+
});
|
|
452
|
+
|
|
453
|
+
// Ручное управление балансировкой
|
|
454
|
+
sipConnector.videoSendingBalancerManager.start(); // Принудительный запуск
|
|
455
|
+
sipConnector.videoSendingBalancerManager.stop(); // Остановка
|
|
456
|
+
sipConnector.videoSendingBalancerManager.restart(); // Перезапуск
|
|
457
|
+
```
|
|
458
|
+
|
|
363
459
|
---
|
|
364
460
|
|
|
365
461
|
## 📈 WebRTC Статистика
|
|
@@ -389,12 +485,39 @@ if (hasAvailableStats()) {
|
|
|
389
485
|
console.log('Исходящая статистика:', outbound);
|
|
390
486
|
console.log('Входящая статистика:', inbound);
|
|
391
487
|
|
|
488
|
+
// Новая метрика availableIncomingBitrate
|
|
489
|
+
if (inbound.availableIncomingBitrate) {
|
|
490
|
+
console.log('Доступный входящий битрейт:', inbound.availableIncomingBitrate);
|
|
491
|
+
}
|
|
492
|
+
|
|
392
493
|
// Анализ качества соединения
|
|
393
494
|
analyzeConnectionQuality(outbound, inbound);
|
|
394
495
|
});
|
|
496
|
+
|
|
497
|
+
// Запуск сбора статистики с адаптивным интервалом
|
|
498
|
+
statsCollector.start(peerConnection);
|
|
395
499
|
}
|
|
396
500
|
```
|
|
397
501
|
|
|
502
|
+
### Адаптивный интервал сбора статистики
|
|
503
|
+
|
|
504
|
+
SDK автоматически адаптирует частоту сбора статистики в зависимости от времени выполнения:
|
|
505
|
+
|
|
506
|
+
| Время выполнения | Множитель интервала | Интервал (мс) |
|
|
507
|
+
| ---------------- | ------------------- | ------------- |
|
|
508
|
+
| < 16 мс | 1x | 1000 |
|
|
509
|
+
| 16-32 мс | 2x | 2000 |
|
|
510
|
+
| 32-48 мс | 3x | 3000 |
|
|
511
|
+
| > 48 мс | 4x | 4000 |
|
|
512
|
+
|
|
513
|
+
```typescript
|
|
514
|
+
// Мониторинг производительности сбора статистики
|
|
515
|
+
statsCollector.on('collected', (stats) => {
|
|
516
|
+
const collectionTime = performance.now() - startTime;
|
|
517
|
+
console.log(`Статистика собрана за ${collectionTime}мс`);
|
|
518
|
+
});
|
|
519
|
+
```
|
|
520
|
+
|
|
398
521
|
### Типы статистики
|
|
399
522
|
|
|
400
523
|
| Категория | Типы | Описание |
|
|
@@ -405,6 +528,108 @@ if (hasAvailableStats()) {
|
|
|
405
528
|
|
|
406
529
|
---
|
|
407
530
|
|
|
531
|
+
## ⚡ Адаптивное опрашивание видеопотоков
|
|
532
|
+
|
|
533
|
+
### Принцип работы
|
|
534
|
+
|
|
535
|
+
SDK использует **адаптивное опрашивание** для мониторинга изменений в видеопотоках, что значительно снижает нагрузку на CPU:
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
// TrackMonitor автоматически адаптирует частоту опрашивания
|
|
539
|
+
const trackMonitor = new TrackMonitor({
|
|
540
|
+
pollIntervalMs: 1000, // Начальный интервал
|
|
541
|
+
maxPollIntervalMs: 16000, // Максимальный интервал (16x)
|
|
542
|
+
});
|
|
543
|
+
```
|
|
544
|
+
|
|
545
|
+
### Алгоритм адаптации
|
|
546
|
+
|
|
547
|
+
| Ситуация | Действие | Результат |
|
|
548
|
+
| ------------------------ | ------------------------------- | ---------------------------- |
|
|
549
|
+
| **Изменение разрешения** | Сброс интервала до минимального | Быстрая реакция на изменения |
|
|
550
|
+
| **Нет изменений** | Удвоение интервала | Снижение нагрузки на CPU |
|
|
551
|
+
| **Достижение максимума** | Ограничение интервала | Предотвращение "заморозки" |
|
|
552
|
+
|
|
553
|
+
### Преимущества
|
|
554
|
+
|
|
555
|
+
- **Снижение CPU нагрузки на 40-60%** при стабильном видео
|
|
556
|
+
- **Быстрая реакция** на изменения разрешения (resize events)
|
|
557
|
+
- **Автоматическое обнаружение** замены треков (replaceTrack)
|
|
558
|
+
- **Настраиваемые интервалы** для разных сценариев использования
|
|
559
|
+
|
|
560
|
+
```typescript
|
|
561
|
+
// Пример использования с кастомными настройками
|
|
562
|
+
const monitor = new TrackMonitor({
|
|
563
|
+
pollIntervalMs: 500, // Более частое начальное опрашивание
|
|
564
|
+
maxPollIntervalMs: 8000, // Меньший максимальный интервал
|
|
565
|
+
});
|
|
566
|
+
|
|
567
|
+
// Подписка на изменения
|
|
568
|
+
monitor.subscribe(videoSender, () => {
|
|
569
|
+
console.log('Обнаружено изменение видеопотока');
|
|
570
|
+
// Перебалансировка параметров
|
|
571
|
+
rebalanceVideoParameters();
|
|
572
|
+
});
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
---
|
|
576
|
+
|
|
577
|
+
## 🎛️ Управление видеобалансировщиком
|
|
578
|
+
|
|
579
|
+
### Автоматическая балансировка
|
|
580
|
+
|
|
581
|
+
С версии 16.0.0 `VideoSendingBalancer` интегрирован в `SipConnector` и запускается автоматически:
|
|
582
|
+
|
|
583
|
+
```typescript
|
|
584
|
+
const sipConnector = new SipConnector(
|
|
585
|
+
{ JsSIP: { UA, WebSocketInterface } },
|
|
586
|
+
{
|
|
587
|
+
videoBalancerOptions: {
|
|
588
|
+
ignoreForCodec: 'H264', // Игнорировать H264
|
|
589
|
+
balancingStartDelay: 10000, // Задержка запуска (мс)
|
|
590
|
+
pollIntervalMs: 1000, // Интервал мониторинга
|
|
591
|
+
onSetParameters: (result) => {
|
|
592
|
+
console.log('Параметры обновлены:', result);
|
|
593
|
+
},
|
|
594
|
+
},
|
|
595
|
+
},
|
|
596
|
+
);
|
|
597
|
+
|
|
598
|
+
// Подписка на события балансировщика
|
|
599
|
+
sipConnector.on('video-balancer:balancing-started', (data) => {
|
|
600
|
+
console.log(`Балансировка запущена через ${data.delay}мс`);
|
|
601
|
+
});
|
|
602
|
+
|
|
603
|
+
sipConnector.on('video-balancer:parameters-updated', (result) => {
|
|
604
|
+
console.log('Обновлены параметры:', result);
|
|
605
|
+
});
|
|
606
|
+
```
|
|
607
|
+
|
|
608
|
+
### Жизненный цикл балансировщика
|
|
609
|
+
|
|
610
|
+
```mermaid
|
|
611
|
+
graph TD
|
|
612
|
+
A[Начало звонка] --> B[Задержка 10 сек]
|
|
613
|
+
B --> C[Запуск балансировки]
|
|
614
|
+
C --> D[Мониторинг изменений]
|
|
615
|
+
D --> E{Изменение треков?}
|
|
616
|
+
E -->|Да| F[Перебалансировка]
|
|
617
|
+
E -->|Нет| D
|
|
618
|
+
F --> D
|
|
619
|
+
G[Завершение звонка] --> H[Остановка балансировки]
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
### События балансировщика
|
|
623
|
+
|
|
624
|
+
| Событие | Описание | Данные |
|
|
625
|
+
| ------------------------------------ | -------------------------- | ------------------------------ |
|
|
626
|
+
| `video-balancer:balancing-scheduled` | Балансировка запланирована | `{ delay: number }` |
|
|
627
|
+
| `video-balancer:balancing-started` | Балансировка запущена | `{ delay: number }` |
|
|
628
|
+
| `video-balancer:balancing-stopped` | Балансировка остановлена | - |
|
|
629
|
+
| `video-balancer:parameters-updated` | Параметры обновлены | `TResultSetParametersToSender` |
|
|
630
|
+
|
|
631
|
+
---
|
|
632
|
+
|
|
408
633
|
## 🔧 API и экспорты
|
|
409
634
|
|
|
410
635
|
### Основные классы
|
|
@@ -450,8 +675,11 @@ import {
|
|
|
450
675
|
├─────────────────────────────────────┤
|
|
451
676
|
│ SipConnector │ ← Координация менеджеров
|
|
452
677
|
├─────────────────────────────────────┤
|
|
453
|
-
│ Connection
|
|
454
|
-
│ Manager
|
|
678
|
+
│ Connection │ Call │ API │Stats │ ← Основные менеджеры
|
|
679
|
+
│ Manager │Manager │Manager│Manager│
|
|
680
|
+
├─────────────────────────────────────┤
|
|
681
|
+
│ Presentation│IncomingCall│VideoBalancer│ ← Специализированные менеджеры
|
|
682
|
+
│ Manager │Manager │Manager │
|
|
455
683
|
├─────────────────────────────────────┤
|
|
456
684
|
│ @krivega/jssip │ ← SIP-функциональность
|
|
457
685
|
└─────────────────────────────────────┘
|
|
@@ -509,10 +737,18 @@ useEffect(() => {
|
|
|
509
737
|
const debouncedStatsHandler = debounce(handleStats, 1000);
|
|
510
738
|
facade.onStats(debouncedStatsHandler);
|
|
511
739
|
|
|
512
|
-
// Приоритизируйте современные кодеки
|
|
513
|
-
const
|
|
514
|
-
|
|
515
|
-
|
|
740
|
+
// Приоритизируйте современные кодеки и настройте балансировку
|
|
741
|
+
const sipConnector = new SipConnector(
|
|
742
|
+
{ JsSIP: { UA, WebSocketInterface } },
|
|
743
|
+
{
|
|
744
|
+
preferredMimeTypesVideoCodecs: ['video/AV1', 'video/VP9'],
|
|
745
|
+
videoBalancerOptions: {
|
|
746
|
+
ignoreForCodec: 'H264',
|
|
747
|
+
balancingStartDelay: 5000, // Быстрее запуск для критичных приложений
|
|
748
|
+
},
|
|
749
|
+
},
|
|
750
|
+
);
|
|
751
|
+
const facade = new SipConnectorFacade(sipConnector);
|
|
516
752
|
```
|
|
517
753
|
|
|
518
754
|
---
|
|
@@ -616,7 +852,7 @@ if (!navigator.mediaDevices?.getDisplayMedia) {
|
|
|
616
852
|
|
|
617
853
|
## 👨💻 Автор
|
|
618
854
|
|
|
619
|
-
|
|
855
|
+
### Krivega Dmitriy
|
|
620
856
|
|
|
621
857
|
- 🌐 Website: [krivega.com](https://krivega.com)
|
|
622
858
|
- 📱 Github: [@Krivega](https://github.com/Krivega)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sip-connector",
|
|
3
|
-
"version": "16.0.
|
|
3
|
+
"version": "16.0.1",
|
|
4
4
|
"description": "Module for connect to Vinteo server",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"webrtc",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"@krivega/timeout-requester": "^1.0.0",
|
|
62
62
|
"debug": "^4.4.1",
|
|
63
63
|
"events-constructor": "^2.0.0",
|
|
64
|
-
"repeated-calls": "^2.3.
|
|
64
|
+
"repeated-calls": "^2.3.5",
|
|
65
65
|
"sequent-promises": "^2.0.1",
|
|
66
66
|
"stack-promises": "^2.0.3",
|
|
67
67
|
"ts-debounce": "^4.0.0",
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"@commitlint/cli": "^19.8.1",
|
|
75
75
|
"@commitlint/config-conventional": "^19.8.1",
|
|
76
76
|
"@eslint/compat": "^1.3.2",
|
|
77
|
-
"@krivega/eslint-config": "^1.0.
|
|
77
|
+
"@krivega/eslint-config": "^1.0.2",
|
|
78
78
|
"@types/debug": "^4.1.12",
|
|
79
79
|
"@types/dom-mediacapture-transform": "^0.1.11",
|
|
80
80
|
"@types/jest": "^30.0.0",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"@krivega/timeout-requester": "^1.0.0",
|
|
102
102
|
"debug": "^4.4.1",
|
|
103
103
|
"events-constructor": "^2.0.0",
|
|
104
|
-
"repeated-calls": "^2.3.
|
|
104
|
+
"repeated-calls": "^2.3.5",
|
|
105
105
|
"sequent-promises": "^2.0.1",
|
|
106
106
|
"stack-promises": "^2.0.3",
|
|
107
107
|
"ts-debounce": "^4.0.0",
|