@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.
- package/CHANGELOG.md +8 -0
- package/CONTRIBUTING.md +1 -0
- package/LICENSE.md +22 -0
- package/README.md +1 -0
- package/config.schema.json +15 -0
- package/dist/camera/accessory.d.ts +27 -0
- package/dist/camera/accessory.js +327 -0
- package/dist/camera/accessory.js.map +1 -0
- package/dist/camera/recordingDelegate.d.ts +27 -0
- package/dist/camera/recordingDelegate.js +263 -0
- package/dist/camera/recordingDelegate.js.map +1 -0
- package/dist/camera/services.d.ts +22 -0
- package/dist/camera/services.js +171 -0
- package/dist/camera/services.js.map +1 -0
- package/dist/camera/sessionWrapper.d.ts +25 -0
- package/dist/camera/sessionWrapper.js +287 -0
- package/dist/camera/sessionWrapper.js.map +1 -0
- package/dist/camera/streamingDelegate.d.ts +13 -0
- package/dist/camera/streamingDelegate.js +96 -0
- package/dist/camera/streamingDelegate.js.map +1 -0
- package/dist/camera/streamingServer.d.ts +24 -0
- package/dist/camera/streamingServer.js +143 -0
- package/dist/camera/streamingServer.js.map +1 -0
- package/dist/crypto.d.ts +1 -0
- package/dist/crypto.js +29 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +57 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/codecs.d.ts +1 -0
- package/dist/utils/codecs.js +2 -0
- package/dist/utils/codecs.js.map +1 -0
- package/dist/utils/ffmpeg.d.ts +11 -0
- package/dist/utils/ffmpeg.js +66 -0
- package/dist/utils/ffmpeg.js.map +1 -0
- package/dist/utils/mac.d.ts +4 -0
- package/dist/utils/mac.js +19 -0
- package/dist/utils/mac.js.map +1 -0
- package/dist/utils/opus-repacketizer.d.ts +7 -0
- package/dist/utils/opus-repacketizer.js +163 -0
- package/dist/utils/opus-repacketizer.js.map +1 -0
- package/media/cameraOffline.png +0 -0
- package/media/maxStreams.png +0 -0
- package/media/noSnapshot.png +0 -0
- package/media/privacyMode.png +0 -0
- package/package.json +62 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import './crypto';
|
|
2
|
+
import type { BasePlugin, CameraDevice, FormSubmitResponse, PluginAPI, PluginLogger } from '@camera.ui/types';
|
|
3
|
+
import type { Accessory, MacAddress } from 'hap-nodejs';
|
|
4
|
+
import type { Config } from './types.js';
|
|
5
|
+
export default class HomeKit implements BasePlugin {
|
|
6
|
+
config: Config;
|
|
7
|
+
publishedExternalAccessories: Map<MacAddress, Accessory>;
|
|
8
|
+
logger: PluginLogger;
|
|
9
|
+
api: PluginAPI;
|
|
10
|
+
private readonly cameras;
|
|
11
|
+
private accessories;
|
|
12
|
+
constructor(logger: PluginLogger, api: PluginAPI);
|
|
13
|
+
configureCameras(cameras: CameraDevice[]): void;
|
|
14
|
+
onFormSubmit(actionId: string, payload: any): Promise<FormSubmitResponse | void>;
|
|
15
|
+
private start;
|
|
16
|
+
private stop;
|
|
17
|
+
private configureCamera;
|
|
18
|
+
private removeCamera;
|
|
19
|
+
}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import './crypto';
|
|
2
|
+
import { HAPStorage } from 'hap-nodejs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { CameraAccessory } from './camera/accessory.js';
|
|
5
|
+
export default class HomeKit {
|
|
6
|
+
config;
|
|
7
|
+
publishedExternalAccessories = new Map();
|
|
8
|
+
logger;
|
|
9
|
+
api;
|
|
10
|
+
cameras = new Map();
|
|
11
|
+
accessories = new Map();
|
|
12
|
+
constructor(logger, api) {
|
|
13
|
+
this.logger = logger;
|
|
14
|
+
this.api = api;
|
|
15
|
+
this.config = api.configService.all();
|
|
16
|
+
this.config.advertiser = api.configService.get('advertiser', "ciao" /* MDNSAdvertiser.CIAO */, (value) => ["ciao" /* MDNSAdvertiser.CIAO */, "bonjour-hap" /* MDNSAdvertiser.BONJOUR */, "avahi" /* MDNSAdvertiser.AVAHI */, "resolved" /* MDNSAdvertiser.RESOLVED */].includes(value), false, true);
|
|
17
|
+
HAPStorage.setCustomStoragePath(resolve(this.api.storagePath, 'accessories'));
|
|
18
|
+
this.logger.debug('Configured mDNS advertiser:', this.config.advertiser);
|
|
19
|
+
this.api.on('finishLaunching', this.start.bind(this));
|
|
20
|
+
this.api.on('shutdown', this.stop.bind(this));
|
|
21
|
+
}
|
|
22
|
+
configureCameras(cameras) {
|
|
23
|
+
for (const camera of cameras) {
|
|
24
|
+
this.configureCamera(camera);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
28
|
+
async onFormSubmit(actionId, payload) { }
|
|
29
|
+
async start() {
|
|
30
|
+
this.api.deviceManager.on('cameraSelected', async (cameraDevice) => {
|
|
31
|
+
await this.configureCamera(cameraDevice);
|
|
32
|
+
});
|
|
33
|
+
this.api.deviceManager.on('cameraDeselected', async (cameraId) => {
|
|
34
|
+
await this.removeCamera(cameraId);
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
async stop() {
|
|
38
|
+
await Promise.all(Array.from(this.accessories.values()).map((accessory) => accessory.teardown()));
|
|
39
|
+
}
|
|
40
|
+
async configureCamera(cameraDevice) {
|
|
41
|
+
this.logger.log('Configuring camera:', cameraDevice.name);
|
|
42
|
+
const cameraAccessory = new CameraAccessory(this, cameraDevice);
|
|
43
|
+
this.cameras.set(cameraDevice.id, cameraDevice);
|
|
44
|
+
this.accessories.set(cameraDevice.id, cameraAccessory);
|
|
45
|
+
}
|
|
46
|
+
async removeCamera(cameraId) {
|
|
47
|
+
const cameraDevice = this.cameras.get(cameraId);
|
|
48
|
+
if (cameraDevice) {
|
|
49
|
+
this.logger.log('Removing camera:', cameraDevice.name);
|
|
50
|
+
await this.accessories.get(cameraId)?.teardown();
|
|
51
|
+
this.cameras.delete(cameraId);
|
|
52
|
+
this.accessories.delete(cameraId);
|
|
53
|
+
this.api.storageController.removeCameraStorage(cameraId);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const baseAudioCodecs: string[];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../src/utils/codecs.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const NAL_TYPE_STAP_A = 24;
|
|
2
|
+
export declare const NAL_TYPE_FU_A = 28;
|
|
3
|
+
export declare const NAL_TYPE_NON_IDR = 1;
|
|
4
|
+
export declare const NAL_TYPE_IDR = 5;
|
|
5
|
+
export declare const NAL_TYPE_SEI = 6;
|
|
6
|
+
export declare const NAL_TYPE_SPS = 7;
|
|
7
|
+
export declare const NAL_TYPE_PPS = 8;
|
|
8
|
+
export declare const NAL_TYPE_DELIMITER = 9;
|
|
9
|
+
export declare const allowedNaluTypes: number[];
|
|
10
|
+
export declare function timeoutPromise<T>(timeout: number, promise: Promise<T>): Promise<T>;
|
|
11
|
+
export declare function checkMp4StartsWithKeyFrame(mp4: Buffer, ffmpegPath: string): Promise<boolean>;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { spawn } from 'node:child_process';
|
|
2
|
+
// https://yumichan.net/video-processing/video-compression/introduction-to-h264-nal-unit/
|
|
3
|
+
export const NAL_TYPE_STAP_A = 24;
|
|
4
|
+
export const NAL_TYPE_FU_A = 28;
|
|
5
|
+
export const NAL_TYPE_NON_IDR = 1;
|
|
6
|
+
export const NAL_TYPE_IDR = 5;
|
|
7
|
+
export const NAL_TYPE_SEI = 6;
|
|
8
|
+
export const NAL_TYPE_SPS = 7;
|
|
9
|
+
export const NAL_TYPE_PPS = 8;
|
|
10
|
+
export const NAL_TYPE_DELIMITER = 9;
|
|
11
|
+
export const allowedNaluTypes = [NAL_TYPE_STAP_A, NAL_TYPE_SPS, NAL_TYPE_PPS, NAL_TYPE_SEI, NAL_TYPE_DELIMITER];
|
|
12
|
+
export function timeoutPromise(timeout, promise) {
|
|
13
|
+
return new Promise((resolve, reject) => {
|
|
14
|
+
const t = setTimeout(() => reject(new Error('Operation timed out')), timeout);
|
|
15
|
+
promise
|
|
16
|
+
.then((v) => {
|
|
17
|
+
clearTimeout(t);
|
|
18
|
+
resolve(v);
|
|
19
|
+
})
|
|
20
|
+
.catch((e) => {
|
|
21
|
+
clearTimeout(t);
|
|
22
|
+
reject(e);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
export async function checkMp4StartsWithKeyFrame(mp4, ffmpegPath) {
|
|
27
|
+
const cp = spawn(ffmpegPath, ['-hide_banner', '-f', 'mp4', '-i', 'pipe:3', '-vcodec', 'copy', '-f', 'h264', 'pipe:4'], {
|
|
28
|
+
stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
|
|
29
|
+
});
|
|
30
|
+
const input = cp.stdio[3];
|
|
31
|
+
const output = cp.stdio[4];
|
|
32
|
+
const buffers = [];
|
|
33
|
+
input.write(mp4);
|
|
34
|
+
input.end();
|
|
35
|
+
output.on('data', (data) => buffers.push(data));
|
|
36
|
+
try {
|
|
37
|
+
await timeoutPromise(1000, new Promise((resolve) => cp.on('exit', resolve)));
|
|
38
|
+
const h264 = Buffer.concat(buffers);
|
|
39
|
+
let offset = 0;
|
|
40
|
+
while (offset < h264.length - 6) {
|
|
41
|
+
if (h264.readInt32BE(offset) !== 1) {
|
|
42
|
+
offset++;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
offset += 4;
|
|
46
|
+
let naluType = h264.readUInt8(offset) & 0x1f;
|
|
47
|
+
if (naluType === NAL_TYPE_FU_A) {
|
|
48
|
+
offset++;
|
|
49
|
+
naluType = h264.readUInt8(offset) & 0x1f;
|
|
50
|
+
}
|
|
51
|
+
if (naluType === NAL_TYPE_IDR) {
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
if (allowedNaluTypes.includes(naluType)) {
|
|
55
|
+
offset++;
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return false;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=ffmpeg.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/utils/ffmpeg.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import crypto from 'node:crypto';
|
|
2
|
+
const validMac = /^([0-9A-F]{2}:){5}([0-9A-F]{2})$/;
|
|
3
|
+
function rd() {
|
|
4
|
+
return Math.round(Math.random() * 100000) % 10;
|
|
5
|
+
}
|
|
6
|
+
export function validMacAddress(address) {
|
|
7
|
+
return validMac.test(address);
|
|
8
|
+
}
|
|
9
|
+
export function generate(data) {
|
|
10
|
+
const sha1sum = crypto.createHash('sha1');
|
|
11
|
+
sha1sum.update(data);
|
|
12
|
+
const s = sha1sum.digest('hex');
|
|
13
|
+
let i = 0;
|
|
14
|
+
return 'xx:xx:xx:xx:xx:xx'.replace(/[x]/g, () => s[i++]).toUpperCase();
|
|
15
|
+
}
|
|
16
|
+
export function randomPinCode() {
|
|
17
|
+
return `${rd()}${rd()}${rd()}-${rd()}${rd()}-${rd()}${rd()}${rd()}`;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=mac.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mac.js","sourceRoot":"","sources":["../../src/utils/mac.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,aAAa,CAAC;AAEjC,MAAM,QAAQ,GAAG,kCAAkC,CAAC;AAEpD,SAAS,EAAE;IACT,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;AACjD,CAAC;AAID,MAAM,UAAU,eAAe,CAAC,OAAe;IAC7C,OAAO,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,IAAoD;IAC3E,MAAM,OAAO,GAAG,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IAC1C,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IACrB,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAEhC,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,mBAAmB,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;AACzE,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,OAAO,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC;AACtE,CAAC"}
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
// OpusRepacketizer is borrowed from scrypted
|
|
2
|
+
// Original source: https://github.com/koush/scrypted/blob/3150a3033515a3886af1e6b35a0ba7432b63e02b/plugins/homekit/src/types/camera/opus-repacketizer.ts
|
|
3
|
+
// https://datatracker.ietf.org/doc/html/rfc6716
|
|
4
|
+
// INPUT (for single frame sample, see RFC for other 4 code values)
|
|
5
|
+
// 0 1 2 3
|
|
6
|
+
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
7
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
8
|
+
// | config |s|0|0| |
|
|
9
|
+
// +-+-+-+-+-+-+-+-+ |
|
|
10
|
+
// | Compressed frame 1 (N-1 bytes)... :
|
|
11
|
+
// : |
|
|
12
|
+
// | |
|
|
13
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
14
|
+
// OUTPUT
|
|
15
|
+
// 0 1 2 3
|
|
16
|
+
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
|
17
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
18
|
+
// | config |s|1|1|1|p| M | Padding length (Optional) :
|
|
19
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
20
|
+
// : N1 (1-2 bytes): N2 (1-2 bytes): ... : N[M-1] |
|
|
21
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
22
|
+
// | |
|
|
23
|
+
// : Compressed frame 1 (N1 bytes)... :
|
|
24
|
+
// | |
|
|
25
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
26
|
+
// | |
|
|
27
|
+
// : Compressed frame 2 (N2 bytes)... :
|
|
28
|
+
// | |
|
|
29
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
30
|
+
// | |
|
|
31
|
+
// : ... :
|
|
32
|
+
// | |
|
|
33
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
34
|
+
// | |
|
|
35
|
+
// : Compressed frame M... :
|
|
36
|
+
// | |
|
|
37
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
38
|
+
// : Opus Padding (Optional)... |
|
|
39
|
+
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
|
40
|
+
// Figure 6: A CBR Code 3 Packet
|
|
41
|
+
// In the VBR case, the (optional) padding length is followed by M-1
|
|
42
|
+
// frame lengths (indicated by "N1" to "N[M-1]" in Figure 7), each
|
|
43
|
+
// encoded in a one- or two-byte sequence as described above. The
|
|
44
|
+
// packet MUST contain enough data for the M-1 lengths after removing
|
|
45
|
+
// the (optional) padding, and the sum of these lengths MUST be no
|
|
46
|
+
// larger than the number of bytes remaining in the packet after
|
|
47
|
+
// decoding them [R7]. The compressed data for all M frames follows,
|
|
48
|
+
// each frame consisting of the indicated number of bytes, with the
|
|
49
|
+
// final frame consuming any remaining bytes before the final padding,
|
|
50
|
+
// as illustrated in Figure 6. The number of header bytes (TOC byte,
|
|
51
|
+
// frame count byte, padding length bytes, and frame length bytes), plus
|
|
52
|
+
// the signaled length of the first M-1 frames themselves, plus the
|
|
53
|
+
// signaled length of the padding MUST be no larger than N, the total
|
|
54
|
+
// size of the packet.
|
|
55
|
+
export class OpusRepacketizer {
|
|
56
|
+
framesPerPacket;
|
|
57
|
+
depacketized = [];
|
|
58
|
+
constructor(framesPerPacket) {
|
|
59
|
+
this.framesPerPacket = framesPerPacket;
|
|
60
|
+
}
|
|
61
|
+
// repacketize a packet with a single frame into a packet with multiple frames.
|
|
62
|
+
repacketize(packet) {
|
|
63
|
+
const code = packet.payload[0] & 0b00000011;
|
|
64
|
+
let offset;
|
|
65
|
+
// see Frame Length Coding in RFC
|
|
66
|
+
const decodeFrameLength = () => {
|
|
67
|
+
let frameLength = packet.payload.readUInt8(offset);
|
|
68
|
+
if (frameLength >= 252) {
|
|
69
|
+
offset++;
|
|
70
|
+
frameLength += packet.payload.readUInt8(offset) * 4;
|
|
71
|
+
}
|
|
72
|
+
return frameLength;
|
|
73
|
+
};
|
|
74
|
+
// code 0: cbr, 1 packet
|
|
75
|
+
// code 1: cbr, 2 packets
|
|
76
|
+
// code 2: vbr, 2 packets
|
|
77
|
+
// code 3: cbr/vbr signaled, variable packets
|
|
78
|
+
if (code === 0) {
|
|
79
|
+
if (this.framesPerPacket === 1 && !this.depacketized.length)
|
|
80
|
+
return packet;
|
|
81
|
+
// depacketize by stripping off the config byte
|
|
82
|
+
this.depacketized.push(packet.payload.subarray(1));
|
|
83
|
+
}
|
|
84
|
+
else if (code === 1) {
|
|
85
|
+
if (this.framesPerPacket === 2 && !this.depacketized.length)
|
|
86
|
+
return packet;
|
|
87
|
+
// depacketize by dividing the remaining payload into two equal sized frames
|
|
88
|
+
const remaining = packet.payload.length - 1;
|
|
89
|
+
if (remaining % 2) {
|
|
90
|
+
throw new Error('expected equal sized opus packets (code 1)');
|
|
91
|
+
}
|
|
92
|
+
const frameLength = remaining / 2;
|
|
93
|
+
this.depacketized.push(packet.payload.subarray(1, 1 + frameLength));
|
|
94
|
+
this.depacketized.push(packet.payload.subarray(1 + frameLength));
|
|
95
|
+
}
|
|
96
|
+
else if (code === 2) {
|
|
97
|
+
if (this.framesPerPacket === 2 && !this.depacketized.length)
|
|
98
|
+
return packet;
|
|
99
|
+
offset = 1;
|
|
100
|
+
// depacketize by dividing the remaining payload into two inequal sized frames
|
|
101
|
+
const frameLength = decodeFrameLength();
|
|
102
|
+
this.depacketized.push(packet.payload.subarray(offset, offset + frameLength));
|
|
103
|
+
this.depacketized.push(packet.payload.subarray(offset + frameLength));
|
|
104
|
+
}
|
|
105
|
+
else if (code === 3) {
|
|
106
|
+
// code 3 packet will have a frame count and padding indicator, and whether the packets
|
|
107
|
+
// are equal size or not.
|
|
108
|
+
const frameCountByte = packet.payload[1], packetFrameCount = frameCountByte & 0b00111111, vbr = frameCountByte & 0b10000000;
|
|
109
|
+
if (this.framesPerPacket === packetFrameCount && !this.depacketized.length) {
|
|
110
|
+
return packet;
|
|
111
|
+
}
|
|
112
|
+
const paddingIndicator = frameCountByte & 0b01000000;
|
|
113
|
+
offset = 2;
|
|
114
|
+
let padding = 0;
|
|
115
|
+
if (paddingIndicator) {
|
|
116
|
+
padding = packet.payload.readUInt8(offset);
|
|
117
|
+
offset++;
|
|
118
|
+
if (padding === 255) {
|
|
119
|
+
padding = 254 + packet.payload.readUInt8(offset);
|
|
120
|
+
offset++;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!vbr) {
|
|
124
|
+
const remaining = packet.payload.length - offset - padding;
|
|
125
|
+
if (remaining % packetFrameCount) {
|
|
126
|
+
throw new Error('expected equal sized opus packets (code 3)');
|
|
127
|
+
}
|
|
128
|
+
const frameLength = remaining / packetFrameCount;
|
|
129
|
+
for (let i = 0; i < packetFrameCount; i++) {
|
|
130
|
+
const start = offset + i * frameLength, end = start + frameLength;
|
|
131
|
+
this.depacketized.push(packet.payload.subarray(start, end));
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else {
|
|
135
|
+
const frameLengths = [];
|
|
136
|
+
for (let i = 0; i < packetFrameCount; i++) {
|
|
137
|
+
const frameLength = decodeFrameLength();
|
|
138
|
+
frameLengths.push(frameLength);
|
|
139
|
+
}
|
|
140
|
+
for (let i = 0; i < packetFrameCount; i++) {
|
|
141
|
+
const frameLength = frameLengths[i], start = offset;
|
|
142
|
+
offset += frameLength;
|
|
143
|
+
this.depacketized.push(packet.payload.subarray(start, offset));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (this.depacketized.length < this.framesPerPacket)
|
|
148
|
+
return;
|
|
149
|
+
const depacketized = this.depacketized.slice(0, this.framesPerPacket);
|
|
150
|
+
this.depacketized = this.depacketized.slice(this.framesPerPacket);
|
|
151
|
+
// reuse the config and stereo indicator, but change the code to 3.
|
|
152
|
+
let toc = packet.payload[0];
|
|
153
|
+
toc |= 0b00000011;
|
|
154
|
+
// vbr | padding indicator | packet count
|
|
155
|
+
const frameCountByte = 0b10000000 | this.framesPerPacket, newHeader = [toc, frameCountByte];
|
|
156
|
+
// M-1 length bytes
|
|
157
|
+
newHeader.push(...depacketized.slice(0, -1).map((data) => data.length));
|
|
158
|
+
const headerBuffer = Buffer.from(newHeader), payload = Buffer.concat([headerBuffer, ...depacketized]);
|
|
159
|
+
packet.payload = payload;
|
|
160
|
+
return packet;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
//# sourceMappingURL=opus-repacketizer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opus-repacketizer.js","sourceRoot":"","sources":["../../src/utils/opus-repacketizer.ts"],"names":[],"mappings":"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"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
{
|
|
2
|
+
"displayName": "HomeKit",
|
|
3
|
+
"name": "@camera.ui/camera-ui-homekit",
|
|
4
|
+
"version": "0.0.2",
|
|
5
|
+
"description": "camera.ui homekit plugin",
|
|
6
|
+
"author": "seydx (https://github.com/seydx/camera.ui)",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"build": "rimraf dist && tsc",
|
|
11
|
+
"format": "prettier --write 'src/' --ignore-unknown --no-error-on-unmatched-pattern",
|
|
12
|
+
"lint": "eslint --fix --ext .js,.ts .",
|
|
13
|
+
"update": "updates --update ./",
|
|
14
|
+
"install-updates": "npm i --save",
|
|
15
|
+
"prepublishOnly": "npm i --package-lock-only && npm run lint && npm run format && npm run build"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@homebridge/camera-utils": "^2.2.6",
|
|
19
|
+
"chacha": "^2.1.0",
|
|
20
|
+
"hap-nodejs": "^1.1.0",
|
|
21
|
+
"rxjs": "^7.8.1",
|
|
22
|
+
"werift": "^0.19.4"
|
|
23
|
+
},
|
|
24
|
+
"devDependencies": {
|
|
25
|
+
"@camera.ui/types": "^0.0.54",
|
|
26
|
+
"@rushstack/eslint-patch": "^1.10.4",
|
|
27
|
+
"@types/node": "^22.1.0",
|
|
28
|
+
"@types/ws": "^8.5.12",
|
|
29
|
+
"@typescript-eslint/eslint-plugin": "^8.0.1",
|
|
30
|
+
"@typescript-eslint/parser": "^8.0.1",
|
|
31
|
+
"concurrently": "^8.2.2",
|
|
32
|
+
"eslint": "8.57.0",
|
|
33
|
+
"eslint-config-prettier": "^9.1.0",
|
|
34
|
+
"eslint-plugin-prettier": "^5.2.1",
|
|
35
|
+
"prettier": "^3.3.3",
|
|
36
|
+
"rimraf": "^6.0.1",
|
|
37
|
+
"typescript": "^5.5.4",
|
|
38
|
+
"updates": "^16.3.7"
|
|
39
|
+
},
|
|
40
|
+
"bugs": {
|
|
41
|
+
"url": "https://github.com/seydx/camera.ui/issues"
|
|
42
|
+
},
|
|
43
|
+
"engines": {
|
|
44
|
+
"camera.ui": ">=0.0.1",
|
|
45
|
+
"node": ">=18.12.0"
|
|
46
|
+
},
|
|
47
|
+
"homepage": "https://github.com/seydx/camera.ui#readme",
|
|
48
|
+
"keywords": [
|
|
49
|
+
"camera-ui-plugin",
|
|
50
|
+
"ring",
|
|
51
|
+
"webrtc"
|
|
52
|
+
],
|
|
53
|
+
"license": "MIT",
|
|
54
|
+
"repository": {
|
|
55
|
+
"type": "git",
|
|
56
|
+
"url": "git+https://github.com/seydx/camera.ui.git"
|
|
57
|
+
},
|
|
58
|
+
"camera.ui": {
|
|
59
|
+
"extension": "hub",
|
|
60
|
+
"dependencies": []
|
|
61
|
+
}
|
|
62
|
+
}
|