-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
AudioLevelObserver.ts
123 lines (105 loc) · 2.44 KB
/
AudioLevelObserver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import Logger from './Logger';
import EnhancedEventEmitter from './EnhancedEventEmitter';
import RtpObserver from './RtpObserver';
import Producer from './Producer';
export interface AudioLevelObserverOptions
{
/**
* Maximum number of entries in the 'volumes”' event. Default 1.
*/
maxEntries?: number;
/**
* Minimum average volume (in dBvo from -127 to 0) for entries in the
* 'volumes' event. Default -80.
*/
threshold?: number;
/**
* Interval in ms for checking audio volumes. Default 1000.
*/
interval?: number;
/**
* Custom application data.
*/
appData?: any;
}
export interface AudioLevelObserverVolume
{
/**
* The audio producer instance.
*/
producer: Producer;
/**
* The average volume (in dBvo from -127 to 0) of the audio producer in the
* last interval.
*/
volume: number;
}
const logger = new Logger('AudioLevelObserver');
export default class AudioLevelObserver extends RtpObserver
{
/**
* @private
* @emits {volumes: Array<Object<producer: Producer, volume: Number>>} volumes
* @emits silence
*/
constructor(params: any)
{
super(params);
this._handleWorkerNotifications();
}
/**
* Observer.
*
* @emits close
* @emits pause
* @emits resume
* @emits {producer: Producer} addproducer
* @emits {producer: Producer} removeproducer
* @emits {producer: Producer} volumes
* @emits silence
*/
get observer(): EnhancedEventEmitter
{
return this._observer;
}
private _handleWorkerNotifications(): void
{
this._channel.on(this._internal.rtpObserverId, (event: string, data?: any) =>
{
switch (event)
{
case 'volumes':
{
// Get the corresponding Producer instance and remove entries with
// no Producer (it may have been closed in the meanwhile).
const volumes: AudioLevelObserverVolume[] = data
.map(({ producerId, volume }: { producerId: string; volume: number }) => (
{
producer: this._getProducerById(producerId),
volume
}
))
.filter(({ producer }: { producer: Producer }) => producer);
if (volumes.length > 0)
{
this.safeEmit('volumes', volumes);
// Emit observer event.
this._observer.safeEmit('volumes', volumes);
}
break;
}
case 'silence':
{
this.safeEmit('silence');
// Emit observer event.
this._observer.safeEmit('silence');
break;
}
default:
{
logger.error('ignoring unknown event "%s"', event);
}
}
});
}
}