@matterbridge/core 3.10.14-dev-20261014-2811fdc → 3.10.14-dev-20261014-ad770e2

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.
@@ -6,7 +6,7 @@ import { hasAnyParameter } from '@matterbridge/utils/cli';
6
6
  import { AnsiLogger, MAGENTA } from 'node-ansi-logger';
7
7
  const log = new AnsiLogger({
8
8
  logName: 'Ffmpeg',
9
- logLevel: hasAnyParameter('debug', 'verbose') ? "debug" : "info",
9
+ logLevel: hasAnyParameter('debug', 'verbose', 'debug-ffmpeg', 'verbose-ffmpeg') ? "debug" : "info",
10
10
  logNameColor: MAGENTA,
11
11
  logTimestampFormat: 4,
12
12
  });
@@ -77,7 +77,7 @@ function getWindowsCommandCandidates() {
77
77
  return candidates;
78
78
  }
79
79
  function resolveFfmpeg() {
80
- const candidates = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg', '/usr/local/bin/ffmpeg', ...getWindowsCommandCandidates()];
80
+ const candidates = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg', '/usr/local/bin/ffmpeg', '/opt/homebrew/bin/ffmpeg', ...getWindowsCommandCandidates()];
81
81
  log.debug(`Resolving ffmpeg: trying ${candidates.length} candidate(s)`);
82
82
  for (const candidate of candidates) {
83
83
  if (path.isAbsolute(candidate)) {
@@ -200,22 +200,31 @@ export function playWebcam(videoSource, audioSource) {
200
200
  log.debug(`Spawning ffplay: ${ffplayCommand} ${args.map(redactSource).join(' ')}`);
201
201
  return spawn(ffplayCommand, args);
202
202
  }
203
+ async function runPrivileged(asRoot, command, args) {
204
+ await (asRoot ? runCommand(command, args) : runCommand('sudo', ['-n', command, ...args]));
205
+ }
203
206
  export async function installFfmpeg() {
204
207
  if (process.platform !== 'linux') {
205
208
  log.warn(`Cannot install ffmpeg: unsupported platform ${process.platform}`);
206
209
  return false;
207
210
  }
208
- if (process.getuid?.() !== 0) {
209
- log.warn('Cannot install ffmpeg: root privileges are required');
210
- return false;
211
+ const isRoot = process.getuid?.() === 0;
212
+ if (!isRoot) {
213
+ try {
214
+ runProbe('sudo', ['-n', 'true']);
215
+ }
216
+ catch {
217
+ log.warn('Cannot install ffmpeg: root privileges or passwordless sudo are required');
218
+ return false;
219
+ }
211
220
  }
212
221
  try {
213
222
  if (isRunnable('apk')) {
214
- await runCommand('apk', ['add', '--no-cache', 'ffmpeg']);
223
+ await runPrivileged(isRoot, 'apk', ['add', '--no-cache', 'ffmpeg']);
215
224
  }
216
225
  else if (isRunnable('apt-get')) {
217
- await runCommand('apt-get', ['update']);
218
- await runCommand('env', ['DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '--no-install-recommends', 'ffmpeg']);
226
+ await runPrivileged(isRoot, 'apt-get', ['update']);
227
+ await runPrivileged(isRoot, 'env', ['DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '--no-install-recommends', 'ffmpeg']);
219
228
  }
220
229
  else {
221
230
  log.warn('Cannot install ffmpeg: no supported package manager found (apk, apt-get)');
@@ -221,11 +221,26 @@ export class WeriftWebRtcSession {
221
221
  this.log.debug(`Webcam capture params: device=${device}, resolution=${resolution}, description="${description}", bitrateKbps=${bitrateKbps}`);
222
222
  switch (process.platform) {
223
223
  case 'linux':
224
- return { args: ['-f', 'v4l2', '-video_size', resolution, '-framerate', '30', '-i', device], description, bitrateKbps, keyFrameInterval: 20 };
224
+ return {
225
+ args: ['-f', 'v4l2', '-video_size', resolution, '-framerate', '30', '-i', device, '-fps_mode', 'cfr', '-r', '30'],
226
+ description,
227
+ bitrateKbps,
228
+ keyFrameInterval: 20,
229
+ };
225
230
  case 'darwin':
226
- return { args: ['-f', 'avfoundation', '-video_size', resolution, '-framerate', '30', '-i', device], description, bitrateKbps, keyFrameInterval: 20 };
231
+ return {
232
+ args: ['-f', 'avfoundation', '-video_size', resolution, '-framerate', '30', '-i', device, '-fps_mode', 'cfr', '-r', '30'],
233
+ description,
234
+ bitrateKbps,
235
+ keyFrameInterval: 20,
236
+ };
227
237
  case 'win32':
228
- return { args: ['-f', 'dshow', '-video_size', resolution, '-framerate', '30', '-i', `video=${device}`], description, bitrateKbps, keyFrameInterval: 20 };
238
+ return {
239
+ args: ['-f', 'dshow', '-video_size', resolution, '-framerate', '30', '-i', `video=${device}`, '-fps_mode', 'cfr', '-r', '30'],
240
+ description,
241
+ bitrateKbps,
242
+ keyFrameInterval: 20,
243
+ };
229
244
  default:
230
245
  this.log.error(`Webcam capture via ffmpeg is not supported on platform "${process.platform}"; not injecting a video track`);
231
246
  return undefined;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@matterbridge/core",
3
- "version": "3.10.14-dev-20261014-2811fdc",
3
+ "version": "3.10.14-dev-20261014-ad770e2",
4
4
  "description": "Matterbridge core library",
5
5
  "author": "https://github.com/Luligu",
6
6
  "homepage": "https://matterbridge.io/",
@@ -136,10 +136,10 @@
136
136
  },
137
137
  "dependencies": {
138
138
  "@matter/main": "0.17.9",
139
- "@matterbridge/dgram": "3.10.14-dev-20261014-2811fdc",
140
- "@matterbridge/thread": "3.10.14-dev-20261014-2811fdc",
141
- "@matterbridge/types": "3.10.14-dev-20261014-2811fdc",
142
- "@matterbridge/utils": "3.10.14-dev-20261014-2811fdc",
139
+ "@matterbridge/dgram": "3.10.14-dev-20261014-ad770e2",
140
+ "@matterbridge/thread": "3.10.14-dev-20261014-ad770e2",
141
+ "@matterbridge/types": "3.10.14-dev-20261014-ad770e2",
142
+ "@matterbridge/utils": "3.10.14-dev-20261014-ad770e2",
143
143
  "escape-html": "1.0.3",
144
144
  "express": "5.2.1",
145
145
  "express-rate-limit": "8.7.1",