@camera.ui/camera-ui-homekit 0.0.16 → 0.0.17

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 (51) hide show
  1. package/dist/camera/accessory.js +4 -13
  2. package/dist/camera/accessory.js.map +1 -1
  3. package/dist/camera/recordingDelegate.d.ts +2 -2
  4. package/dist/camera/recordingDelegate.js +10 -9
  5. package/dist/camera/recordingDelegate.js.map +1 -1
  6. package/dist/camera/services.d.ts +2 -2
  7. package/dist/camera/services.js.map +1 -1
  8. package/dist/camera/sessionWrapper.d.ts +14 -11
  9. package/dist/camera/sessionWrapper.js +264 -221
  10. package/dist/camera/sessionWrapper.js.map +1 -1
  11. package/dist/camera/streamingDelegate.d.ts +2 -2
  12. package/dist/camera/streamingDelegate.js +1 -2
  13. package/dist/camera/streamingDelegate.js.map +1 -1
  14. package/dist/camera/streamingServer.d.ts +2 -2
  15. package/dist/camera/streamingServer.js.map +1 -1
  16. package/dist/constants.d.ts +1 -4
  17. package/dist/constants.js +6 -2
  18. package/dist/constants.js.map +1 -1
  19. package/dist/index.d.ts +3 -3
  20. package/dist/index.js.map +1 -1
  21. package/dist/types.d.ts +1 -4
  22. package/dist/utils/processor.d.ts +45 -0
  23. package/dist/utils/processor.js +133 -0
  24. package/dist/utils/processor.js.map +1 -0
  25. package/dist/utils/return-audio-transcoder.d.ts +2 -3
  26. package/dist/utils/return-audio-transcoder.js +1 -3
  27. package/dist/utils/return-audio-transcoder.js.map +1 -1
  28. package/dist/utils/srtp.js +1 -1
  29. package/dist/utils/srtp.js.map +1 -1
  30. package/dist/utils/utils.d.ts +3 -1
  31. package/dist/utils/utils.js +5 -13
  32. package/dist/utils/utils.js.map +1 -1
  33. package/package.json +8 -7
  34. package/dist/utils/ffmpeg-process.d.ts +0 -23
  35. package/dist/utils/ffmpeg-process.js +0 -72
  36. package/dist/utils/ffmpeg-process.js.map +0 -1
  37. package/dist/utils/ffmpeg.d.ts +0 -2
  38. package/dist/utils/ffmpeg.js +0 -17
  39. package/dist/utils/ffmpeg.js.map +0 -1
  40. package/dist/utils/mp4.d.ts +0 -10
  41. package/dist/utils/mp4.js +0 -53
  42. package/dist/utils/mp4.js.map +0 -1
  43. package/dist/utils/ports.d.ts +0 -7
  44. package/dist/utils/ports.js +0 -43
  45. package/dist/utils/ports.js.map +0 -1
  46. package/dist/utils/rtp-splitter.d.ts +0 -34
  47. package/dist/utils/rtp-splitter.js +0 -76
  48. package/dist/utils/rtp-splitter.js.map +0 -1
  49. package/dist/utils/rtp.d.ts +0 -3
  50. package/dist/utils/rtp.js +0 -16
  51. package/dist/utils/rtp.js.map +0 -1
@@ -1,72 +0,0 @@
1
- import { spawn } from 'child_process';
2
- import { Subject } from 'rxjs';
3
- const noop = () => null;
4
- const onGlobalProcessStopped = new Subject();
5
- // register a single event listener, rather than listener per ffmpeg process
6
- // this helps avoid a warning for hitting too many listeners
7
- process.on('exit', () => onGlobalProcessStopped.next(null));
8
- export class FfmpegProcess {
9
- options;
10
- ff;
11
- processSubscription = onGlobalProcessStopped.subscribe(() => this.stop());
12
- started = false;
13
- stopped = false;
14
- exited = false;
15
- constructor(options) {
16
- this.options = options;
17
- this.ff = spawn(options.ffmpegPath, options.ffmpegArgs.map((x) => x.toString()));
18
- const { logger, logLabel } = options;
19
- const logError = logger?.error || noop;
20
- const logInfo = logger?.info || noop;
21
- const logPrefix = logLabel ? `${logLabel}: ` : '';
22
- if (options.stdoutCallback) {
23
- const { stdoutCallback } = options;
24
- this.ff.stdout.on('data', (data) => {
25
- stdoutCallback(data);
26
- });
27
- }
28
- this.ff.stderr.on('data', (data) => {
29
- if (!this.started) {
30
- this.started = true;
31
- options.startedCallback?.();
32
- }
33
- logInfo(logPrefix + data);
34
- });
35
- this.ff.stdin.on('error', (error) => {
36
- if (!error.message.includes('EPIPE')) {
37
- logError(logPrefix + error.message);
38
- }
39
- });
40
- this.ff.on('exit', (code, signal) => {
41
- this.exited = true;
42
- this.options.exitCallback?.(code, signal);
43
- if (!code || code === 255) {
44
- logInfo(logPrefix + 'stopped gracefully');
45
- }
46
- else {
47
- logError(logPrefix + `exited with code ${code} and signal ${signal}`);
48
- }
49
- this.stop();
50
- });
51
- }
52
- stop() {
53
- if (this.stopped) {
54
- return;
55
- }
56
- this.stopped = true;
57
- this.processSubscription.unsubscribe();
58
- this.ff.stderr.pause();
59
- this.ff.stdout.pause();
60
- if (!this.exited) {
61
- this.ff.kill();
62
- }
63
- }
64
- writeStdin(input) {
65
- if (this.stopped) {
66
- return;
67
- }
68
- this.ff.stdin.write(input);
69
- this.ff.stdin.end();
70
- }
71
- }
72
- //# sourceMappingURL=ffmpeg-process.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ffmpeg-process.js","sourceRoot":"","sources":["../../src/utils/ffmpeg-process.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export declare function doesFfmpegSupportCodec(codec: string, ffmpegPath: string): Promise<boolean>;
2
- export declare function isFfmpegInstalled(ffmpegPath: string): Promise<boolean>;
@@ -1,17 +0,0 @@
1
- import { exec } from 'child_process';
2
- import { promisify } from 'node:util';
3
- const execAwait = promisify(exec);
4
- export async function doesFfmpegSupportCodec(codec, ffmpegPath) {
5
- const output = await execAwait(`${ffmpegPath} -codecs`);
6
- return output.stdout.includes(codec);
7
- }
8
- export async function isFfmpegInstalled(ffmpegPath) {
9
- try {
10
- await execAwait(`${ffmpegPath} -codecs`);
11
- return true;
12
- }
13
- catch {
14
- return false;
15
- }
16
- }
17
- //# sourceMappingURL=ffmpeg.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ffmpeg.js","sourceRoot":"","sources":["../../src/utils/ffmpeg.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;AAElC,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAAa,EAAE,UAAkB;IAC5E,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,GAAG,UAAU,UAAU,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,UAAkB;IACxD,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,GAAG,UAAU,UAAU,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
@@ -1,10 +0,0 @@
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 checkMp4StartsWithKeyFrame(mp4: Buffer, ffmpegPath: string): Promise<boolean>;
package/dist/utils/mp4.js DELETED
@@ -1,53 +0,0 @@
1
- import { spawn } from 'node:child_process';
2
- import { timeoutPromise } from './utils.js';
3
- // https://yumichan.net/video-processing/video-compression/introduction-to-h264-nal-unit/
4
- export const NAL_TYPE_STAP_A = 24;
5
- export const NAL_TYPE_FU_A = 28;
6
- export const NAL_TYPE_NON_IDR = 1;
7
- export const NAL_TYPE_IDR = 5;
8
- export const NAL_TYPE_SEI = 6;
9
- export const NAL_TYPE_SPS = 7;
10
- export const NAL_TYPE_PPS = 8;
11
- export const NAL_TYPE_DELIMITER = 9;
12
- export const allowedNaluTypes = [NAL_TYPE_STAP_A, NAL_TYPE_SPS, NAL_TYPE_PPS, NAL_TYPE_SEI, NAL_TYPE_DELIMITER];
13
- export async function checkMp4StartsWithKeyFrame(mp4, ffmpegPath) {
14
- const cp = spawn(ffmpegPath, ['-hide_banner', '-f', 'mp4', '-i', 'pipe:3', '-vcodec', 'copy', '-f', 'h264', 'pipe:4'], {
15
- stdio: ['pipe', 'pipe', 'pipe', 'pipe', 'pipe'],
16
- });
17
- const input = cp.stdio[3];
18
- const output = cp.stdio[4];
19
- const buffers = [];
20
- input.write(mp4);
21
- input.end();
22
- output.on('data', (data) => buffers.push(data));
23
- try {
24
- await timeoutPromise(1000, new Promise((resolve) => cp.on('exit', resolve)));
25
- const h264 = Buffer.concat(buffers);
26
- let offset = 0;
27
- while (offset < h264.length - 6) {
28
- if (h264.readInt32BE(offset) !== 1) {
29
- offset++;
30
- continue;
31
- }
32
- offset += 4;
33
- let naluType = h264.readUInt8(offset) & 0x1f;
34
- if (naluType === NAL_TYPE_FU_A) {
35
- offset++;
36
- naluType = h264.readUInt8(offset) & 0x1f;
37
- }
38
- if (naluType === NAL_TYPE_IDR) {
39
- return true;
40
- }
41
- if (allowedNaluTypes.includes(naluType)) {
42
- offset++;
43
- continue;
44
- }
45
- return false;
46
- }
47
- return false;
48
- }
49
- catch {
50
- return false;
51
- }
52
- }
53
- //# sourceMappingURL=mp4.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"mp4.js","sourceRoot":"","sources":["../../src/utils/mp4.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- import type { Socket } from 'dgram';
2
- export declare function reservePorts({ count, type, attemptNumber, }?: {
3
- count?: number;
4
- type?: 'udp' | 'tcp';
5
- attemptNumber?: number;
6
- }): Promise<number[]>;
7
- export declare function bindToPort(socket: Socket, address?: string): Promise<number>;
@@ -1,43 +0,0 @@
1
- import { pickPort } from 'pick-port';
2
- // Need to reserve ports in sequence because ffmpeg uses the next port up by default. If it's taken, ffmpeg will error
3
- export async function reservePorts({ count = 1, type = 'udp', attemptNumber = 0, } = {}) {
4
- if (attemptNumber > 100) {
5
- throw new Error('Failed to reserve ports after 100 tries');
6
- }
7
- const pickPortOptions = {
8
- type,
9
- reserveTimeout: 15, // 15 seconds is max setup time for HomeKit streams, so the port should be in use by then
10
- }, port = await pickPort(pickPortOptions), ports = [port], tryAgain = () => {
11
- return reservePorts({
12
- count,
13
- type,
14
- attemptNumber: attemptNumber + 1,
15
- });
16
- };
17
- for (let i = 1; i < count; i++) {
18
- try {
19
- const targetConsecutivePort = port + i, openPort = await pickPort({
20
- ...pickPortOptions,
21
- minPort: targetConsecutivePort,
22
- maxPort: targetConsecutivePort,
23
- });
24
- ports.push(openPort);
25
- }
26
- catch {
27
- // can't reserve next port, bail and get another set
28
- return tryAgain();
29
- }
30
- }
31
- return ports;
32
- }
33
- export function bindToPort(socket, address = '127.0.0.1') {
34
- return new Promise((resolve, reject) => {
35
- socket.on('error', reject);
36
- // 0 means select a random open port
37
- socket.bind(0, address, () => {
38
- const { port } = socket.address();
39
- resolve(port);
40
- });
41
- });
42
- }
43
- //# sourceMappingURL=ports.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ports.js","sourceRoot":"","sources":["../../src/utils/ports.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAKrC,uHAAuH;AACvH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,EACjC,KAAK,GAAG,CAAC,EACT,IAAI,GAAG,KAAK,EACZ,aAAa,GAAG,CAAC,MAKf,EAAE;IACJ,IAAI,aAAa,GAAG,GAAG,EAAE,CAAC;QACxB,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,eAAe,GAAG;QACpB,IAAI;QACJ,cAAc,EAAE,EAAE,EAAE,yFAAyF;KAC9G,EACD,IAAI,GAAG,MAAM,QAAQ,CAAC,eAAe,CAAC,EACtC,KAAK,GAAG,CAAC,IAAI,CAAC,EACd,QAAQ,GAAG,GAAG,EAAE;QACd,OAAO,YAAY,CAAC;YAClB,KAAK;YACL,IAAI;YACJ,aAAa,EAAE,aAAa,GAAG,CAAC;SACjC,CAAC,CAAC;IACL,CAAC,CAAC;IAEJ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAC,EACpC,QAAQ,GAAG,MAAM,QAAQ,CAAC;gBACxB,GAAG,eAAe;gBAClB,OAAO,EAAE,qBAAqB;gBAC9B,OAAO,EAAE,qBAAqB;aAC/B,CAAC,CAAC;YAEL,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,OAAO,QAAQ,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,MAAc,EAAE,OAAO,GAAG,WAAW;IAC9D,OAAO,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC7C,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAE3B,oCAAoC;QACpC,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,OAAO,EAAE,GAAG,EAAE;YAC3B,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,EAAiB,CAAC;YACjD,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -1,34 +0,0 @@
1
- import type { Observable } from 'rxjs';
2
- import type { RemoteInfo, Socket } from 'dgram';
3
- export interface SocketTarget {
4
- port: number;
5
- address?: string;
6
- }
7
- export interface RtpMessageDescription {
8
- isRtpMessage: boolean;
9
- payloadType: number;
10
- info: RemoteInfo;
11
- message: Buffer;
12
- }
13
- export type RtpMessageHandler = (description: RtpMessageDescription) => SocketTarget | null;
14
- export declare class RtpSplitter {
15
- socket?: Socket;
16
- address?: string;
17
- port?: number;
18
- type?: 'udp4' | 'udp6';
19
- onMessage?: Observable<{
20
- message: Buffer;
21
- info: RemoteInfo;
22
- isRtpMessage: boolean;
23
- payloadType: number;
24
- }>;
25
- private closed;
26
- private cleanedUp;
27
- private onClose;
28
- constructor();
29
- prepare(type: 'udp4' | 'udp6', address?: string, messageHandler?: RtpMessageHandler): Promise<void>;
30
- addMessageHandler(handler: RtpMessageHandler): void;
31
- send(message: Buffer, sendTo: SocketTarget): void;
32
- private cleanUp;
33
- close(): void;
34
- }
@@ -1,76 +0,0 @@
1
- import { createSocket } from 'dgram';
2
- import { fromEvent, merge, ReplaySubject } from 'rxjs';
3
- import { map, share, takeUntil } from 'rxjs/operators';
4
- import { bindToPort } from './ports.js';
5
- import { getPayloadType, isRtpMessagePayloadType } from './rtp.js';
6
- export class RtpSplitter {
7
- socket;
8
- address;
9
- port;
10
- type;
11
- onMessage;
12
- closed = false;
13
- cleanedUp = false;
14
- onClose = new ReplaySubject();
15
- constructor() { }
16
- async prepare(type, address = '127.0.0.1', messageHandler) {
17
- this.type = type;
18
- const socket = createSocket(type);
19
- const port = await bindToPort(socket, address);
20
- socket.setSendBufferSize(1024 * 1024);
21
- this.socket = socket;
22
- this.address = address;
23
- this.port = port;
24
- this.onMessage = fromEvent(this.socket, 'message').pipe(map(([message, info]) => {
25
- const payloadType = getPayloadType(message);
26
- return {
27
- message,
28
- info,
29
- isRtpMessage: isRtpMessagePayloadType(payloadType),
30
- payloadType,
31
- };
32
- }), takeUntil(this.onClose), share());
33
- if (messageHandler) {
34
- this.addMessageHandler(messageHandler);
35
- }
36
- merge(fromEvent(this.socket, 'close'), fromEvent(this.socket, 'error'))
37
- .pipe(takeUntil(this.onClose))
38
- .subscribe(() => {
39
- this.cleanUp();
40
- });
41
- }
42
- addMessageHandler(handler) {
43
- this.onMessage?.subscribe((description) => {
44
- const forwardingTarget = handler(description);
45
- if (forwardingTarget) {
46
- this.send(description.message, forwardingTarget);
47
- }
48
- });
49
- }
50
- send(message, sendTo) {
51
- if (this.closed) {
52
- // If we send a message on a closed socket, it will throw an ERR_SOCKET_DGRAM_NOT_RUNNING error
53
- return;
54
- }
55
- this.socket?.send(message, sendTo.port, sendTo.address || '127.0.0.1');
56
- }
57
- cleanUp() {
58
- this.closed = true;
59
- if (this.cleanedUp) {
60
- return;
61
- }
62
- this.address = undefined;
63
- this.port = undefined;
64
- this.type = undefined;
65
- this.cleanedUp = true;
66
- this.onClose.next(null);
67
- }
68
- close() {
69
- if (this.closed) {
70
- return;
71
- }
72
- this.socket?.close();
73
- this.cleanUp();
74
- }
75
- }
76
- //# sourceMappingURL=rtp-splitter.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rtp-splitter.js","sourceRoot":"","sources":["../../src/utils/rtp-splitter.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- export declare function getPayloadType(message: Buffer): number;
2
- export declare function isRtpMessagePayloadType(payloadType: number): boolean;
3
- export declare function getSsrc(message: Buffer): number | null;
package/dist/utils/rtp.js DELETED
@@ -1,16 +0,0 @@
1
- export function getPayloadType(message) {
2
- return message.readUInt8(1) & 0x7f;
3
- }
4
- export function isRtpMessagePayloadType(payloadType) {
5
- return payloadType > 90 || payloadType === 0;
6
- }
7
- export function getSsrc(message) {
8
- try {
9
- const payloadType = getPayloadType(message), isRtp = isRtpMessagePayloadType(payloadType);
10
- return message.readUInt32BE(isRtp ? 8 : 4);
11
- }
12
- catch {
13
- return null;
14
- }
15
- }
16
- //# sourceMappingURL=rtp.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"rtp.js","sourceRoot":"","sources":["../../src/utils/rtp.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,uBAAuB,CAAC,WAAmB;IACzD,OAAO,WAAW,GAAG,EAAE,IAAI,WAAW,KAAK,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,OAAe;IACrC,IAAI,CAAC;QACH,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,EACzC,KAAK,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAC;QAC/C,OAAO,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC7C,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}