@camera.ui/camera-ui-homekit 0.0.15 → 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.
- package/dist/camera/accessory.js +4 -13
- package/dist/camera/accessory.js.map +1 -1
- package/dist/camera/recordingDelegate.d.ts +2 -2
- package/dist/camera/recordingDelegate.js +10 -9
- package/dist/camera/recordingDelegate.js.map +1 -1
- package/dist/camera/services.d.ts +2 -2
- package/dist/camera/services.js.map +1 -1
- package/dist/camera/sessionWrapper.d.ts +14 -11
- package/dist/camera/sessionWrapper.js +277 -222
- package/dist/camera/sessionWrapper.js.map +1 -1
- package/dist/camera/streamingDelegate.d.ts +2 -2
- package/dist/camera/streamingDelegate.js +1 -2
- package/dist/camera/streamingDelegate.js.map +1 -1
- package/dist/camera/streamingServer.d.ts +2 -2
- package/dist/camera/streamingServer.js.map +1 -1
- package/dist/constants.d.ts +1 -4
- package/dist/constants.js +6 -2
- package/dist/constants.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +1 -4
- package/dist/utils/processor.d.ts +45 -0
- package/dist/utils/processor.js +133 -0
- package/dist/utils/processor.js.map +1 -0
- package/dist/utils/return-audio-transcoder.d.ts +2 -3
- package/dist/utils/return-audio-transcoder.js +1 -3
- package/dist/utils/return-audio-transcoder.js.map +1 -1
- package/dist/utils/srtp.js +1 -1
- package/dist/utils/srtp.js.map +1 -1
- package/dist/utils/utils.d.ts +3 -1
- package/dist/utils/utils.js +5 -13
- package/dist/utils/utils.js.map +1 -1
- package/package.json +9 -8
- package/dist/utils/ffmpeg-process.d.ts +0 -23
- package/dist/utils/ffmpeg-process.js +0 -72
- package/dist/utils/ffmpeg-process.js.map +0 -1
- package/dist/utils/ffmpeg.d.ts +0 -2
- package/dist/utils/ffmpeg.js +0 -17
- package/dist/utils/ffmpeg.js.map +0 -1
- package/dist/utils/mp4.d.ts +0 -10
- package/dist/utils/mp4.js +0 -53
- package/dist/utils/mp4.js.map +0 -1
- package/dist/utils/ports.d.ts +0 -7
- package/dist/utils/ports.js +0 -43
- package/dist/utils/ports.js.map +0 -1
- package/dist/utils/rtp-splitter.d.ts +0 -34
- package/dist/utils/rtp-splitter.js +0 -76
- package/dist/utils/rtp-splitter.js.map +0 -1
- package/dist/utils/rtp.d.ts +0 -3
- package/dist/utils/rtp.js +0 -16
- 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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"}
|
package/dist/utils/ffmpeg.d.ts
DELETED
package/dist/utils/ffmpeg.js
DELETED
|
@@ -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
|
package/dist/utils/ffmpeg.js.map
DELETED
|
@@ -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"}
|
package/dist/utils/mp4.d.ts
DELETED
|
@@ -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
|
package/dist/utils/mp4.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mp4.js","sourceRoot":"","sources":["../../src/utils/mp4.ts"],"names":[],"mappings":"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"}
|
package/dist/utils/ports.d.ts
DELETED
|
@@ -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>;
|
package/dist/utils/ports.js
DELETED
|
@@ -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
|
package/dist/utils/ports.js.map
DELETED
|
@@ -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":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAErC,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACvD,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,uBAAuB,EAAE,MAAM,UAAU,CAAC;AAkBnE,MAAM,OAAO,WAAW;IACf,MAAM,CAAU;IAChB,OAAO,CAAU;IACjB,IAAI,CAAU;IACd,IAAI,CAAmB;IAEvB,SAAS,CAKb;IAEK,MAAM,GAAG,KAAK,CAAC;IACf,SAAS,GAAG,KAAK,CAAC;IAElB,OAAO,GAAG,IAAI,aAAa,EAAO,CAAC;IAE3C,gBAAe,CAAC;IAET,KAAK,CAAC,OAAO,CAAC,IAAqB,EAAE,OAAO,GAAG,WAAW,EAAE,cAAkC;QACnG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,MAAM,MAAM,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG,MAAM,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE/C,MAAM,CAAC,iBAAiB,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;QAEtC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QAEjB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAuB,IAAI,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,IAAI,CAC3E,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,EAAE;YACtB,MAAM,WAAW,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;YAE5C,OAAO;gBACL,OAAO;gBACP,IAAI;gBACJ,YAAY,EAAE,uBAAuB,CAAC,WAAW,CAAC;gBAClD,WAAW;aACZ,CAAC;QACJ,CAAC,CAAC,EACF,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,EACvB,KAAK,EAAE,CACR,CAAC;QAEF,IAAI,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,iBAAiB,CAAC,cAAc,CAAC,CAAC;QACzC,CAAC;QAED,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,SAAS,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;aACpE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;aAC7B,SAAS,CAAC,GAAG,EAAE;YACd,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,CAAC,CAAC,CAAC;IACP,CAAC;IAEM,iBAAiB,CAAC,OAA0B;QACjD,IAAI,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC,WAAW,EAAE,EAAE;YACxC,MAAM,gBAAgB,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;YAE9C,IAAI,gBAAgB,EAAE,CAAC;gBACrB,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC;YACnD,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEM,IAAI,CAAC,OAAe,EAAE,MAAoB;QAC/C,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,+FAA+F;YAC/F,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,OAAO,IAAI,WAAW,CAAC,CAAC;IACzE,CAAC;IAEO,OAAO;QACb,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAEnB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,SAAS,CAAC;QACzB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC;QACtB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;IAEM,KAAK;QACV,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF"}
|
package/dist/utils/rtp.d.ts
DELETED
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
|
package/dist/utils/rtp.js.map
DELETED
|
@@ -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"}
|