@camera.ui/camera-ui-homekit 0.0.2

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 (49) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/CONTRIBUTING.md +1 -0
  3. package/LICENSE.md +22 -0
  4. package/README.md +1 -0
  5. package/config.schema.json +15 -0
  6. package/dist/camera/accessory.d.ts +27 -0
  7. package/dist/camera/accessory.js +327 -0
  8. package/dist/camera/accessory.js.map +1 -0
  9. package/dist/camera/recordingDelegate.d.ts +27 -0
  10. package/dist/camera/recordingDelegate.js +263 -0
  11. package/dist/camera/recordingDelegate.js.map +1 -0
  12. package/dist/camera/services.d.ts +22 -0
  13. package/dist/camera/services.js +171 -0
  14. package/dist/camera/services.js.map +1 -0
  15. package/dist/camera/sessionWrapper.d.ts +25 -0
  16. package/dist/camera/sessionWrapper.js +287 -0
  17. package/dist/camera/sessionWrapper.js.map +1 -0
  18. package/dist/camera/streamingDelegate.d.ts +13 -0
  19. package/dist/camera/streamingDelegate.js +96 -0
  20. package/dist/camera/streamingDelegate.js.map +1 -0
  21. package/dist/camera/streamingServer.d.ts +24 -0
  22. package/dist/camera/streamingServer.js +143 -0
  23. package/dist/camera/streamingServer.js.map +1 -0
  24. package/dist/crypto.d.ts +1 -0
  25. package/dist/crypto.js +29 -0
  26. package/dist/crypto.js.map +1 -0
  27. package/dist/index.d.ts +19 -0
  28. package/dist/index.js +57 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/types.d.ts +10 -0
  31. package/dist/types.js +2 -0
  32. package/dist/types.js.map +1 -0
  33. package/dist/utils/codecs.d.ts +1 -0
  34. package/dist/utils/codecs.js +2 -0
  35. package/dist/utils/codecs.js.map +1 -0
  36. package/dist/utils/ffmpeg.d.ts +11 -0
  37. package/dist/utils/ffmpeg.js +66 -0
  38. package/dist/utils/ffmpeg.js.map +1 -0
  39. package/dist/utils/mac.d.ts +4 -0
  40. package/dist/utils/mac.js +19 -0
  41. package/dist/utils/mac.js.map +1 -0
  42. package/dist/utils/opus-repacketizer.d.ts +7 -0
  43. package/dist/utils/opus-repacketizer.js +163 -0
  44. package/dist/utils/opus-repacketizer.js.map +1 -0
  45. package/media/cameraOffline.png +0 -0
  46. package/media/maxStreams.png +0 -0
  47. package/media/noSnapshot.png +0 -0
  48. package/media/privacyMode.png +0 -0
  49. package/package.json +62 -0
@@ -0,0 +1,263 @@
1
+ import { Characteristic, Service } from 'hap-nodejs';
2
+ import { checkMp4StartsWithKeyFrame } from '../utils/ffmpeg.js';
3
+ import { MP4StreamingServer } from './streamingServer.js';
4
+ export class RecordingDelegate {
5
+ cameraAccessory;
6
+ accessory;
7
+ cameraDevice;
8
+ logger;
9
+ isRecording = false;
10
+ handlingRecordingRequest = false;
11
+ maxVideoDuration = 3 * 60 * 1000;
12
+ recordingTimeout;
13
+ server;
14
+ configuration;
15
+ constructor(cameraAccessory, accessory, cameraDevice, logger) {
16
+ this.cameraAccessory = cameraAccessory;
17
+ this.accessory = accessory;
18
+ this.cameraDevice = cameraDevice;
19
+ this.logger = logger;
20
+ }
21
+ async updateRecordingActive(active) {
22
+ this.logger.debug(this.cameraDevice.name, `Recording active: ${active}`);
23
+ if (!active) {
24
+ this.accessory.getService(Service.MotionSensor)?.getCharacteristic(Characteristic.MotionDetected).updateValue(false);
25
+ }
26
+ this.isRecording = active;
27
+ }
28
+ updateRecordingConfiguration(configuration) {
29
+ this.logger.debug(this.cameraDevice.name, 'Recording configuration updated:', JSON.stringify(configuration));
30
+ this.configuration = configuration;
31
+ }
32
+ async *handleRecordingStreamRequest(streamId) {
33
+ if (!this.configuration) {
34
+ this.logger.warn(this.cameraDevice.name, 'Recording configuration is not set, cannot start recording stream!');
35
+ return;
36
+ }
37
+ if (this.handlingRecordingRequest) {
38
+ this.logger.warn(this.cameraDevice.name, 'Already handling a recording stream request, cannot start another one!');
39
+ return;
40
+ }
41
+ this.logger.log(this.cameraDevice.name, `Starting motion recording stream for stream ID "${streamId}"`);
42
+ this.handlingRecordingRequest = true;
43
+ this.server = new MP4StreamingServer(this.logger, this.accessory, this.cameraDevice);
44
+ const ffmpegPath = await this.cameraDevice.getFfmpegPath();
45
+ const mp4PrebufferingState = this.cameraDevice.streamSource.getPrebufferingState('mp4');
46
+ const mpegtsPrebufferingState = this.cameraDevice.streamSource.getPrebufferingState('mpegts');
47
+ const isMP4Server = mp4PrebufferingState.state && mp4PrebufferingState.url;
48
+ if (!mp4PrebufferingState.state && !this.cameraDevice.isCloud) {
49
+ this.logger.attention(this.cameraDevice.name, 'Prebuffering is not enabled! Please install and enable the prebuffering plugin.');
50
+ }
51
+ if (isMP4Server) {
52
+ await this.server.connectToServer(mp4PrebufferingState.url);
53
+ }
54
+ else {
55
+ const streamInfo = await this.cameraDevice.streamSource.getStreamInfo();
56
+ const cameraAudioEnabled = streamInfo?.audio.enabled !== undefined ? streamInfo.audio.enabled : true;
57
+ const recordingAudioEnabled = this.cameraAccessory.controller?.recordingManagement?.recordingManagementService.getCharacteristic(Characteristic.RecordingAudioActive).value === 1;
58
+ const audioEnabled = cameraAudioEnabled && recordingAudioEnabled;
59
+ const isAAC = streamInfo?.audio.codec ? streamInfo.audio.codec.toLowerCase().indexOf('aac') !== -1 : true;
60
+ const transcodeRecording = await this.cameraAccessory.cameraStorage?.getValue('transcodeRecording');
61
+ const request = {
62
+ audio: {
63
+ codec: this.configuration.audioCodec.type === 0 /* AudioRecordingCodecType.AAC_LC */ ? 'aac' : 'libfdk_aac',
64
+ sampleRate: this.getSampleRate(this.configuration.audioCodec.samplerate),
65
+ channels: this.configuration.audioCodec.audioChannels,
66
+ bitrate: this.configuration.audioCodec.bitrate,
67
+ },
68
+ video: {
69
+ width: this.configuration.videoCodec.resolution[0],
70
+ height: this.configuration.videoCodec.resolution[1],
71
+ fps: this.configuration.videoCodec.resolution[2],
72
+ bitrate: this.configuration.videoCodec.parameters.bitRate,
73
+ iFrameInterval: this.configuration.videoCodec.parameters.iFrameInterval / 1000,
74
+ profile: this.getProfile(this.configuration.videoCodec.parameters.profile),
75
+ level: this.getLevel(this.configuration.videoCodec.parameters.level),
76
+ },
77
+ };
78
+ const ffmpegInput = ['-hide_banner', '-v', 'error', '-fflags', 'nobuffer', '-flags', 'low_delay', '-timeout', '5000000', '-fflags', '+genpts'];
79
+ if (mpegtsPrebufferingState.state) {
80
+ ffmpegInput.push('-f', 'mpegts', '-re', '-i', mpegtsPrebufferingState.url);
81
+ }
82
+ else {
83
+ ffmpegInput.push('-rtsp_transport', 'tcp', '-re', '-i', this.cameraDevice.streamSource.urls.transcoded.aac);
84
+ }
85
+ const videoArgs = [];
86
+ const audioArgs = [];
87
+ if (transcodeRecording) {
88
+ videoArgs.push(
89
+ // '-an',
90
+ '-sn', '-dn', '-codec:v', 'libx264', '-pix_fmt', 'yuv420p', '-profile:v', request.video.profile, '-level:v', request.video.level, '-preset', 'ultrafast', '-bf', '0', '-filter_complex', `scale=w='min(${request.video.width},iw)':h=-2`, '-b:v', `${request.video.bitrate}k`, '-bufsize', `${2 * request.video.bitrate}k`, '-maxrate', `${request.video.bitrate}k`,
91
+ // '-force_key_frames', `expr:gte(t,n_forced*${request.video.iFrameInterval})`,
92
+ '-g', `${request.video.iFrameInterval * request.video.fps}`, '-r', `${request.video.fps}`);
93
+ }
94
+ else {
95
+ videoArgs.push('-vcodec', 'copy');
96
+ }
97
+ if (audioEnabled) {
98
+ if (!isAAC) {
99
+ this.logger.warn(this.cameraDevice.name, 'Recording audio is not explicitly AAC, forcing transcoding. Setting audio output to AAC is recommended.');
100
+ audioArgs.push(...(request.audio.codec === 'aac' ? ['-acodec', request.audio.codec, '-profile:a', 'aac_low'] : ['-acodec', request.audio.codec, '-profile:a', 'aac_eld']), '-ar', `${request.audio.sampleRate}k`, '-b:a', `${request.audio.bitrate}k`, '-ac', `${request.audio.channels}`);
101
+ }
102
+ else {
103
+ audioArgs.push('-acodec', 'copy', '-bsf:a', 'aac_adtstoasc');
104
+ }
105
+ }
106
+ await this.server.createServer(ffmpegPath, ffmpegInput, videoArgs, audioArgs);
107
+ }
108
+ if (!this.server || this.server.destroyed) {
109
+ this.logger.warn(this.cameraDevice.name, 'Server was destroyed, cannot start recording stream!');
110
+ await this.cleanupRecording();
111
+ return;
112
+ }
113
+ let segment = 0;
114
+ let isLastSegment = false;
115
+ // let headerData: Buffer[] | undefined;
116
+ this.recordingTimeout = setTimeout(() => {
117
+ this.logger.warn(this.cameraDevice.name, 'Max recording duration reached!');
118
+ isLastSegment = true;
119
+ }, this.maxVideoDuration);
120
+ try {
121
+ let checkMp4 = !isMP4Server;
122
+ let needSkip = true;
123
+ let pending = [];
124
+ let ftyp;
125
+ let moov;
126
+ for await (const box of this.server.generator()) {
127
+ const { header, type, data } = box;
128
+ // if (checkMp4 && !ftyp && type === 'ftyp') {
129
+ // headerData = ftyp = [header, data];
130
+ // }
131
+ if (checkMp4 && !moov && type === 'moov') {
132
+ moov = [header, data];
133
+ }
134
+ if (type === 'mdat' && checkMp4) {
135
+ checkMp4 = false;
136
+ try {
137
+ const mp4Buffer = Buffer.concat([...ftyp, ...moov, ...pending, header, data]);
138
+ const mp4StartsWithKeyFrame = await checkMp4StartsWithKeyFrame(mp4Buffer, ffmpegPath);
139
+ if (!mp4StartsWithKeyFrame) {
140
+ this.logger.debug(this.cameraDevice.name, 'MP4 fragment does not start with keyframe, skipping...');
141
+ needSkip = false;
142
+ pending = [];
143
+ continue;
144
+ }
145
+ }
146
+ finally {
147
+ ftyp = undefined;
148
+ moov = undefined;
149
+ }
150
+ }
151
+ pending.push(header, data);
152
+ if (type === 'moov' || type === 'mdat') {
153
+ if (type === 'mdat' && needSkip) {
154
+ pending = [];
155
+ needSkip = false;
156
+ continue;
157
+ }
158
+ const fragment = Buffer.concat(pending);
159
+ pending = [];
160
+ this.logger.debug(this.cameraDevice.name, `Motion fragment #${++segment} sent. Size:`, fragment.length);
161
+ yield {
162
+ data: fragment,
163
+ isLast: isLastSegment,
164
+ };
165
+ if (isLastSegment) {
166
+ break;
167
+ }
168
+ }
169
+ }
170
+ }
171
+ catch (error) {
172
+ if (!error.message.startsWith('FFMPEG')) {
173
+ this.logger.error(this.cameraDevice.name, 'Encountered unexpected error on generator. Error:', error.message);
174
+ }
175
+ else {
176
+ this.logger.debug(this.cameraDevice.name, `Recording completed ${error}`);
177
+ }
178
+ }
179
+ finally {
180
+ await this.cleanupRecording();
181
+ }
182
+ }
183
+ async closeRecordingStream(streamId, reason) {
184
+ this.logger.log(this.cameraDevice.name, `Closing recording stream with ID "${streamId}". Reason: ${this.getHdsReason(reason)}`);
185
+ await this.cleanupRecording();
186
+ }
187
+ async acknowledgeStream(streamId) {
188
+ this.logger.log(this.cameraDevice.name, `Last packet of stream with ID "${streamId}" acknowledged`);
189
+ await this.closeRecordingStream(streamId, 0 /* HDSProtocolSpecificErrorReason.NORMAL */);
190
+ }
191
+ async cleanupRecording() {
192
+ clearTimeout(this.recordingTimeout);
193
+ this.recordingTimeout = undefined;
194
+ await this.server?.destroy();
195
+ this.server = undefined;
196
+ this.handlingRecordingRequest = false;
197
+ }
198
+ getSampleRate(samplerate) {
199
+ switch (samplerate) {
200
+ case 0 /* AudioRecordingSamplerate.KHZ_8 */:
201
+ return '8';
202
+ case 1 /* AudioRecordingSamplerate.KHZ_16 */:
203
+ return '16';
204
+ case 2 /* AudioRecordingSamplerate.KHZ_24 */:
205
+ return '24';
206
+ case 3 /* AudioRecordingSamplerate.KHZ_32 */:
207
+ return '32';
208
+ case 4 /* AudioRecordingSamplerate.KHZ_44_1 */:
209
+ return '44.1';
210
+ case 5 /* AudioRecordingSamplerate.KHZ_48 */:
211
+ return '48';
212
+ default:
213
+ throw new Error('Unsupported audio samplerate: ' + samplerate);
214
+ }
215
+ }
216
+ getProfile(profile) {
217
+ switch (profile) {
218
+ case 0 /* H264Profile.BASELINE */:
219
+ return 'baseline';
220
+ case 1 /* H264Profile.MAIN */:
221
+ return 'main';
222
+ case 2 /* H264Profile.HIGH */:
223
+ return 'high';
224
+ }
225
+ }
226
+ getLevel(level) {
227
+ switch (level) {
228
+ case 0 /* H264Level.LEVEL3_1 */:
229
+ return '3.1';
230
+ case 1 /* H264Level.LEVEL3_2 */:
231
+ return '3.2';
232
+ case 2 /* H264Level.LEVEL4_0 */:
233
+ return '4.0';
234
+ }
235
+ }
236
+ getHdsReason(reason) {
237
+ switch (reason) {
238
+ case 7 /* HDSProtocolSpecificErrorReason.BAD_DATA */:
239
+ return 'Bad Data';
240
+ case 2 /* HDSProtocolSpecificErrorReason.BUSY */:
241
+ return 'Busy';
242
+ case 3 /* HDSProtocolSpecificErrorReason.CANCELLED */:
243
+ return 'Cancelled';
244
+ case 9 /* HDSProtocolSpecificErrorReason.INVALID_CONFIGURATION */:
245
+ return 'Invalid Configuration';
246
+ case 0 /* HDSProtocolSpecificErrorReason.NORMAL */:
247
+ return 'Normal';
248
+ case 1 /* HDSProtocolSpecificErrorReason.NOT_ALLOWED */:
249
+ return 'Not Allowed';
250
+ case 8 /* HDSProtocolSpecificErrorReason.PROTOCOL_ERROR */:
251
+ return 'Protocol Error';
252
+ case 6 /* HDSProtocolSpecificErrorReason.TIMEOUT */:
253
+ return 'Timeout';
254
+ case 5 /* HDSProtocolSpecificErrorReason.UNEXPECTED_FAILURE */:
255
+ return 'Unexpected Failure';
256
+ case 4 /* HDSProtocolSpecificErrorReason.UNSUPPORTED */:
257
+ return 'Unsupported';
258
+ default:
259
+ return 'Unknown';
260
+ }
261
+ }
262
+ }
263
+ //# sourceMappingURL=recordingDelegate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recordingDelegate.js","sourceRoot":"","sources":["../../src/camera/recordingDelegate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { Service } from 'hap-nodejs';
2
+ import type { CameraDevice, PluginLogger } from '@camera.ui/types';
3
+ import type { Accessory } from 'hap-nodejs';
4
+ export declare class CameraServices {
5
+ services: Service[];
6
+ private accessory;
7
+ private cameraDevice;
8
+ private logger;
9
+ private onMotionDetected?;
10
+ private onDoorbellPressed?;
11
+ private onLightSwitched?;
12
+ private onBatteryChanged?;
13
+ constructor(accessory: Accessory, cameraDevice: CameraDevice, logger: PluginLogger);
14
+ addServices(): void;
15
+ private addBatteryService;
16
+ private removeBatteryService;
17
+ private addMotionService;
18
+ private addDoorbellService;
19
+ private removeDoorbellService;
20
+ private addLightService;
21
+ private removeLightService;
22
+ }
@@ -0,0 +1,171 @@
1
+ import { Characteristic, Service } from 'hap-nodejs';
2
+ export class CameraServices {
3
+ services = [];
4
+ accessory;
5
+ cameraDevice;
6
+ logger;
7
+ onMotionDetected;
8
+ onDoorbellPressed;
9
+ onLightSwitched;
10
+ onBatteryChanged;
11
+ constructor(accessory, cameraDevice, logger) {
12
+ this.accessory = accessory;
13
+ this.cameraDevice = cameraDevice;
14
+ this.logger = logger;
15
+ this.cameraDevice.onPropertyChange('hasMotionDetector').subscribe(({ newData }) => {
16
+ // if (newData) {
17
+ // this.addMotionService();
18
+ // } else {
19
+ // this.removeMotionService();
20
+ // }
21
+ if (!newData) {
22
+ this.accessory.getService(Service.MotionSensor)?.getCharacteristic(Characteristic.MotionDetected).updateValue(false);
23
+ }
24
+ });
25
+ this.cameraDevice.onPropertyChange('hasLight').subscribe(({ newData }) => {
26
+ if (newData) {
27
+ this.addLightService();
28
+ }
29
+ else {
30
+ this.removeLightService();
31
+ }
32
+ });
33
+ this.cameraDevice.onPropertyChange('hasBinarySensor').subscribe(({ newData }) => {
34
+ if (newData) {
35
+ this.addDoorbellService();
36
+ }
37
+ else {
38
+ this.removeDoorbellService();
39
+ }
40
+ });
41
+ this.cameraDevice.onPropertyChange('hasBattery').subscribe(({ newData }) => {
42
+ if (newData) {
43
+ this.addBatteryService();
44
+ }
45
+ else {
46
+ this.removeBatteryService();
47
+ }
48
+ });
49
+ this.addServices();
50
+ }
51
+ addServices() {
52
+ this.logger.debug(this.cameraDevice.name, 'Adding services');
53
+ this.addMotionService();
54
+ this.addDoorbellService();
55
+ this.addLightService();
56
+ this.addBatteryService();
57
+ }
58
+ addBatteryService() {
59
+ let batteryService = this.accessory.getService(Service.Battery);
60
+ if (!batteryService && this.cameraDevice.hasBattery) {
61
+ this.logger.debug(this.cameraDevice.name, 'Adding battery service');
62
+ batteryService = this.accessory.addService(Service.Battery, 'Battery');
63
+ if (!batteryService.testCharacteristic(Characteristic.BatteryLevel)) {
64
+ batteryService.addCharacteristic(Characteristic.BatteryLevel);
65
+ }
66
+ if (!batteryService.testCharacteristic(Characteristic.ChargingState)) {
67
+ batteryService.addCharacteristic(Characteristic.ChargingState);
68
+ }
69
+ batteryService.getCharacteristic(Characteristic.BatteryLevel).on('change', (change) => {
70
+ this.logger.debug(this.cameraDevice.name, 'Battery level changed to', change.newValue);
71
+ });
72
+ batteryService.getCharacteristic(Characteristic.StatusLowBattery).on('change', (change) => {
73
+ this.logger.debug(this.cameraDevice.name, 'Battery state changed to', change.newValue);
74
+ });
75
+ batteryService.getCharacteristic(Characteristic.ChargingState).on('change', (change) => {
76
+ this.logger.debug(this.cameraDevice.name, 'Battery charging state changed to', change.newValue);
77
+ });
78
+ this.onBatteryChanged = this.cameraDevice.onBatteryChanged.subscribe(({ level, lowBattery, charging }) => {
79
+ const low = lowBattery || level <= 10 ? Characteristic.StatusLowBattery.BATTERY_LEVEL_LOW : Characteristic.StatusLowBattery.BATTERY_LEVEL_NORMAL;
80
+ const charg = charging === true ? Characteristic.ChargingState.CHARGING : Characteristic.ChargingState.NOT_CHARGING;
81
+ batteryService?.getCharacteristic(Characteristic.BatteryLevel).updateValue(level);
82
+ batteryService?.getCharacteristic(Characteristic.StatusLowBattery).updateValue(low);
83
+ batteryService?.getCharacteristic(Characteristic.ChargingState).updateValue(charg);
84
+ });
85
+ this.services.push(batteryService);
86
+ }
87
+ }
88
+ removeBatteryService() {
89
+ const batteryService = this.accessory.getService(Service.Battery);
90
+ if (batteryService) {
91
+ this.logger.debug(this.cameraDevice.name, 'Removing battery service');
92
+ this.onBatteryChanged?.unsubscribe();
93
+ this.accessory.removeService(batteryService);
94
+ this.services = this.services.filter((service) => service.UUID !== batteryService.UUID);
95
+ }
96
+ }
97
+ addMotionService() {
98
+ let motionService = this.accessory.getService(Service.MotionSensor);
99
+ // if (!motionService && this.cameraDevice.hasMotionDetector) {
100
+ if (!motionService) {
101
+ this.logger.debug(this.cameraDevice.name, 'Adding motion service');
102
+ motionService = this.accessory.addService(Service.MotionSensor, 'Motion Sensor');
103
+ motionService.getCharacteristic(Characteristic.MotionDetected).on('change', (change) => {
104
+ this.logger.debug(this.cameraDevice.name, 'Motion state changed to', change.newValue);
105
+ });
106
+ this.onMotionDetected = this.cameraDevice.onMotionDetected.subscribe(({ state, detections }) => {
107
+ const detected = state || detections.length > 0;
108
+ motionService?.getCharacteristic(Characteristic.MotionDetected).updateValue(detected);
109
+ });
110
+ this.services.push(motionService);
111
+ }
112
+ }
113
+ // private removeMotionService(): void {
114
+ // const motionService = this.accessory.getService(Service.MotionSensor);
115
+ // if (motionService) {
116
+ // this.logger.debug(this.cameraDevice.name, 'Removing motion service');
117
+ // this.onMotionDetected?.unsubscribe();
118
+ // this.accessory.removeService(motionService);
119
+ // this.services = this.services.filter((service) => service.UUID !== motionService.UUID);
120
+ // }
121
+ // }
122
+ addDoorbellService() {
123
+ let doorbellService = this.accessory.getService(Service.Doorbell);
124
+ if (!doorbellService && this.cameraDevice.hasBinarySensor) {
125
+ this.logger.debug(this.cameraDevice.name, 'Adding doorbell service');
126
+ doorbellService = this.accessory.addService(Service.Doorbell, 'Doorbell');
127
+ doorbellService.getCharacteristic(Characteristic.ProgrammableSwitchEvent).on('change', (change) => {
128
+ this.logger.debug(this.cameraDevice.name, 'Doorbell state changed to', change.newValue);
129
+ });
130
+ this.onDoorbellPressed = this.cameraDevice.onDoorbellPressed.subscribe(({ state }) => {
131
+ if (state) {
132
+ doorbellService?.getCharacteristic(Characteristic.ProgrammableSwitchEvent).updateValue(Characteristic.ProgrammableSwitchEvent.SINGLE_PRESS);
133
+ }
134
+ });
135
+ this.services.push(doorbellService);
136
+ }
137
+ }
138
+ removeDoorbellService() {
139
+ const doorbellService = this.accessory.getService(Service.Doorbell);
140
+ if (doorbellService) {
141
+ this.logger.debug(this.cameraDevice.name, 'Removing doorbell service');
142
+ this.onDoorbellPressed?.unsubscribe();
143
+ this.accessory.removeService(doorbellService);
144
+ this.services = this.services.filter((service) => service.UUID !== doorbellService.UUID);
145
+ }
146
+ }
147
+ addLightService() {
148
+ let lightService = this.accessory.getService(Service.Lightbulb);
149
+ if (!lightService && this.cameraDevice.hasLight) {
150
+ this.logger.debug(this.cameraDevice.name, 'Adding light service');
151
+ lightService = this.accessory.addService(Service.Lightbulb, 'Light');
152
+ lightService.getCharacteristic(Characteristic.On).on('change', (change) => {
153
+ this.logger.debug(this.cameraDevice.name, 'Light state changed to', change.newValue);
154
+ });
155
+ this.onLightSwitched = this.cameraDevice.onLightSwitched.subscribe(({ state }) => {
156
+ lightService?.getCharacteristic(Characteristic.On).updateValue(state);
157
+ });
158
+ this.services.push(lightService);
159
+ }
160
+ }
161
+ removeLightService() {
162
+ const lightService = this.accessory.getService(Service.Lightbulb);
163
+ if (lightService) {
164
+ this.logger.debug(this.cameraDevice.name, 'Removing light service');
165
+ this.onLightSwitched?.unsubscribe();
166
+ this.accessory.removeService(lightService);
167
+ this.services = this.services.filter((service) => service.UUID !== lightService.UUID);
168
+ }
169
+ }
170
+ }
171
+ //# sourceMappingURL=services.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"services.js","sourceRoot":"","sources":["../../src/camera/services.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import { RtpSplitter } from '@homebridge/camera-utils';
2
+ import type { CameraDevice, PluginLogger, WeriftSession } from '@camera.ui/types';
3
+ import type { SrtpOptions } from '@homebridge/camera-utils';
4
+ import type { PrepareStreamRequest, StartStreamRequest } from 'hap-nodejs';
5
+ import type { CameraAccessory } from './accessory.js';
6
+ export declare class StreamingSessionWrapper {
7
+ start: number;
8
+ audioSsrc: number;
9
+ videoSsrc: number;
10
+ audioSrtp: SrtpOptions;
11
+ videoSrtp: SrtpOptions;
12
+ audioSplitter: RtpSplitter;
13
+ videoSplitter: RtpSplitter;
14
+ private cameraAccessory;
15
+ private cameraDevice;
16
+ private streamingSession;
17
+ private prepareStreamRequest;
18
+ private logger;
19
+ private repacketizeAudioSplitter;
20
+ constructor(cameraAccessory: CameraAccessory, cameraDevice: CameraDevice, streamingSession: WeriftSession, prepareStreamRequest: PrepareStreamRequest, start: number, logger: PluginLogger);
21
+ activate(request: StartStreamRequest): Promise<void>;
22
+ stop(): void;
23
+ private listenForAudioPackets;
24
+ private libfdkAacInstalledPromise;
25
+ }