hap-nodejs 0.12.3-beta.2 → 0.12.3-beta.21

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.
Files changed (175) hide show
  1. package/README.md +1 -0
  2. package/dist/accessories/AirConditioner_accessory.js +24 -24
  3. package/dist/accessories/AirConditioner_accessory.js.map +1 -1
  4. package/dist/accessories/AppleTVRemote_accessory.js +23 -23
  5. package/dist/accessories/AppleTVRemote_accessory.js.map +1 -1
  6. package/dist/accessories/Camera_accessory.js +292 -373
  7. package/dist/accessories/Camera_accessory.js.map +1 -1
  8. package/dist/accessories/Fan_accessory.js +15 -21
  9. package/dist/accessories/Fan_accessory.js.map +1 -1
  10. package/dist/accessories/GarageDoorOpener_accessory.js +12 -12
  11. package/dist/accessories/GarageDoorOpener_accessory.js.map +1 -1
  12. package/dist/accessories/Light-AdaptiveLighting_accessory.js +31 -21
  13. package/dist/accessories/Light-AdaptiveLighting_accessory.js.map +1 -1
  14. package/dist/accessories/Light_accessory.js +45 -48
  15. package/dist/accessories/Light_accessory.js.map +1 -1
  16. package/dist/accessories/Lock_accessory.js +11 -11
  17. package/dist/accessories/Lock_accessory.js.map +1 -1
  18. package/dist/accessories/MotionSensor_accessory.js +8 -8
  19. package/dist/accessories/MotionSensor_accessory.js.map +1 -1
  20. package/dist/accessories/Outlet_accessory.js +10 -10
  21. package/dist/accessories/Outlet_accessory.js.map +1 -1
  22. package/dist/accessories/SmartSpeaker_accessory.js +11 -11
  23. package/dist/accessories/SmartSpeaker_accessory.js.map +1 -1
  24. package/dist/accessories/Sprinkler_accessory.js +19 -19
  25. package/dist/accessories/Sprinkler_accessory.js.map +1 -1
  26. package/dist/accessories/TV_accessory.js +17 -17
  27. package/dist/accessories/TV_accessory.js.map +1 -1
  28. package/dist/accessories/TemperatureSensor_accessory.js +6 -6
  29. package/dist/accessories/TemperatureSensor_accessory.js.map +1 -1
  30. package/dist/accessories/Wi-FiRouter_accessory.js +3 -3
  31. package/dist/accessories/Wi-FiRouter_accessory.js.map +1 -1
  32. package/dist/accessories/Wi-FiSatellite_accessory.js +4 -4
  33. package/dist/accessories/Wi-FiSatellite_accessory.js.map +1 -1
  34. package/dist/accessories/gstreamer-audioProducer.js +36 -47
  35. package/dist/accessories/gstreamer-audioProducer.js.map +1 -1
  36. package/dist/accessories/types.js +2 -2
  37. package/dist/accessories/types.js.map +1 -1
  38. package/dist/index.d.ts +0 -14
  39. package/dist/index.d.ts.map +1 -1
  40. package/dist/index.js +5 -28
  41. package/dist/index.js.map +1 -1
  42. package/dist/lib/Accessory.d.ts +1 -58
  43. package/dist/lib/Accessory.d.ts.map +1 -1
  44. package/dist/lib/Accessory.js +747 -1149
  45. package/dist/lib/Accessory.js.map +1 -1
  46. package/dist/lib/Advertiser.d.ts +1 -2
  47. package/dist/lib/Advertiser.d.ts.map +1 -1
  48. package/dist/lib/Advertiser.js +392 -524
  49. package/dist/lib/Advertiser.js.map +1 -1
  50. package/dist/lib/Bridge.js +6 -10
  51. package/dist/lib/Bridge.js.map +1 -1
  52. package/dist/lib/Characteristic.d.ts +2 -133
  53. package/dist/lib/Characteristic.d.ts.map +1 -1
  54. package/dist/lib/Characteristic.js +1467 -669
  55. package/dist/lib/Characteristic.js.map +1 -1
  56. package/dist/lib/HAPServer.d.ts +0 -10
  57. package/dist/lib/HAPServer.d.ts.map +1 -1
  58. package/dist/lib/HAPServer.js +216 -280
  59. package/dist/lib/HAPServer.js.map +1 -1
  60. package/dist/lib/Service.d.ts +1 -51
  61. package/dist/lib/Service.d.ts.map +1 -1
  62. package/dist/lib/Service.js +474 -322
  63. package/dist/lib/Service.js.map +1 -1
  64. package/dist/lib/camera/RTPProxy.js +112 -104
  65. package/dist/lib/camera/RTPProxy.js.map +1 -1
  66. package/dist/lib/camera/RTPStreamManagement.d.ts +0 -65
  67. package/dist/lib/camera/RTPStreamManagement.d.ts.map +1 -1
  68. package/dist/lib/camera/RTPStreamManagement.js +255 -278
  69. package/dist/lib/camera/RTPStreamManagement.js.map +1 -1
  70. package/dist/lib/camera/RecordingManagement.js +318 -381
  71. package/dist/lib/camera/RecordingManagement.js.map +1 -1
  72. package/dist/lib/camera/index.d.ts +0 -1
  73. package/dist/lib/camera/index.d.ts.map +1 -1
  74. package/dist/lib/camera/index.js +1 -2
  75. package/dist/lib/camera/index.js.map +1 -1
  76. package/dist/lib/controller/AdaptiveLightingController.d.ts +19 -3
  77. package/dist/lib/controller/AdaptiveLightingController.d.ts.map +1 -1
  78. package/dist/lib/controller/AdaptiveLightingController.js +217 -218
  79. package/dist/lib/controller/AdaptiveLightingController.js.map +1 -1
  80. package/dist/lib/controller/CameraController.d.ts +0 -4
  81. package/dist/lib/controller/CameraController.d.ts.map +1 -1
  82. package/dist/lib/controller/CameraController.js +189 -256
  83. package/dist/lib/controller/CameraController.js.map +1 -1
  84. package/dist/lib/controller/DoorbellController.js +38 -39
  85. package/dist/lib/controller/DoorbellController.js.map +1 -1
  86. package/dist/lib/controller/RemoteController.d.ts +0 -14
  87. package/dist/lib/controller/RemoteController.d.ts.map +1 -1
  88. package/dist/lib/controller/RemoteController.js +340 -415
  89. package/dist/lib/controller/RemoteController.js.map +1 -1
  90. package/dist/lib/controller/index.js +1 -1
  91. package/dist/lib/datastream/DataStreamManagement.js +56 -57
  92. package/dist/lib/datastream/DataStreamManagement.js.map +1 -1
  93. package/dist/lib/datastream/DataStreamParser.js +259 -304
  94. package/dist/lib/datastream/DataStreamParser.js.map +1 -1
  95. package/dist/lib/datastream/DataStreamServer.d.ts +0 -5
  96. package/dist/lib/datastream/DataStreamServer.d.ts.map +1 -1
  97. package/dist/lib/datastream/DataStreamServer.js +252 -269
  98. package/dist/lib/datastream/DataStreamServer.js.map +1 -1
  99. package/dist/lib/datastream/index.js +1 -1
  100. package/dist/lib/definitions/CharacteristicDefinitions.d.ts +1 -106
  101. package/dist/lib/definitions/CharacteristicDefinitions.d.ts.map +1 -1
  102. package/dist/lib/definitions/CharacteristicDefinitions.js +2000 -2995
  103. package/dist/lib/definitions/CharacteristicDefinitions.js.map +1 -1
  104. package/dist/lib/definitions/ServiceDefinitions.d.ts +0 -32
  105. package/dist/lib/definitions/ServiceDefinitions.d.ts.map +1 -1
  106. package/dist/lib/definitions/ServiceDefinitions.js +820 -1147
  107. package/dist/lib/definitions/ServiceDefinitions.js.map +1 -1
  108. package/dist/lib/definitions/generate-definitions.js +383 -679
  109. package/dist/lib/definitions/generate-definitions.js.map +1 -1
  110. package/dist/lib/definitions/generator-configuration.js +29 -29
  111. package/dist/lib/definitions/generator-configuration.js.map +1 -1
  112. package/dist/lib/definitions/index.js +1 -1
  113. package/dist/lib/model/AccessoryInfo.js +101 -136
  114. package/dist/lib/model/AccessoryInfo.js.map +1 -1
  115. package/dist/lib/model/ControllerStorage.js +86 -89
  116. package/dist/lib/model/ControllerStorage.js.map +1 -1
  117. package/dist/lib/model/HAPStorage.js +15 -16
  118. package/dist/lib/model/HAPStorage.js.map +1 -1
  119. package/dist/lib/model/IdentifierCache.js +49 -49
  120. package/dist/lib/model/IdentifierCache.js.map +1 -1
  121. package/dist/lib/tv/AccessControlManagement.js +40 -44
  122. package/dist/lib/tv/AccessControlManagement.js.map +1 -1
  123. package/dist/lib/util/checkName.d.ts +2 -1
  124. package/dist/lib/util/checkName.d.ts.map +1 -1
  125. package/dist/lib/util/checkName.js +7 -11
  126. package/dist/lib/util/checkName.js.map +1 -1
  127. package/dist/lib/util/clone.js +5 -27
  128. package/dist/lib/util/clone.js.map +1 -1
  129. package/dist/lib/util/color-utils.js +8 -12
  130. package/dist/lib/util/color-utils.js.map +1 -1
  131. package/dist/lib/util/eventedhttp.d.ts.map +1 -1
  132. package/dist/lib/util/eventedhttp.js +301 -409
  133. package/dist/lib/util/eventedhttp.js.map +1 -1
  134. package/dist/lib/util/hapCrypto.js +31 -32
  135. package/dist/lib/util/hapCrypto.js.map +1 -1
  136. package/dist/lib/util/hapStatusError.js +9 -12
  137. package/dist/lib/util/hapStatusError.js.map +1 -1
  138. package/dist/lib/util/net-utils.js +32 -53
  139. package/dist/lib/util/net-utils.js.map +1 -1
  140. package/dist/lib/util/once.js +3 -8
  141. package/dist/lib/util/once.js.map +1 -1
  142. package/dist/lib/util/promise-utils.js +8 -13
  143. package/dist/lib/util/promise-utils.js.map +1 -1
  144. package/dist/lib/util/request-util.js +2 -3
  145. package/dist/lib/util/request-util.js.map +1 -1
  146. package/dist/lib/util/time.js +5 -5
  147. package/dist/lib/util/time.js.map +1 -1
  148. package/dist/lib/util/tlv.d.ts +0 -27
  149. package/dist/lib/util/tlv.d.ts.map +1 -1
  150. package/dist/lib/util/tlv.js +71 -113
  151. package/dist/lib/util/tlv.js.map +1 -1
  152. package/dist/lib/util/uuid.d.ts +0 -9
  153. package/dist/lib/util/uuid.d.ts.map +1 -1
  154. package/dist/lib/util/uuid.js +15 -33
  155. package/dist/lib/util/uuid.js.map +1 -1
  156. package/dist/types.d.ts +0 -35
  157. package/dist/types.d.ts.map +1 -1
  158. package/dist/types.js.map +1 -1
  159. package/package.json +10 -10
  160. package/dist/BridgedCore.d.ts +0 -2
  161. package/dist/BridgedCore.d.ts.map +0 -1
  162. package/dist/BridgedCore.js +0 -43
  163. package/dist/BridgedCore.js.map +0 -1
  164. package/dist/Core.d.ts +0 -2
  165. package/dist/Core.d.ts.map +0 -1
  166. package/dist/Core.js +0 -52
  167. package/dist/Core.js.map +0 -1
  168. package/dist/lib/AccessoryLoader.d.ts +0 -28
  169. package/dist/lib/AccessoryLoader.d.ts.map +0 -1
  170. package/dist/lib/AccessoryLoader.js +0 -166
  171. package/dist/lib/AccessoryLoader.js.map +0 -1
  172. package/dist/lib/camera/Camera.d.ts +0 -43
  173. package/dist/lib/camera/Camera.d.ts.map +0 -1
  174. package/dist/lib/camera/Camera.js +0 -36
  175. package/dist/lib/camera/Camera.js.map +0 -1
@@ -1,63 +1,64 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- var tslib_1 = require("tslib");
4
- var assert_1 = tslib_1.__importDefault(require("assert"));
5
- var child_process_1 = require("child_process");
6
- var events_1 = require("events");
7
- var net_1 = require("net");
8
- var __1 = require("..");
9
- var cameraUUID = __1.uuid.generate("hap-nodejs:accessories:ip-camera");
10
- var camera = exports.accessory = new __1.Accessory("IPCamera", cameraUUID);
3
+ const tslib_1 = require("tslib");
4
+ const assert_1 = tslib_1.__importDefault(require("assert"));
5
+ const child_process_1 = require("child_process");
6
+ const events_1 = require("events");
7
+ const net_1 = require("net");
8
+ const __1 = require("..");
9
+ const cameraUUID = __1.uuid.generate("hap-nodejs:accessories:ip-camera");
10
+ const camera = exports.accessory = new __1.Accessory("IPCamera", cameraUUID);
11
11
  // @ts-expect-error: Core/BridgeCore API
12
12
  camera.username = "9F:B2:46:0C:40:DB";
13
13
  // @ts-expect-error: Core/BridgeCore API
14
14
  camera.pincode = "948-23-459";
15
15
  camera.category = 17 /* Categories.IP_CAMERA */;
16
- var FFMPEGH264ProfileNames = [
16
+ const FFMPEGH264ProfileNames = [
17
17
  "baseline",
18
18
  "main",
19
19
  "high",
20
20
  ];
21
- var FFMPEGH264LevelNames = [
21
+ const FFMPEGH264LevelNames = [
22
22
  "3.1",
23
23
  "3.2",
24
24
  "4.0",
25
25
  ];
26
- var ports = new Set();
26
+ const ports = new Set();
27
27
  function getPort() {
28
- for (var i = 5011;; i++) {
28
+ for (let i = 5011;; i++) {
29
29
  if (!ports.has(i)) {
30
30
  ports.add(i);
31
31
  return i;
32
32
  }
33
33
  }
34
34
  }
35
- var ExampleCamera = /** @class */ (function () {
36
- function ExampleCamera() {
37
- this.ffmpegDebugOutput = false;
38
- // keep track of sessions
39
- this.pendingSessions = {};
40
- this.ongoingSessions = {};
41
- this.handlingStreamingRequest = false;
42
- }
43
- ExampleCamera.prototype.handleSnapshotRequest = function (request, callback) {
44
- var _this = this;
45
- var ffmpegCommand = "-f lavfi -i testsrc=s=".concat(request.width, "x").concat(request.height, " -vframes 1 -f mjpeg -");
46
- var ffmpeg = (0, child_process_1.spawn)("ffmpeg", ffmpegCommand.split(" "), { env: process.env });
47
- var snapshotBuffers = [];
48
- ffmpeg.stdout.on("data", function (data) { return snapshotBuffers.push(data); });
49
- ffmpeg.stderr.on("data", function (data) {
50
- if (_this.ffmpegDebugOutput) {
35
+ class ExampleCamera {
36
+ ffmpegDebugOutput = false;
37
+ controller;
38
+ // keep track of sessions
39
+ pendingSessions = {};
40
+ ongoingSessions = {};
41
+ // minimal secure video properties.
42
+ configuration;
43
+ handlingStreamingRequest = false;
44
+ server;
45
+ handleSnapshotRequest(request, callback) {
46
+ const ffmpegCommand = `-f lavfi -i testsrc=s=${request.width}x${request.height} -vframes 1 -f mjpeg -`;
47
+ const ffmpeg = (0, child_process_1.spawn)("ffmpeg", ffmpegCommand.split(" "), { env: process.env });
48
+ const snapshotBuffers = [];
49
+ ffmpeg.stdout.on("data", data => snapshotBuffers.push(data));
50
+ ffmpeg.stderr.on("data", data => {
51
+ if (this.ffmpegDebugOutput) {
51
52
  console.log("SNAPSHOT: " + String(data));
52
53
  }
53
54
  });
54
- ffmpeg.on("exit", function (code, signal) {
55
+ ffmpeg.on("exit", (code, signal) => {
55
56
  if (signal) {
56
57
  console.log("Snapshot process was killed with signal: " + signal);
57
58
  callback(new Error("killed with signal " + signal));
58
59
  }
59
60
  else if (code === 0) {
60
- console.log("Successfully captured snapshot at ".concat(request.width, "x").concat(request.height));
61
+ console.log(`Successfully captured snapshot at ${request.width}x${request.height}`);
61
62
  callback(undefined, Buffer.concat(snapshotBuffers));
62
63
  }
63
64
  else {
@@ -65,18 +66,18 @@ var ExampleCamera = /** @class */ (function () {
65
66
  callback(new Error("Snapshot process exited with code " + code));
66
67
  }
67
68
  });
68
- };
69
+ }
69
70
  // called when iOS request rtp setup
70
- ExampleCamera.prototype.prepareStream = function (request, callback) {
71
- var sessionId = request.sessionID;
72
- var targetAddress = request.targetAddress;
73
- var video = request.video;
74
- var videoCryptoSuite = video.srtpCryptoSuite; // could be used to support multiple crypto suite (or support no suite for debugging)
75
- var videoSrtpKey = video.srtp_key;
76
- var videoSrtpSalt = video.srtp_salt;
77
- var videoSSRC = __1.CameraController.generateSynchronisationSource();
78
- var localPort = getPort();
79
- var sessionInfo = {
71
+ prepareStream(request, callback) {
72
+ const sessionId = request.sessionID;
73
+ const targetAddress = request.targetAddress;
74
+ const video = request.video;
75
+ const videoCryptoSuite = video.srtpCryptoSuite; // could be used to support multiple crypto suite (or support no suite for debugging)
76
+ const videoSrtpKey = video.srtp_key;
77
+ const videoSrtpSalt = video.srtp_salt;
78
+ const videoSSRC = __1.CameraController.generateSynchronisationSource();
79
+ const localPort = getPort();
80
+ const sessionInfo = {
80
81
  address: targetAddress,
81
82
  videoPort: video.port,
82
83
  localVideoPort: localPort,
@@ -84,7 +85,7 @@ var ExampleCamera = /** @class */ (function () {
84
85
  videoSRTP: Buffer.concat([videoSrtpKey, videoSrtpSalt]),
85
86
  videoSSRC: videoSSRC,
86
87
  };
87
- var response = {
88
+ const response = {
88
89
  video: {
89
90
  port: localPort,
90
91
  ssrc: videoSSRC,
@@ -95,38 +96,37 @@ var ExampleCamera = /** @class */ (function () {
95
96
  };
96
97
  this.pendingSessions[sessionId] = sessionInfo;
97
98
  callback(undefined, response);
98
- };
99
+ }
99
100
  // called when iOS device asks stream to start/stop/reconfigure
100
- ExampleCamera.prototype.handleStreamRequest = function (request, callback) {
101
- var _this = this;
102
- var sessionId = request.sessionID;
101
+ handleStreamRequest(request, callback) {
102
+ const sessionId = request.sessionID;
103
103
  switch (request.type) {
104
104
  case "start" /* StreamRequestTypes.START */: {
105
- var sessionInfo = this.pendingSessions[sessionId];
106
- var video = request.video;
107
- var profile = FFMPEGH264ProfileNames[video.profile];
108
- var level = FFMPEGH264LevelNames[video.level];
109
- var width = video.width;
110
- var height = video.height;
111
- var fps = video.fps;
112
- var payloadType = video.pt;
113
- var maxBitrate = video.max_bit_rate;
105
+ const sessionInfo = this.pendingSessions[sessionId];
106
+ const video = request.video;
107
+ const profile = FFMPEGH264ProfileNames[video.profile];
108
+ const level = FFMPEGH264LevelNames[video.level];
109
+ const width = video.width;
110
+ const height = video.height;
111
+ const fps = video.fps;
112
+ const payloadType = video.pt;
113
+ const maxBitrate = video.max_bit_rate;
114
114
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
115
- var rtcpInterval = video.rtcp_interval; // usually 0.5
116
- var mtu = video.mtu; // maximum transmission unit
117
- var address = sessionInfo.address;
118
- var videoPort = sessionInfo.videoPort;
119
- var localVideoPort = sessionInfo.localVideoPort;
120
- var ssrc = sessionInfo.videoSSRC;
121
- var cryptoSuite = sessionInfo.videoCryptoSuite;
122
- var videoSRTP = sessionInfo.videoSRTP.toString("base64");
123
- console.log("Starting video stream (".concat(width, "x").concat(height, ", ").concat(fps, " fps, ").concat(maxBitrate, " kbps, ").concat(mtu, " mtu)..."));
124
- var videoffmpegCommand = "-re -f lavfi -i testsrc=s=".concat(width, "x").concat(height, ":r=").concat(fps, " -map 0:0 ") +
125
- "-c:v h264 -pix_fmt yuv420p -r ".concat(fps, " -an -sn -dn -b:v ").concat(maxBitrate, "k ") +
126
- "-profile:v ".concat(profile, " -level:v ").concat(level, " ") +
127
- "-payload_type ".concat(payloadType, " -ssrc ").concat(ssrc, " -f rtp ");
115
+ const rtcpInterval = video.rtcp_interval; // usually 0.5
116
+ const mtu = video.mtu; // maximum transmission unit
117
+ const address = sessionInfo.address;
118
+ const videoPort = sessionInfo.videoPort;
119
+ const localVideoPort = sessionInfo.localVideoPort;
120
+ const ssrc = sessionInfo.videoSSRC;
121
+ const cryptoSuite = sessionInfo.videoCryptoSuite;
122
+ const videoSRTP = sessionInfo.videoSRTP.toString("base64");
123
+ console.log(`Starting video stream (${width}x${height}, ${fps} fps, ${maxBitrate} kbps, ${mtu} mtu)...`);
124
+ let videoffmpegCommand = `-re -f lavfi -i testsrc=s=${width}x${height}:r=${fps} -map 0:0 ` +
125
+ `-c:v h264 -pix_fmt yuv420p -r ${fps} -an -sn -dn -b:v ${maxBitrate}k ` +
126
+ `-profile:v ${profile} -level:v ${level} ` +
127
+ `-payload_type ${payloadType} -ssrc ${ssrc} -f rtp `;
128
128
  if (cryptoSuite !== 2 /* SRTPCryptoSuites.NONE */) {
129
- var suite = void 0;
129
+ let suite;
130
130
  switch (cryptoSuite) {
131
131
  case 0 /* SRTPCryptoSuites.AES_CM_128_HMAC_SHA1_80 */: // actually ffmpeg just supports AES_CM_128_HMAC_SHA1_80
132
132
  suite = "AES_CM_128_HMAC_SHA1_80";
@@ -135,41 +135,41 @@ var ExampleCamera = /** @class */ (function () {
135
135
  suite = "AES_CM_256_HMAC_SHA1_80";
136
136
  break;
137
137
  }
138
- videoffmpegCommand += "-srtp_out_suite ".concat(suite, " -srtp_out_params ").concat(videoSRTP, " s");
138
+ videoffmpegCommand += `-srtp_out_suite ${suite} -srtp_out_params ${videoSRTP} s`;
139
139
  }
140
- videoffmpegCommand += "rtp://".concat(address, ":").concat(videoPort, "?rtcpport=").concat(videoPort, "&localrtcpport=").concat(localVideoPort, "&pkt_size=").concat(mtu);
140
+ videoffmpegCommand += `rtp://${address}:${videoPort}?rtcpport=${videoPort}&localrtcpport=${localVideoPort}&pkt_size=${mtu}`;
141
141
  if (this.ffmpegDebugOutput) {
142
142
  console.log("FFMPEG command: ffmpeg " + videoffmpegCommand);
143
143
  }
144
- var ffmpegVideo = (0, child_process_1.spawn)("ffmpeg", videoffmpegCommand.split(" "), { env: process.env });
145
- var started_1 = false;
146
- ffmpegVideo.stderr.on("data", function (data) {
144
+ const ffmpegVideo = (0, child_process_1.spawn)("ffmpeg", videoffmpegCommand.split(" "), { env: process.env });
145
+ let started = false;
146
+ ffmpegVideo.stderr.on("data", (data) => {
147
147
  console.log(data.toString("utf8"));
148
- if (!started_1) {
149
- started_1 = true;
148
+ if (!started) {
149
+ started = true;
150
150
  console.log("FFMPEG: received first frame");
151
151
  callback(); // do not forget to execute callback once set up
152
152
  }
153
- if (_this.ffmpegDebugOutput) {
153
+ if (this.ffmpegDebugOutput) {
154
154
  console.log("VIDEO: " + String(data));
155
155
  }
156
156
  });
157
- ffmpegVideo.on("error", function (error) {
157
+ ffmpegVideo.on("error", error => {
158
158
  console.log("[Video] Failed to start video stream: " + error.message);
159
159
  callback(new Error("ffmpeg process creation failed!"));
160
160
  });
161
- ffmpegVideo.on("exit", function (code, signal) {
162
- var message = "[Video] ffmpeg exited with code: " + code + " and signal: " + signal;
161
+ ffmpegVideo.on("exit", (code, signal) => {
162
+ const message = "[Video] ffmpeg exited with code: " + code + " and signal: " + signal;
163
163
  if (code == null || code === 255) {
164
164
  console.log(message + " (Video stream stopped!)");
165
165
  }
166
166
  else {
167
167
  console.log(message + " (error)");
168
- if (!started_1) {
168
+ if (!started) {
169
169
  callback(new Error(message));
170
170
  }
171
171
  else {
172
- _this.controller.forceStopStreamingSession(sessionId);
172
+ this.controller.forceStopStreamingSession(sessionId);
173
173
  }
174
174
  }
175
175
  });
@@ -186,7 +186,7 @@ var ExampleCamera = /** @class */ (function () {
186
186
  callback();
187
187
  break;
188
188
  case "stop" /* StreamRequestTypes.STOP */: {
189
- var ongoingSession = this.ongoingSessions[sessionId];
189
+ const ongoingSession = this.ongoingSessions[sessionId];
190
190
  if (!ongoingSession) {
191
191
  callback();
192
192
  break;
@@ -205,15 +205,15 @@ var ExampleCamera = /** @class */ (function () {
205
205
  break;
206
206
  }
207
207
  }
208
- };
209
- ExampleCamera.prototype.updateRecordingActive = function (active) {
208
+ }
209
+ updateRecordingActive(active) {
210
210
  // we haven't implemented a prebuffer
211
211
  console.log("Recording active set to " + active);
212
- };
213
- ExampleCamera.prototype.updateRecordingConfiguration = function (configuration) {
212
+ }
213
+ updateRecordingConfiguration(configuration) {
214
214
  this.configuration = configuration;
215
215
  console.log(configuration);
216
- };
216
+ }
217
217
  /**
218
218
  * This is a very minimal, very experimental example on how to implement fmp4 streaming with a
219
219
  * CameraController supporting HomeKit Secure Video.
@@ -224,315 +224,234 @@ var ExampleCamera = /** @class */ (function () {
224
224
  * when the HomeKit Controller requests it (see the documentation of `CameraRecordingDelegate`).
225
225
  */
226
226
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
227
- ExampleCamera.prototype.handleRecordingStreamRequest = function (streamId) {
228
- return tslib_1.__asyncGenerator(this, arguments, function handleRecordingStreamRequest_1() {
229
- var STOP_AFTER_MOTION_STOP, profile, level, videoArgs, samplerate, audioArgs, pending, _a, _b, _c, box, motionDetected, fragment, isLast, e_1_1, error_1;
230
- var _d, e_1, _e, _f;
231
- var _g, _h, _j;
232
- return tslib_1.__generator(this, function (_k) {
233
- switch (_k.label) {
234
- case 0:
235
- (0, assert_1.default)(!!this.configuration);
236
- STOP_AFTER_MOTION_STOP = false;
237
- this.handlingStreamingRequest = true;
238
- (0, assert_1.default)(this.configuration.videoCodec.type === 0 /* VideoCodecType.H264 */);
239
- profile = this.configuration.videoCodec.parameters.profile === 2 /* H264Profile.HIGH */ ? "high"
240
- : this.configuration.videoCodec.parameters.profile === 1 /* H264Profile.MAIN */ ? "main" : "baseline";
241
- level = this.configuration.videoCodec.parameters.level === 2 /* H264Level.LEVEL4_0 */ ? "4.0"
242
- : this.configuration.videoCodec.parameters.level === 1 /* H264Level.LEVEL3_2 */ ? "3.2" : "3.1";
243
- videoArgs = [
244
- "-an",
245
- "-sn",
246
- "-dn",
247
- "-codec:v",
248
- "libx264",
249
- "-pix_fmt",
250
- "yuv420p",
251
- "-profile:v", profile,
252
- "-level:v", level,
253
- "-b:v",
254
- "".concat(this.configuration.videoCodec.parameters.bitRate, "k"),
255
- "-force_key_frames",
256
- "expr:eq(t,n_forced*".concat(this.configuration.videoCodec.parameters.iFrameInterval / 1000, ")"),
257
- "-r", this.configuration.videoCodec.resolution[2].toString(),
258
- ];
259
- switch (this.configuration.audioCodec.samplerate) {
260
- case 0 /* AudioRecordingSamplerate.KHZ_8 */:
261
- samplerate = "8";
262
- break;
263
- case 1 /* AudioRecordingSamplerate.KHZ_16 */:
264
- samplerate = "16";
265
- break;
266
- case 2 /* AudioRecordingSamplerate.KHZ_24 */:
267
- samplerate = "24";
268
- break;
269
- case 3 /* AudioRecordingSamplerate.KHZ_32 */:
270
- samplerate = "32";
271
- break;
272
- case 4 /* AudioRecordingSamplerate.KHZ_44_1 */:
273
- samplerate = "44.1";
274
- break;
275
- case 5 /* AudioRecordingSamplerate.KHZ_48 */:
276
- samplerate = "48";
277
- break;
278
- default:
279
- throw new Error("Unsupported audio samplerate: " + this.configuration.audioCodec.samplerate);
280
- }
281
- audioArgs = ((_h = (_g = this.controller) === null || _g === void 0 ? void 0 : _g.recordingManagement) === null || _h === void 0 ? void 0 : _h.recordingManagementService.getCharacteristic(__1.Characteristic.RecordingAudioActive))
282
- ? tslib_1.__spreadArray(tslib_1.__spreadArray([
283
- "-acodec", "libfdk_aac"
284
- ], tslib_1.__read((this.configuration.audioCodec.type === 0 /* AudioRecordingCodecType.AAC_LC */ ?
285
- ["-profile:a", "aac_low"] :
286
- ["-profile:a", "aac_eld"])), false), [
287
- "-ar",
288
- "".concat(samplerate, "k"),
289
- "-b:a",
290
- "".concat(this.configuration.audioCodec.bitrate, "k"),
291
- "-ac",
292
- "".concat(this.configuration.audioCodec.audioChannels),
293
- ], false) : [];
294
- this.server = new MP4StreamingServer("ffmpeg", "-f lavfi -i testsrc=s=".concat(this.configuration.videoCodec.resolution[0], "x").concat(this.configuration.videoCodec.resolution[1], ":r=").concat(this.configuration.videoCodec.resolution[2])
295
- .split(/ /g), audioArgs, videoArgs);
296
- return [4 /*yield*/, tslib_1.__await(this.server.start())];
297
- case 1:
298
- _k.sent();
299
- if (!(!this.server || this.server.destroyed)) return [3 /*break*/, 3];
300
- return [4 /*yield*/, tslib_1.__await(void 0)];
301
- case 2: return [2 /*return*/, _k.sent()]; // early exit
302
- case 3:
303
- pending = [];
304
- _k.label = 4;
305
- case 4:
306
- _k.trys.push([4, 19, , 20]);
307
- _k.label = 5;
308
- case 5:
309
- _k.trys.push([5, 12, 13, 18]);
310
- _a = true, _b = tslib_1.__asyncValues(this.server.generator());
311
- _k.label = 6;
312
- case 6: return [4 /*yield*/, tslib_1.__await(_b.next())];
313
- case 7:
314
- if (!(_c = _k.sent(), _d = _c.done, !_d)) return [3 /*break*/, 11];
315
- _f = _c.value;
316
- _a = false;
317
- box = _f;
318
- pending.push(box.header, box.data);
319
- motionDetected = (_j = camera.getService(__1.Service.MotionSensor)) === null || _j === void 0 ? void 0 : _j.getCharacteristic(__1.Characteristic.MotionDetected).value;
320
- console.log("mp4 box type " + box.type + " and length " + box.length);
321
- if (!(box.type === "moov" || box.type === "mdat")) return [3 /*break*/, 10];
322
- fragment = Buffer.concat(pending);
323
- pending.splice(0, pending.length);
324
- isLast = STOP_AFTER_MOTION_STOP && !motionDetected;
325
- return [4 /*yield*/, tslib_1.__await({
326
- data: fragment,
327
- isLast: isLast,
328
- })];
329
- case 8: return [4 /*yield*/, _k.sent()];
330
- case 9:
331
- _k.sent();
332
- if (isLast) {
333
- console.log("Ending session due to motion stopped!");
334
- return [3 /*break*/, 11];
335
- }
336
- _k.label = 10;
337
- case 10:
338
- _a = true;
339
- return [3 /*break*/, 6];
340
- case 11: return [3 /*break*/, 18];
341
- case 12:
342
- e_1_1 = _k.sent();
343
- e_1 = { error: e_1_1 };
344
- return [3 /*break*/, 18];
345
- case 13:
346
- _k.trys.push([13, , 16, 17]);
347
- if (!(!_a && !_d && (_e = _b.return))) return [3 /*break*/, 15];
348
- return [4 /*yield*/, tslib_1.__await(_e.call(_b))];
349
- case 14:
350
- _k.sent();
351
- _k.label = 15;
352
- case 15: return [3 /*break*/, 17];
353
- case 16:
354
- if (e_1) throw e_1.error;
355
- return [7 /*endfinally*/];
356
- case 17: return [7 /*endfinally*/];
357
- case 18: return [3 /*break*/, 20];
358
- case 19:
359
- error_1 = _k.sent();
360
- if (!error_1.message.startsWith("FFMPEG")) { // cheap way of identifying our own emitted errors
361
- console.error("Encountered unexpected error on generator " + error_1.stack);
362
- }
363
- return [3 /*break*/, 20];
364
- case 20: return [2 /*return*/];
227
+ async *handleRecordingStreamRequest(streamId) {
228
+ (0, assert_1.default)(!!this.configuration);
229
+ /**
230
+ * With this flag you can control how the generator reacts to a reset to the motion trigger.
231
+ * If set to true, the generator will send a proper endOfStream if the motion stops.
232
+ * If set to false, the generator will run till the HomeKit Controller closes the stream.
233
+ *
234
+ * Note: In a real implementation you would most likely introduce a bit of a delay.
235
+ */
236
+ const STOP_AFTER_MOTION_STOP = false;
237
+ this.handlingStreamingRequest = true;
238
+ (0, assert_1.default)(this.configuration.videoCodec.type === 0 /* VideoCodecType.H264 */);
239
+ const profile = this.configuration.videoCodec.parameters.profile === 2 /* H264Profile.HIGH */ ? "high"
240
+ : this.configuration.videoCodec.parameters.profile === 1 /* H264Profile.MAIN */ ? "main" : "baseline";
241
+ const level = this.configuration.videoCodec.parameters.level === 2 /* H264Level.LEVEL4_0 */ ? "4.0"
242
+ : this.configuration.videoCodec.parameters.level === 1 /* H264Level.LEVEL3_2 */ ? "3.2" : "3.1";
243
+ const videoArgs = [
244
+ "-an",
245
+ "-sn",
246
+ "-dn",
247
+ "-codec:v",
248
+ "libx264",
249
+ "-pix_fmt",
250
+ "yuv420p",
251
+ "-profile:v", profile,
252
+ "-level:v", level,
253
+ "-b:v", `${this.configuration.videoCodec.parameters.bitRate}k`,
254
+ "-force_key_frames", `expr:eq(t,n_forced*${this.configuration.videoCodec.parameters.iFrameInterval / 1000})`,
255
+ "-r", this.configuration.videoCodec.resolution[2].toString(),
256
+ ];
257
+ let samplerate;
258
+ switch (this.configuration.audioCodec.samplerate) {
259
+ case 0 /* AudioRecordingSamplerate.KHZ_8 */:
260
+ samplerate = "8";
261
+ break;
262
+ case 1 /* AudioRecordingSamplerate.KHZ_16 */:
263
+ samplerate = "16";
264
+ break;
265
+ case 2 /* AudioRecordingSamplerate.KHZ_24 */:
266
+ samplerate = "24";
267
+ break;
268
+ case 3 /* AudioRecordingSamplerate.KHZ_32 */:
269
+ samplerate = "32";
270
+ break;
271
+ case 4 /* AudioRecordingSamplerate.KHZ_44_1 */:
272
+ samplerate = "44.1";
273
+ break;
274
+ case 5 /* AudioRecordingSamplerate.KHZ_48 */:
275
+ samplerate = "48";
276
+ break;
277
+ default:
278
+ throw new Error("Unsupported audio samplerate: " + this.configuration.audioCodec.samplerate);
279
+ }
280
+ const audioArgs = this.controller?.recordingManagement?.recordingManagementService.getCharacteristic(__1.Characteristic.RecordingAudioActive)
281
+ ? [
282
+ "-acodec", "libfdk_aac",
283
+ ...(this.configuration.audioCodec.type === 0 /* AudioRecordingCodecType.AAC_LC */ ?
284
+ ["-profile:a", "aac_low"] :
285
+ ["-profile:a", "aac_eld"]),
286
+ "-ar", `${samplerate}k`,
287
+ "-b:a", `${this.configuration.audioCodec.bitrate}k`,
288
+ "-ac", `${this.configuration.audioCodec.audioChannels}`,
289
+ ]
290
+ : [];
291
+ this.server = new MP4StreamingServer("ffmpeg", `-f lavfi -i \
292
+ testsrc=s=${this.configuration.videoCodec.resolution[0]}x${this.configuration.videoCodec.resolution[1]}:r=${this.configuration.videoCodec.resolution[2]}`
293
+ .split(/ /g), audioArgs, videoArgs);
294
+ await this.server.start();
295
+ if (!this.server || this.server.destroyed) {
296
+ return; // early exit
297
+ }
298
+ const pending = [];
299
+ try {
300
+ for await (const box of this.server.generator()) {
301
+ pending.push(box.header, box.data);
302
+ const motionDetected = camera.getService(__1.Service.MotionSensor)?.getCharacteristic(__1.Characteristic.MotionDetected).value;
303
+ console.log("mp4 box type " + box.type + " and length " + box.length);
304
+ if (box.type === "moov" || box.type === "mdat") {
305
+ const fragment = Buffer.concat(pending);
306
+ pending.splice(0, pending.length);
307
+ const isLast = STOP_AFTER_MOTION_STOP && !motionDetected;
308
+ yield {
309
+ data: fragment,
310
+ isLast: isLast,
311
+ };
312
+ if (isLast) {
313
+ console.log("Ending session due to motion stopped!");
314
+ break;
315
+ }
365
316
  }
366
- });
367
- });
368
- };
317
+ }
318
+ }
319
+ catch (error) {
320
+ if (!error.message.startsWith("FFMPEG")) { // cheap way of identifying our own emitted errors
321
+ console.error("Encountered unexpected error on generator " + error.stack);
322
+ }
323
+ }
324
+ }
369
325
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
370
- ExampleCamera.prototype.closeRecordingStream = function (streamId, reason) {
326
+ closeRecordingStream(streamId, reason) {
371
327
  if (this.server) {
372
328
  this.server.destroy();
373
329
  this.server = undefined;
374
330
  }
375
331
  this.handlingStreamingRequest = false;
376
- };
377
- ExampleCamera.prototype.acknowledgeStream = function (streamId) {
332
+ }
333
+ acknowledgeStream(streamId) {
378
334
  this.closeRecordingStream(streamId);
379
- };
380
- return ExampleCamera;
381
- }());
382
- var MP4StreamingServer = /** @class */ (function () {
383
- function MP4StreamingServer(ffmpegPath, ffmpegInput, audioOutputArgs, videoOutputArgs) {
384
- var _a, _b, _c;
385
- var _this = this;
386
- /**
387
- * This can be configured to output ffmpeg debug output!
388
- */
389
- this.debugMode = false;
390
- this.destroyed = false;
391
- this.connectPromise = new Promise(function (resolve) { return _this.connectResolve = resolve; });
335
+ }
336
+ }
337
+ class MP4StreamingServer {
338
+ server;
339
+ /**
340
+ * This can be configured to output ffmpeg debug output!
341
+ */
342
+ debugMode = false;
343
+ ffmpegPath;
344
+ args;
345
+ socket;
346
+ childProcess;
347
+ destroyed = false;
348
+ connectPromise;
349
+ connectResolve;
350
+ constructor(ffmpegPath, ffmpegInput, audioOutputArgs, videoOutputArgs) {
351
+ this.connectPromise = new Promise(resolve => this.connectResolve = resolve);
392
352
  this.server = (0, net_1.createServer)(this.handleConnection.bind(this));
393
353
  this.ffmpegPath = ffmpegPath;
394
354
  this.args = [];
395
- (_a = this.args).push.apply(_a, tslib_1.__spreadArray([], tslib_1.__read(ffmpegInput), false));
396
- (_b = this.args).push.apply(_b, tslib_1.__spreadArray([], tslib_1.__read(audioOutputArgs), false));
355
+ this.args.push(...ffmpegInput);
356
+ this.args.push(...audioOutputArgs);
397
357
  this.args.push("-f", "mp4");
398
- (_c = this.args).push.apply(_c, tslib_1.__spreadArray([], tslib_1.__read(videoOutputArgs), false));
358
+ this.args.push(...videoOutputArgs);
399
359
  this.args.push("-fflags", "+genpts", "-reset_timestamps", "1");
400
360
  this.args.push("-movflags", "frag_keyframe+empty_moov+default_base_moof");
401
361
  }
402
- MP4StreamingServer.prototype.start = function () {
403
- return tslib_1.__awaiter(this, void 0, void 0, function () {
404
- var promise, port;
405
- var _a, _b;
406
- return tslib_1.__generator(this, function (_c) {
407
- switch (_c.label) {
408
- case 0:
409
- promise = (0, events_1.once)(this.server, "listening");
410
- this.server.listen(); // listen on random port
411
- return [4 /*yield*/, promise];
412
- case 1:
413
- _c.sent();
414
- if (this.destroyed) {
415
- return [2 /*return*/];
416
- }
417
- port = this.server.address().port;
418
- this.args.push("tcp://127.0.0.1:" + port);
419
- console.log(this.ffmpegPath + " " + this.args.join(" "));
420
- this.childProcess = (0, child_process_1.spawn)(this.ffmpegPath, this.args, { env: process.env, stdio: this.debugMode ? "pipe" : "ignore" });
421
- if (!this.childProcess) {
422
- console.error("ChildProcess is undefined directly after the init!");
423
- }
424
- if (this.debugMode) {
425
- (_a = this.childProcess.stdout) === null || _a === void 0 ? void 0 : _a.on("data", function (data) { return console.log(data.toString()); });
426
- (_b = this.childProcess.stderr) === null || _b === void 0 ? void 0 : _b.on("data", function (data) { return console.log(data.toString()); });
427
- }
428
- return [2 /*return*/];
429
- }
430
- });
431
- });
432
- };
433
- MP4StreamingServer.prototype.destroy = function () {
434
- var _a, _b;
435
- (_a = this.socket) === null || _a === void 0 ? void 0 : _a.destroy();
436
- (_b = this.childProcess) === null || _b === void 0 ? void 0 : _b.kill();
362
+ async start() {
363
+ const promise = (0, events_1.once)(this.server, "listening");
364
+ this.server.listen(); // listen on random port
365
+ await promise;
366
+ if (this.destroyed) {
367
+ return;
368
+ }
369
+ const port = this.server.address().port;
370
+ this.args.push("tcp://127.0.0.1:" + port);
371
+ console.log(this.ffmpegPath + " " + this.args.join(" "));
372
+ this.childProcess = (0, child_process_1.spawn)(this.ffmpegPath, this.args, { env: process.env, stdio: this.debugMode ? "pipe" : "ignore" });
373
+ if (!this.childProcess) {
374
+ console.error("ChildProcess is undefined directly after the init!");
375
+ }
376
+ if (this.debugMode) {
377
+ this.childProcess.stdout?.on("data", data => console.log(data.toString()));
378
+ this.childProcess.stderr?.on("data", data => console.log(data.toString()));
379
+ }
380
+ }
381
+ destroy() {
382
+ this.socket?.destroy();
383
+ this.childProcess?.kill();
437
384
  this.socket = undefined;
438
385
  this.childProcess = undefined;
439
386
  this.destroyed = true;
440
- };
441
- MP4StreamingServer.prototype.handleConnection = function (socket) {
442
- var _a;
387
+ }
388
+ handleConnection(socket) {
443
389
  this.server.close(); // don't accept any further clients
444
390
  this.socket = socket;
445
- (_a = this.connectResolve) === null || _a === void 0 ? void 0 : _a.call(this);
446
- };
391
+ this.connectResolve?.();
392
+ }
447
393
  /**
448
394
  * Generator for `MP4Atom`s.
449
395
  * Throws error to signal EOF when socket is closed.
450
396
  */
451
- MP4StreamingServer.prototype.generator = function () {
452
- return tslib_1.__asyncGenerator(this, arguments, function generator_1() {
453
- var header, length, type, data;
454
- return tslib_1.__generator(this, function (_a) {
455
- switch (_a.label) {
456
- case 0: return [4 /*yield*/, tslib_1.__await(this.connectPromise)];
457
- case 1:
458
- _a.sent();
459
- if (!this.socket || !this.childProcess) {
460
- console.log("Socket undefined " + !!this.socket + " childProcess undefined " + !!this.childProcess);
461
- throw new Error("Unexpected state!");
462
- }
463
- _a.label = 2;
464
- case 2:
465
- if (!true) return [3 /*break*/, 7];
466
- return [4 /*yield*/, tslib_1.__await(this.read(8))];
467
- case 3:
468
- header = _a.sent();
469
- length = header.readInt32BE(0) - 8;
470
- type = header.slice(4).toString();
471
- return [4 /*yield*/, tslib_1.__await(this.read(length))];
472
- case 4:
473
- data = _a.sent();
474
- return [4 /*yield*/, tslib_1.__await({
475
- header: header,
476
- length: length,
477
- type: type,
478
- data: data,
479
- })];
480
- case 5: return [4 /*yield*/, _a.sent()];
481
- case 6:
482
- _a.sent();
483
- return [3 /*break*/, 2];
484
- case 7: return [2 /*return*/];
485
- }
486
- });
487
- });
488
- };
489
- MP4StreamingServer.prototype.read = function (length) {
490
- return tslib_1.__awaiter(this, void 0, void 0, function () {
491
- var value;
492
- var _this = this;
493
- return tslib_1.__generator(this, function (_a) {
494
- if (!this.socket) {
495
- throw Error("FFMPEG tried reading from closed socket!");
496
- }
497
- if (!length) {
498
- return [2 /*return*/, Buffer.alloc(0)];
499
- }
500
- value = this.socket.read(length);
397
+ async *generator() {
398
+ await this.connectPromise;
399
+ if (!this.socket || !this.childProcess) {
400
+ console.log("Socket undefined " + !!this.socket + " childProcess undefined " + !!this.childProcess);
401
+ throw new Error("Unexpected state!");
402
+ }
403
+ while (true) {
404
+ const header = await this.read(8);
405
+ const length = header.readInt32BE(0) - 8;
406
+ const type = header.slice(4).toString();
407
+ const data = await this.read(length);
408
+ yield {
409
+ header: header,
410
+ length: length,
411
+ type: type,
412
+ data: data,
413
+ };
414
+ }
415
+ }
416
+ async read(length) {
417
+ if (!this.socket) {
418
+ throw Error("FFMPEG tried reading from closed socket!");
419
+ }
420
+ if (!length) {
421
+ return Buffer.alloc(0);
422
+ }
423
+ const value = this.socket.read(length);
424
+ if (value) {
425
+ return value;
426
+ }
427
+ return new Promise((resolve, reject) => {
428
+ const readHandler = () => {
429
+ const value = this.socket.read(length);
501
430
  if (value) {
502
- return [2 /*return*/, value];
431
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
432
+ cleanup();
433
+ resolve(value);
503
434
  }
504
- return [2 /*return*/, new Promise(function (resolve, reject) {
505
- var readHandler = function () {
506
- var value = _this.socket.read(length);
507
- if (value) {
508
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
509
- cleanup();
510
- resolve(value);
511
- }
512
- };
513
- var endHandler = function () {
514
- // eslint-disable-next-line @typescript-eslint/no-use-before-define
515
- cleanup();
516
- reject(new Error("FFMPEG socket closed during read for ".concat(length, " bytes!")));
517
- };
518
- var cleanup = function () {
519
- var _a, _b;
520
- (_a = _this.socket) === null || _a === void 0 ? void 0 : _a.removeListener("readable", readHandler);
521
- (_b = _this.socket) === null || _b === void 0 ? void 0 : _b.removeListener("close", endHandler);
522
- };
523
- if (!_this.socket) {
524
- throw new Error("FFMPEG socket is closed now!");
525
- }
526
- _this.socket.on("readable", readHandler);
527
- _this.socket.on("close", endHandler);
528
- })];
529
- });
435
+ };
436
+ const endHandler = () => {
437
+ // eslint-disable-next-line @typescript-eslint/no-use-before-define
438
+ cleanup();
439
+ reject(new Error(`FFMPEG socket closed during read for ${length} bytes!`));
440
+ };
441
+ const cleanup = () => {
442
+ this.socket?.removeListener("readable", readHandler);
443
+ this.socket?.removeListener("close", endHandler);
444
+ };
445
+ if (!this.socket) {
446
+ throw new Error("FFMPEG socket is closed now!");
447
+ }
448
+ this.socket.on("readable", readHandler);
449
+ this.socket.on("close", endHandler);
530
450
  });
531
- };
532
- return MP4StreamingServer;
533
- }());
534
- var streamDelegate = new ExampleCamera();
535
- var cameraController = new __1.CameraController({
451
+ }
452
+ }
453
+ const streamDelegate = new ExampleCamera();
454
+ const cameraController = new __1.CameraController({
536
455
  cameraStreamCount: 2, // HomeKit requires at least 2 streams, but 1 is also just fine
537
456
  delegate: streamDelegate,
538
457
  streamingOptions: {
@@ -619,8 +538,8 @@ camera.configureController(cameraController);
619
538
  // a service to trigger the motion sensor!
620
539
  camera.addService(__1.Service.Switch, "MOTION TRIGGER")
621
540
  .getCharacteristic(__1.Characteristic.On)
622
- .onSet(function (value) {
623
- var _a;
624
- (_a = camera.getService(__1.Service.MotionSensor)) === null || _a === void 0 ? void 0 : _a.updateCharacteristic(__1.Characteristic.MotionDetected, value);
541
+ .onSet(value => {
542
+ camera.getService(__1.Service.MotionSensor)
543
+ ?.updateCharacteristic(__1.Characteristic.MotionDetected, value);
625
544
  });
626
545
  //# sourceMappingURL=Camera_accessory.js.map