@matterbridge/core 3.10.14 → 3.10.15-dev-20261018-1598399
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/behaviors/ffmpeg.js +5 -1
- package/dist/behaviors/webRtcTransportProviderServer.d.ts +2 -0
- package/dist/behaviors/webRtcTransportProviderServer.js +21 -0
- package/dist/behaviors/weriftSession.d.ts +1 -1
- package/dist/behaviors/weriftSession.js +13 -7
- package/dist/devices/camera/export.d.ts +1 -0
- package/dist/devices/camera/export.js +1 -0
- package/dist/devices/camera.js +0 -1
- package/package.json +6 -6
package/dist/behaviors/ffmpeg.js
CHANGED
|
@@ -123,7 +123,11 @@ export function runFfmpeg(args) {
|
|
|
123
123
|
throw new Error('Cannot run ffmpeg: not found on this host');
|
|
124
124
|
}
|
|
125
125
|
log.debug(`Spawning ffmpeg: ${ffmpegCommand} ${args.map(redactSource).join(' ')}`);
|
|
126
|
-
|
|
126
|
+
const child = spawn(ffmpegCommand, args);
|
|
127
|
+
child.once('exit', (code, signal) => {
|
|
128
|
+
log.debug(`ffmpeg process ${child.pid ?? 'unknown'} exited with ${signal ? `signal ${signal}` : `code ${code}`}`);
|
|
129
|
+
});
|
|
130
|
+
return child;
|
|
127
131
|
}
|
|
128
132
|
async function ffmpegOutput(args) {
|
|
129
133
|
return new Promise((resolve, reject) => {
|
|
@@ -16,6 +16,7 @@ export declare class MatterbridgeWebRtcTransportProviderServer extends WebRtcTra
|
|
|
16
16
|
provideAnswer(request: WebRtcTransportProvider.ProvideAnswerRequest): Promise<void>;
|
|
17
17
|
provideIceCandidates(request: WebRtcTransportProvider.ProvideIceCandidatesRequest): Promise<void>;
|
|
18
18
|
endSession(request: WebRtcTransportProvider.EndSessionRequest): Promise<void>;
|
|
19
|
+
closeAllSessions(): Promise<void>;
|
|
19
20
|
}
|
|
20
21
|
export declare namespace MatterbridgeWebRtcTransportProviderServer {
|
|
21
22
|
class State extends WebRtcTransportProviderServer.State {
|
|
@@ -28,3 +29,4 @@ export declare namespace MatterbridgeWebRtcTransportProviderServer {
|
|
|
28
29
|
}
|
|
29
30
|
}
|
|
30
31
|
export declare function createDefaultWebRtcTransportProviderClusterServer(endpoint: MatterbridgeEndpoint, weriftOfferOptions?: WeriftOfferOptions): MatterbridgeEndpoint;
|
|
32
|
+
export declare function closeWebRtcSessions(device: MatterbridgeEndpoint): Promise<void>;
|
|
@@ -441,6 +441,22 @@ export class MatterbridgeWebRtcTransportProviderServer extends WebRtcTransportPr
|
|
|
441
441
|
device.log.info(`MatterbridgeWebRtcTransportProviderServer.endSession: ended webRTC session ${request.webRtcSessionId} (reason ${request.reason}) (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
442
442
|
this.endpoint.emitCommand(WebRtcTransportProvider, 'endSession', request, this.context);
|
|
443
443
|
}
|
|
444
|
+
async closeAllSessions() {
|
|
445
|
+
const device = this.endpoint.stateOf(MatterbridgeServer);
|
|
446
|
+
for (const session of this.state.currentSessions)
|
|
447
|
+
this.#updateStreamReferenceCounts(session.videoStreams, session.audioStreams, -1);
|
|
448
|
+
this.state.currentSessions = [];
|
|
449
|
+
this.internal.trickledSessions.clear();
|
|
450
|
+
const webRtcPeers = [...this.internal.sessions.entries()];
|
|
451
|
+
this.internal.sessions.clear();
|
|
452
|
+
const results = await Promise.allSettled(webRtcPeers.map(async ([, webRtcPeer]) => webRtcPeer.close()));
|
|
453
|
+
for (const [index, result] of results.entries()) {
|
|
454
|
+
if (result.status === 'rejected') {
|
|
455
|
+
device.log.error(`MatterbridgeWebRtcTransportProviderServer.closeAllSessions: failed to close webRTC session ${webRtcPeers[index][0]}: ${result.reason instanceof Error ? result.reason.message : String(result.reason)} (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
device.log.info(`MatterbridgeWebRtcTransportProviderServer.closeAllSessions: closed ${webRtcPeers.length} webRTC session(s) (endpoint ${this.endpoint.maybeId}.${this.endpoint.maybeNumber})`);
|
|
459
|
+
}
|
|
444
460
|
}
|
|
445
461
|
(function (MatterbridgeWebRtcTransportProviderServer) {
|
|
446
462
|
class State extends WebRtcTransportProviderServer.State {
|
|
@@ -458,3 +474,8 @@ export function createDefaultWebRtcTransportProviderClusterServer(endpoint, weri
|
|
|
458
474
|
endpoint.behaviors.require(MatterbridgeWebRtcTransportProviderServer, { currentSessions: [], weriftOfferOptions });
|
|
459
475
|
return endpoint;
|
|
460
476
|
}
|
|
477
|
+
export async function closeWebRtcSessions(device) {
|
|
478
|
+
await Promise.all([device, ...device.getChildEndpoints()]
|
|
479
|
+
.filter((endpoint) => endpoint.behaviors.has(MatterbridgeWebRtcTransportProviderServer))
|
|
480
|
+
.map(async (endpoint) => endpoint.act(async (agent) => agent.get(MatterbridgeWebRtcTransportProviderServer).closeAllSessions())));
|
|
481
|
+
}
|
|
@@ -52,6 +52,7 @@ export declare class WeriftWebRtcSession {
|
|
|
52
52
|
private getConfiguredVideoSource;
|
|
53
53
|
private buildFfmpegVideoInputArgs;
|
|
54
54
|
private logFfmpegStderr;
|
|
55
|
+
private watchGeneratorExit;
|
|
55
56
|
private generateVideoTrack;
|
|
56
57
|
private preferVideoCodecOnTransceivers;
|
|
57
58
|
private preferAudioCodecOnTransceivers;
|
|
@@ -70,6 +71,5 @@ export declare class WeriftWebRtcSession {
|
|
|
70
71
|
private logDtlsTransportStateChanges;
|
|
71
72
|
private logDiagnosticsSnapshot;
|
|
72
73
|
close(): Promise<void>;
|
|
73
|
-
static closeAll(): Promise<void>;
|
|
74
74
|
}
|
|
75
75
|
export {};
|
|
@@ -78,7 +78,7 @@ export class WeriftWebRtcSession {
|
|
|
78
78
|
this.log.info(`Peer connection state: ${state}`);
|
|
79
79
|
});
|
|
80
80
|
this.log.debug(`Created RTCPeerConnection with codecs: audio=[OPUS, PCMU], video=[H264, VP8] for session ${webRtcSessionId}`);
|
|
81
|
-
this.diagnosticsInterval = setInterval(() => void this.logDiagnosticsSnapshot(), WeriftWebRtcSession.DIAGNOSTICS_INTERVAL_MS);
|
|
81
|
+
this.diagnosticsInterval = setInterval(() => void this.logDiagnosticsSnapshot(), WeriftWebRtcSession.DIAGNOSTICS_INTERVAL_MS).unref();
|
|
82
82
|
WeriftWebRtcSession.activeSessions.add(this);
|
|
83
83
|
if (!WeriftWebRtcSession.exitHandlerRegistered) {
|
|
84
84
|
WeriftWebRtcSession.exitHandlerRegistered = true;
|
|
@@ -253,6 +253,14 @@ export class WeriftWebRtcSession {
|
|
|
253
253
|
this.log.debug(`Ffmpeg ${kind} generator: ${message}`);
|
|
254
254
|
});
|
|
255
255
|
}
|
|
256
|
+
watchGeneratorExit(generator, kind) {
|
|
257
|
+
generator.once('exit', (code, signal) => {
|
|
258
|
+
const attached = kind === 'video' ? this.testVideoGenerator : this.testAudioGenerator;
|
|
259
|
+
if (attached !== generator)
|
|
260
|
+
return;
|
|
261
|
+
this.log.warn(`Ffmpeg ${kind} generator exited unexpectedly with ${signal ? `signal ${signal}` : `code ${code}`}: the ${kind} track carries no more media`);
|
|
262
|
+
});
|
|
263
|
+
}
|
|
256
264
|
async generateVideoTrack(codec) {
|
|
257
265
|
if (this.testVideoAttached)
|
|
258
266
|
return;
|
|
@@ -315,6 +323,7 @@ export class WeriftWebRtcSession {
|
|
|
315
323
|
];
|
|
316
324
|
const generator = runFfmpeg(ffmpegArgs);
|
|
317
325
|
this.logFfmpegStderr(generator, 'video');
|
|
326
|
+
this.watchGeneratorExit(generator, 'video');
|
|
318
327
|
generator.once('error', (error) => {
|
|
319
328
|
this.log.warn(`Video generator failed: ${getErrorMessage(error)}`);
|
|
320
329
|
});
|
|
@@ -448,6 +457,7 @@ export class WeriftWebRtcSession {
|
|
|
448
457
|
];
|
|
449
458
|
const generator = runFfmpeg(ffmpegArgs);
|
|
450
459
|
this.logFfmpegStderr(generator, 'audio');
|
|
460
|
+
this.watchGeneratorExit(generator, 'audio');
|
|
451
461
|
generator.once('error', (error) => {
|
|
452
462
|
this.log.warn(`Audio generator failed: ${getErrorMessage(error)}`);
|
|
453
463
|
});
|
|
@@ -462,6 +472,7 @@ export class WeriftWebRtcSession {
|
|
|
462
472
|
}
|
|
463
473
|
cleanupTestVideoArtifacts() {
|
|
464
474
|
if (this.testVideoGenerator) {
|
|
475
|
+
this.log.debug(`Stopping ffmpeg video generator (pid ${this.testVideoGenerator.pid ?? 'unknown'})`);
|
|
465
476
|
this.testVideoGenerator.kill('SIGTERM');
|
|
466
477
|
this.testVideoGenerator = undefined;
|
|
467
478
|
}
|
|
@@ -471,6 +482,7 @@ export class WeriftWebRtcSession {
|
|
|
471
482
|
}
|
|
472
483
|
cleanupTestAudioArtifacts() {
|
|
473
484
|
if (this.testAudioGenerator) {
|
|
485
|
+
this.log.debug(`Stopping ffmpeg audio generator (pid ${this.testAudioGenerator.pid ?? 'unknown'})`);
|
|
474
486
|
this.testAudioGenerator.kill('SIGTERM');
|
|
475
487
|
this.testAudioGenerator = undefined;
|
|
476
488
|
}
|
|
@@ -612,10 +624,4 @@ export class WeriftWebRtcSession {
|
|
|
612
624
|
WeriftWebRtcSession.activeSessions.delete(this);
|
|
613
625
|
this.log.info(`RTCPeerConnection closed (connectionState=${this.peerConnection.connectionState})`);
|
|
614
626
|
}
|
|
615
|
-
static async closeAll() {
|
|
616
|
-
for (const session of WeriftWebRtcSession.activeSessions) {
|
|
617
|
-
session.log.info(`Closing session ${session.webRtcSessionId} as part of closeAll()`);
|
|
618
|
-
await session.close();
|
|
619
|
-
}
|
|
620
|
-
}
|
|
621
627
|
}
|
package/dist/devices/camera.js
CHANGED
|
@@ -22,7 +22,6 @@ export class Camera extends MatterbridgeEndpoint {
|
|
|
22
22
|
if (identifyType !== Identify.IdentifyType.None) {
|
|
23
23
|
this.createDefaultIdentifyClusterServer(identifyTime, identifyType);
|
|
24
24
|
}
|
|
25
|
-
this.createDefaultBasicInformationClusterServer(name, serial, 0xfff1, 'Matterbridge', 0x8000, 'Matterbridge Chime');
|
|
26
25
|
switch (powerSourceType) {
|
|
27
26
|
case 'Rechargeable':
|
|
28
27
|
this.createDefaultPowerSourceRechargeableBatteryClusterServer();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@matterbridge/core",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.15-dev-20261018-1598399",
|
|
4
4
|
"description": "Matterbridge core library",
|
|
5
5
|
"author": "https://github.com/Luligu",
|
|
6
6
|
"homepage": "https://matterbridge.io/",
|
|
@@ -136,12 +136,12 @@
|
|
|
136
136
|
},
|
|
137
137
|
"dependencies": {
|
|
138
138
|
"@matter/main": "0.17.9",
|
|
139
|
-
"@matterbridge/dgram": "3.10.
|
|
140
|
-
"@matterbridge/thread": "3.10.
|
|
141
|
-
"@matterbridge/types": "3.10.
|
|
142
|
-
"@matterbridge/utils": "3.10.
|
|
139
|
+
"@matterbridge/dgram": "3.10.15-dev-20261018-1598399",
|
|
140
|
+
"@matterbridge/thread": "3.10.15-dev-20261018-1598399",
|
|
141
|
+
"@matterbridge/types": "3.10.15-dev-20261018-1598399",
|
|
142
|
+
"@matterbridge/utils": "3.10.15-dev-20261018-1598399",
|
|
143
143
|
"escape-html": "1.0.3",
|
|
144
|
-
"express": "5.
|
|
144
|
+
"express": "5.3.0",
|
|
145
145
|
"express-rate-limit": "8.7.1",
|
|
146
146
|
"multer": "2.4.0",
|
|
147
147
|
"node-ansi-logger": "3.3.1",
|