homebridge-plugin-utils 1.1.0 → 1.3.0

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/dist/rtp.js ADDED
@@ -0,0 +1,178 @@
1
+ /* Copyright(C) 2017-2024, HJD (https://github.com/hjdhjd). All rights reserved.
2
+ *
3
+ * rtp.ts: RTP-related utilities to slice and dice RTP streams.
4
+ *
5
+ * This module is heavily inspired by the homebridge and homebridge-camera-ffmpeg source code and borrows from both. Thank you for your contributions to the community.
6
+ */
7
+ import { EventEmitter, once } from "node:events";
8
+ import { createSocket } from "node:dgram";
9
+ // How often, in seconds, should we heartbeat FFmpeg in two-way audio sessions. This should be less than 5 seconds, which is FFmpeg's input timeout interval.
10
+ const TWOWAY_HEARTBEAT_INTERVAL = 3;
11
+ /*
12
+ * Here's the problem this class solves: FFmpeg doesn't support multiplexing RTP and RTCP data on a single UDP port (RFC 5761). If it did, we wouldn't need this
13
+ * workaround for HomeKit compatibility, which does multiplex RTP and RTCP over a single UDP port.
14
+ *
15
+ * This class inspects all packets coming in from inputPort and demultiplexes RTP and RTCP traffic to rtpPort and rtcpPort, respectively.
16
+ *
17
+ * Credit to @dgreif and @brandawg93 who graciously shared their code as a starting point, and their collaboration in answering the questions needed to bring all this
18
+ * together. A special thank you to @Sunoo for the many hours of discussion and brainstorming on this and other topics.
19
+ */
20
+ export class RtpDemuxer extends EventEmitter {
21
+ heartbeatTimer;
22
+ heartbeatMsg;
23
+ _isRunning;
24
+ log;
25
+ inputPort;
26
+ socket;
27
+ // Create an instance of RtpDemuxer.
28
+ constructor(ipFamily, inputPort, rtcpPort, rtpPort, log) {
29
+ super();
30
+ this._isRunning = false;
31
+ this.log = log;
32
+ this.inputPort = inputPort;
33
+ this.socket = createSocket(ipFamily === "ipv6" ? "udp6" : "udp4");
34
+ // Catch errors when they happen on our demuxer.
35
+ this.socket.on("error", (error) => {
36
+ this.log?.error("RtpDemuxer Error: %s", error);
37
+ this.socket.close();
38
+ });
39
+ // Split the message into RTP and RTCP packets.
40
+ this.socket.on("message", (msg) => {
41
+ // Send RTP packets to the RTP port.
42
+ if (this.isRtpMessage(msg)) {
43
+ this.emit("rtp");
44
+ this.socket.send(msg, rtpPort);
45
+ }
46
+ else {
47
+ // Save this RTCP message for heartbeat purposes for the RTP port. This works because RTCP packets will be ignored
48
+ // by ffmpeg on the RTP port, effectively providing a heartbeat to ensure FFmpeg doesn't timeout if there's an
49
+ // extended delay between data transmission.
50
+ this.heartbeatMsg = Buffer.from(msg);
51
+ // Clear the old heartbeat timer.
52
+ clearTimeout(this.heartbeatTimer);
53
+ this.heartbeat(rtpPort);
54
+ // RTCP control packets should go to the RTCP port.
55
+ this.socket.send(msg, rtcpPort);
56
+ }
57
+ });
58
+ this.log?.debug("Creating an RtpDemuxer instance - inbound port: %s, RTCP port: %s, RTP port: %s.", this.inputPort, rtcpPort, rtpPort);
59
+ // Take the socket live.
60
+ this.socket.bind(this.inputPort);
61
+ this._isRunning = true;
62
+ }
63
+ // Send a regular heartbeat to FFmpeg to ensure the pipe remains open and the process alive.
64
+ heartbeat(port) {
65
+ // Clear the old heartbeat timer.
66
+ clearTimeout(this.heartbeatTimer);
67
+ // Send a heartbeat to FFmpeg every few seconds to keep things open. FFmpeg has a five-second timeout
68
+ // in reading input, and we want to be comfortably within the margin for error to ensure the process
69
+ // continues to run.
70
+ this.heartbeatTimer = setTimeout(() => {
71
+ this.log?.debug("Sending ffmpeg a heartbeat.");
72
+ this.socket.send(this.heartbeatMsg, port);
73
+ this.heartbeat(port);
74
+ }, TWOWAY_HEARTBEAT_INTERVAL * 1000);
75
+ }
76
+ // Close the socket and cleanup.
77
+ close() {
78
+ this.log?.debug("Closing the RtpDemuxer instance on port %s.", this.inputPort);
79
+ clearTimeout(this.heartbeatTimer);
80
+ this.socket.close();
81
+ this._isRunning = false;
82
+ this.emit("rtp");
83
+ }
84
+ // Retrieve the payload information from a packet to discern what the packet payload is.
85
+ getPayloadType(message) {
86
+ return message.readUInt8(1) & 0x7f;
87
+ }
88
+ // Return whether or not a packet is RTP (or not).
89
+ isRtpMessage(message) {
90
+ const payloadType = this.getPayloadType(message);
91
+ return (payloadType > 90) || (payloadType === 0);
92
+ }
93
+ // Inform people whether we are up and running or not.
94
+ get isRunning() {
95
+ return this._isRunning;
96
+ }
97
+ }
98
+ /* RTP port allocator class that keeps track of UDP ports that are currently earmarked for use. We need this when allocating ports that we use for various network
99
+ * activities such as demuxing FFmpeg or opening up other sockets. Otherwise, we run a risk (especially in environment where there are many such requests) of allocating
100
+ * the same port multiple times and end up erroring out unceremoniously.
101
+ */
102
+ export class RtpPortAllocator {
103
+ portsInUse;
104
+ // Instantiate our port retrieval.
105
+ constructor() {
106
+ // Initialize our in use tracker.
107
+ this.portsInUse = {};
108
+ }
109
+ // Find an available UDP port by binding to one to validate it's availability.
110
+ async getPort(ipFamily, port = 0) {
111
+ try {
112
+ // Keep looping until we find what we're looking for: local UDP ports that are unspoken for.
113
+ for (;;) {
114
+ // Create a datagram socket, so we can use it to find a port.
115
+ const socket = createSocket(ipFamily === "ipv6" ? "udp6" : "udp4");
116
+ // Exclude this socket from Node's reference counting so we don't have issues later.
117
+ socket.unref();
118
+ // Listen for the bind event.
119
+ const eventListener = once(socket, "listening");
120
+ // Bind to the port in question. If port is set to 0, we'll get a randomly generated port generated for us.
121
+ socket.bind(port);
122
+ // Ensure we wait for the socket to be bound.
123
+ // eslint-disable-next-line no-await-in-loop
124
+ await eventListener;
125
+ // Retrieve the port number we've gotten from the bind request.
126
+ const assignedPort = socket.address().port;
127
+ // We're done with the socket, let's cleanup.
128
+ socket.close();
129
+ // Check to see if the port is one we're already using. If it is, try again.
130
+ if (this.portsInUse[assignedPort]) {
131
+ continue;
132
+ }
133
+ // Now let's mark the port in use.
134
+ this.portsInUse[assignedPort] = true;
135
+ // Return the port.
136
+ return assignedPort;
137
+ }
138
+ }
139
+ catch (error) {
140
+ return -1;
141
+ }
142
+ }
143
+ // Reserve consecutive ports for use with FFmpeg. FFmpeg currently lacks the ability to specify both the RTP and RTCP ports. FFmpeg always assumes, by convention, that
144
+ // when you specify an RTP port, the RTCP port is the RTP port + 1. In order to work around that challenge, we need to always ensure that when we reserve multiple ports
145
+ // for RTP (primarily for two-way audio) that we we are reserving consecutive ports only.
146
+ async reserve(ipFamily = "ipv4", portCount = 1, attempts = 0) {
147
+ // Sanity check and make sure we're not requesting any more than two ports at a time, or if we've exceeded our attempt limit.
148
+ if (![1, 2].includes(portCount) || (attempts > 10)) {
149
+ return -1;
150
+ }
151
+ let firstPort = 0;
152
+ // Find the appropriate number of ports being requested.
153
+ for (let i = 0; i < portCount; i++) {
154
+ // eslint-disable-next-line no-await-in-loop
155
+ const assignedPort = await this.getPort(ipFamily, firstPort ? firstPort + 1 : 0);
156
+ // We haven't gotten a port, let's try again.
157
+ if (assignedPort === -1) {
158
+ // If we've gotten the first port of a pair of ports, make sure we release it here.
159
+ if (firstPort) {
160
+ this.cancel(firstPort);
161
+ }
162
+ // We still haven't found what we're looking for...keep looking.
163
+ return this.reserve(ipFamily, portCount, attempts++);
164
+ }
165
+ // We've seen the first port we may be looking for, let's save it.
166
+ if (!firstPort) {
167
+ firstPort = assignedPort;
168
+ }
169
+ }
170
+ // Return the first port we've found.
171
+ return firstPort;
172
+ }
173
+ // Delete a port reservation that's no longer needed.
174
+ cancel(port) {
175
+ delete this.portsInUse[port];
176
+ }
177
+ }
178
+ //# sourceMappingURL=rtp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rtp.js","sourceRoot":"","sources":["../src/rtp.ts"],"names":[],"mappings":"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"}
@@ -7,7 +7,7 @@ export class FeatureOptions {
7
7
  defaults;
8
8
  valueOptions;
9
9
  // Create a feature option instance.
10
- constructor(categories, options, configuredOptions) {
10
+ constructor(categories, options, configuredOptions = []) {
11
11
  // Initialize our defaults.
12
12
  this._categories = [];
13
13
  this._configuredOptions = [];
@@ -20,8 +20,18 @@ export class FeatureOptions {
20
20
  this.configuredOptions = configuredOptions;
21
21
  this.options = options ?? {};
22
22
  }
23
- color(option, device) {
24
- switch (this.scope(option, device)) {
23
+ /**
24
+ * Return a Bootstrap-specific color reference depending on the scope of a given feature option.
25
+ *
26
+ * @param option - Feature option to check.
27
+ * @param device - Optional device scope identifier.
28
+ * @param controller - Optional controller scope identifier.
29
+ *
30
+ * @returns Returns a Bootstrap color utility class associated with each scope level. `text-info` denotes an entry that's been modified at that scope level, while
31
+ * `text-success` and `text-warning` denote options that were defined at higher levels in the scope hierarchy - controller and global, respectively.
32
+ */
33
+ color(option, device, controller) {
34
+ switch (this.scope(option, device, controller)) {
25
35
  case "device":
26
36
  return "text-info";
27
37
  case "controller":
@@ -82,32 +92,28 @@ export class FeatureOptions {
82
92
  /**
83
93
  * Parse a floating point feature option value.
84
94
  *
85
- * @param value - Value to parse.
95
+ * @param option - Feature option to check.
96
+ * @param device - Optional device scope identifier.
97
+ * @param controller - Optional controller scope identifier.
86
98
  *
87
- * @returns Returns a floating point number from a string, or `undefined` if it couldn't be parsed.
99
+ * @returns Returns the value of a value-centric option as a floating point number or `undefined` if it doesn't exist or couldn't be parsed.
88
100
  */
89
- getFloat(value) {
90
- // We don't have the value configured -- we're done.
91
- if (value === undefined) {
92
- return undefined;
93
- }
101
+ getFloat(option, device, controller) {
94
102
  // Parse the number and return the value.
95
- return this.parseOptionNumeric(value, parseFloat);
103
+ return this.parseOptionNumeric(this.value(option, device, controller), parseFloat);
96
104
  }
97
105
  /**
98
106
  * Parse an integer feature option value.
99
107
  *
100
- * @param value - Value to parse.
108
+ * @param option - Feature option to check.
109
+ * @param device - Optional device scope identifier.
110
+ * @param controller - Optional controller scope identifier.
101
111
  *
102
- * @returns Returns an integer from a string, or `undefined` if it couldn't be parsed.
112
+ * @returns Returns the value of a value-centric option as an integer or `undefined` if it doesn't exist or couldn't be parsed.
103
113
  */
104
- getInteger(value) {
105
- // We don't have the value configured -- we're done.
106
- if (value === undefined) {
107
- return undefined;
108
- }
114
+ getInteger(option, device, controller) {
109
115
  // Parse the number and return the value.
110
- return this.parseOptionNumeric(value, parseInt);
116
+ return this.parseOptionNumeric(this.value(option, device, controller), parseInt);
111
117
  }
112
118
  /**
113
119
  * Return whether an option has been set in either the device or controller scope context.
@@ -153,7 +159,7 @@ export class FeatureOptions {
153
159
  * @returns Returns an object containing the location in the scope hierarchy of an `option` as well as the current value associated with the option.
154
160
  */
155
161
  scope(option, device, controller) {
156
- return this.getOptionInfo(option, device, controller).scope;
162
+ return this.optionInfo(option, device, controller).scope;
157
163
  }
158
164
  /**
159
165
  * Return the current state of a feature option, traversing the scope hierarchy.
@@ -165,7 +171,7 @@ export class FeatureOptions {
165
171
  * @returns Returns true if the option is enabled, and false otherwise.
166
172
  */
167
173
  test(option, device, controller) {
168
- return this.getOptionInfo(option, device, controller).value;
174
+ return this.optionInfo(option, device, controller).value;
169
175
  }
170
176
  /**
171
177
  * Return the value associated with a value-centric feature option, traversing the scope hierarchy.
@@ -177,6 +183,10 @@ export class FeatureOptions {
177
183
  * @returns Returns the current value associated with `option` or `undefined` if none.
178
184
  */
179
185
  value(option, device, controller) {
186
+ // If this isn't a value-centric feature option, we're done.
187
+ if (!this.isValue(option)) {
188
+ return undefined;
189
+ }
180
190
  const getValue = (checkOption, checkId) => {
181
191
  const regex = this.valueRegex(checkOption, checkId);
182
192
  // Get the option value, if we have one.
@@ -287,7 +297,7 @@ export class FeatureOptions {
287
297
  }
288
298
  }
289
299
  // Utility function to return the setting of a particular option and it's position in the scoping hierarchy.
290
- getOptionInfo(option, device, controller) {
300
+ optionInfo(option, device, controller) {
291
301
  // There are a couple of ways to enable and disable options. The rules of the road are:
292
302
  //
293
303
  // 1. Explicitly disabling, or enabling an option on the controller propogates to all the devices that are managed by that controller. Why might you want to do this?
@@ -1 +1 @@
1
- {"version":3,"file":"featureoptions.js","sourceRoot":"","sources":["../src/featureoptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"featureoptions.js","sourceRoot":"","sources":["../src/featureoptions.ts"],"names":[],"mappings":"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"}