homebridge-plugin-utils 1.31.0 → 1.33.0
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/build/eslint-rules.mjs +138 -19
- package/dist/featureoptions.d.ts +4 -12
- package/dist/featureoptions.js +2 -2
- package/dist/featureoptions.js.map +1 -1
- package/dist/ffmpeg/codecs.js +9 -9
- package/dist/ffmpeg/codecs.js.map +1 -1
- package/dist/ffmpeg/exec.d.ts +2 -2
- package/dist/ffmpeg/fmp4.d.ts +71 -0
- package/dist/ffmpeg/fmp4.js +144 -0
- package/dist/ffmpeg/fmp4.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +1 -0
- package/dist/ffmpeg/index.js +1 -0
- package/dist/ffmpeg/index.js.map +1 -1
- package/dist/ffmpeg/options.d.ts +9 -1
- package/dist/ffmpeg/options.js +11 -3
- package/dist/ffmpeg/options.js.map +1 -1
- package/dist/ffmpeg/process.js +3 -3
- package/dist/ffmpeg/process.js.map +1 -1
- package/dist/ffmpeg/record.d.ts +51 -3
- package/dist/ffmpeg/record.js +31 -3
- package/dist/ffmpeg/record.js.map +1 -1
- package/dist/ffmpeg/rtp.js +4 -4
- package/dist/ffmpeg/rtp.js.map +1 -1
- package/dist/ffmpeg/stream.js +3 -4
- package/dist/ffmpeg/stream.js.map +1 -1
- package/dist/mqttclient.d.ts +1 -1
- package/dist/mqttclient.js +7 -5
- package/dist/mqttclient.js.map +1 -1
- package/dist/service.js +2 -0
- package/dist/service.js.map +1 -1
- package/dist/ui/featureoptions.js +2 -2
- package/dist/ui/featureoptions.js.map +1 -1
- package/dist/util.d.ts +2 -2
- package/dist/util.js +1 -1
- package/dist/util.js.map +1 -1
- package/package.json +9 -11
package/build/eslint-rules.mjs
CHANGED
|
@@ -2,8 +2,9 @@
|
|
|
2
2
|
*
|
|
3
3
|
* eslint-rules.mjs: Opinionated default linting rules for Homebridge plugins.
|
|
4
4
|
*/
|
|
5
|
+
import eslintJs from "@eslint/js";
|
|
5
6
|
import stylistic from "@stylistic/eslint-plugin";
|
|
6
|
-
import
|
|
7
|
+
import ts from "typescript-eslint";
|
|
7
8
|
|
|
8
9
|
const ruleBlankAfterOpenBrace = {
|
|
9
10
|
|
|
@@ -11,7 +12,7 @@ const ruleBlankAfterOpenBrace = {
|
|
|
11
12
|
|
|
12
13
|
function checkNode(node) {
|
|
13
14
|
|
|
14
|
-
const sourceCode = context.
|
|
15
|
+
const sourceCode = context.sourceCode;
|
|
15
16
|
const openBrace = sourceCode.getFirstToken(node);
|
|
16
17
|
const nextToken = sourceCode.getTokenAfter(openBrace);
|
|
17
18
|
|
|
@@ -121,7 +122,7 @@ const ruleParenComparisonsInLogical = {
|
|
|
121
122
|
|
|
122
123
|
create(context) {
|
|
123
124
|
|
|
124
|
-
const sourceCode = context.
|
|
125
|
+
const sourceCode = context.sourceCode;
|
|
125
126
|
|
|
126
127
|
// Comparison operators to wrap when used inside && / || compounds.
|
|
127
128
|
const comparisonOperators = new Set([ "==", "!=", "===", "!==", "<", "<=", ">", ">=", "in", "instanceof" ]);
|
|
@@ -201,7 +202,7 @@ const ruleCatchParenSpacing = {
|
|
|
201
202
|
|
|
202
203
|
create(context) {
|
|
203
204
|
|
|
204
|
-
const sourceCode = context.
|
|
205
|
+
const sourceCode = context.sourceCode;
|
|
205
206
|
|
|
206
207
|
return {
|
|
207
208
|
|
|
@@ -252,6 +253,20 @@ const ruleCatchParenSpacing = {
|
|
|
252
253
|
}
|
|
253
254
|
};
|
|
254
255
|
|
|
256
|
+
// Extract rules by name from a typescript-eslint config array. Throws if the named entry is missing so that a typescript-eslint version bump that renames config entries
|
|
257
|
+
// fails loudly rather than silently dropping rules.
|
|
258
|
+
function configRules(configs, name) {
|
|
259
|
+
|
|
260
|
+
const entry = configs.find((c) => c.name === name);
|
|
261
|
+
|
|
262
|
+
if(!entry) {
|
|
263
|
+
|
|
264
|
+
throw new Error("typescript-eslint config entry not found: " + name);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return entry.rules;
|
|
268
|
+
}
|
|
269
|
+
|
|
255
270
|
// ESlint plugins to use.
|
|
256
271
|
const plugins = {
|
|
257
272
|
|
|
@@ -265,14 +280,14 @@ const plugins = {
|
|
|
265
280
|
}
|
|
266
281
|
},
|
|
267
282
|
"@stylistic": stylistic,
|
|
268
|
-
"@typescript-eslint":
|
|
283
|
+
"@typescript-eslint": ts.plugin
|
|
269
284
|
};
|
|
270
285
|
|
|
271
286
|
// TypeScript-specific rules.
|
|
272
287
|
const tsRules = {
|
|
273
288
|
|
|
274
|
-
...
|
|
275
|
-
...
|
|
289
|
+
...configRules(ts.configs.strictTypeChecked, "typescript-eslint/strict-type-checked"),
|
|
290
|
+
...configRules(ts.configs.stylisticTypeChecked, "typescript-eslint/stylistic-type-checked"),
|
|
276
291
|
"@stylistic/member-delimiter-style": "warn",
|
|
277
292
|
"@typescript-eslint/await-thenable": "warn",
|
|
278
293
|
"@typescript-eslint/consistent-type-imports": "warn",
|
|
@@ -299,7 +314,7 @@ const tsRules = {
|
|
|
299
314
|
// JavaScript-specific rules.
|
|
300
315
|
const jsRules = {
|
|
301
316
|
|
|
302
|
-
...
|
|
317
|
+
...ts.configs.disableTypeChecked.rules,
|
|
303
318
|
"@typescript-eslint/no-floating-promises": "off",
|
|
304
319
|
"require-await": "warn"
|
|
305
320
|
};
|
|
@@ -307,7 +322,7 @@ const jsRules = {
|
|
|
307
322
|
// Rules that exist across both JavaScript and TypeScript files.
|
|
308
323
|
const commonRules = {
|
|
309
324
|
|
|
310
|
-
...
|
|
325
|
+
...ts.configs.eslintRecommended.rules,
|
|
311
326
|
"@hjdhjd/blank-line-after-open-brace": "warn",
|
|
312
327
|
"@hjdhjd/catch-paren-spacing": "warn",
|
|
313
328
|
"@hjdhjd/paren-comparisons-in-logical": "warn",
|
|
@@ -376,17 +391,121 @@ const commonRules = {
|
|
|
376
391
|
const globalsUi = Object.fromEntries([ "clearTimeout", "console", "container", "document", "fetch", "getComputedStyle", "homebridge", "setTimeout", "window" ]
|
|
377
392
|
.map(key => [ key, "readonly" ]));
|
|
378
393
|
|
|
379
|
-
export default
|
|
394
|
+
/* Build a ready-to-use ESLint flat config array. Consumers call this function and export default the result.
|
|
395
|
+
*
|
|
396
|
+
* @param {object} options - Configuration options.
|
|
397
|
+
* @param {string[]} options.ts - Glob patterns for TypeScript files (strict + stylistic type-checked rules).
|
|
398
|
+
* @param {string[]} options.js - Glob patterns for JavaScript files (disable-type-checked rules).
|
|
399
|
+
* @param {string[]} options.ui - Glob patterns for browser UI files (adds browser globals).
|
|
400
|
+
* @param {string[]} options.allowDefaultProject - Globs passed to parserOptions.projectService.allowDefaultProject.
|
|
401
|
+
* @param {string[]} options.ignores - Global ignore patterns (in addition to the hardcoded "dist" ignore on the common block).
|
|
402
|
+
* @param {object[]} options.extraConfigs - Additional flat config objects appended to the output.
|
|
403
|
+
* @returns {object[]} A flat config array suitable for `export default` in eslint.config.mjs. Block ordering is significant — do not reorder.
|
|
404
|
+
*/
|
|
405
|
+
function config({
|
|
406
|
+
allowDefaultProject = [],
|
|
407
|
+
extraConfigs = [],
|
|
408
|
+
ignores = [],
|
|
409
|
+
js = [],
|
|
410
|
+
ts: tsFiles = [],
|
|
411
|
+
ui = []
|
|
412
|
+
} = {}) {
|
|
413
|
+
|
|
414
|
+
const allFiles = [ ...tsFiles, ...js, ...ui ];
|
|
415
|
+
const configs = [];
|
|
416
|
+
|
|
417
|
+
// Global ignores block.
|
|
418
|
+
if(ignores.length > 0) {
|
|
419
|
+
|
|
420
|
+
configs.push({ ignores });
|
|
421
|
+
}
|
|
380
422
|
|
|
381
|
-
|
|
423
|
+
// Core ESLint recommended rules. This block must precede the TS/JS blocks so that their rule overrides (e.g., no-unused-vars: "off") take priority.
|
|
424
|
+
if(allFiles.length > 0) {
|
|
382
425
|
|
|
383
|
-
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
rules
|
|
426
|
+
configs.push(eslintJs.configs.recommended);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// TypeScript-specific rules.
|
|
430
|
+
if(tsFiles.length > 0) {
|
|
387
431
|
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
432
|
+
configs.push({
|
|
433
|
+
|
|
434
|
+
files: tsFiles,
|
|
435
|
+
rules: { ...tsRules }
|
|
436
|
+
});
|
|
391
437
|
}
|
|
392
|
-
|
|
438
|
+
|
|
439
|
+
// JavaScript-specific rules.
|
|
440
|
+
if(js.length > 0) {
|
|
441
|
+
|
|
442
|
+
configs.push({
|
|
443
|
+
|
|
444
|
+
files: js,
|
|
445
|
+
rules: { ...jsRules }
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
// Common rules applied to all linted files.
|
|
450
|
+
if(allFiles.length > 0) {
|
|
451
|
+
|
|
452
|
+
configs.push({
|
|
453
|
+
|
|
454
|
+
files: allFiles,
|
|
455
|
+
|
|
456
|
+
ignores: ["dist"],
|
|
457
|
+
|
|
458
|
+
languageOptions: {
|
|
459
|
+
|
|
460
|
+
ecmaVersion: "latest",
|
|
461
|
+
parser: ts.parser,
|
|
462
|
+
parserOptions: {
|
|
463
|
+
|
|
464
|
+
ecmaVersion: "latest",
|
|
465
|
+
|
|
466
|
+
projectService: {
|
|
467
|
+
|
|
468
|
+
allowDefaultProject,
|
|
469
|
+
defaultProject: "./tsconfig.json"
|
|
470
|
+
}
|
|
471
|
+
},
|
|
472
|
+
|
|
473
|
+
sourceType: "module"
|
|
474
|
+
},
|
|
475
|
+
|
|
476
|
+
linterOptions: {
|
|
477
|
+
|
|
478
|
+
reportUnusedDisableDirectives: "error"
|
|
479
|
+
},
|
|
480
|
+
|
|
481
|
+
plugins: { ...plugins },
|
|
482
|
+
|
|
483
|
+
rules: { ...commonRules }
|
|
484
|
+
});
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
// UI globals block.
|
|
488
|
+
if(ui.length > 0) {
|
|
489
|
+
|
|
490
|
+
configs.push({
|
|
491
|
+
|
|
492
|
+
files: ui,
|
|
493
|
+
|
|
494
|
+
languageOptions: {
|
|
495
|
+
|
|
496
|
+
globals: { ...globalsUi }
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
// Escape hatch for project-specific config blocks.
|
|
502
|
+
configs.push(...extraConfigs);
|
|
503
|
+
|
|
504
|
+
return configs;
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
// Default export is the config function.
|
|
508
|
+
export default config;
|
|
509
|
+
|
|
510
|
+
// Named exports for advanced customization or gradual migration.
|
|
511
|
+
export { commonRules, config, globalsUi, jsRules, plugins, tsRules };
|
package/dist/featureoptions.d.ts
CHANGED
|
@@ -100,9 +100,7 @@ export declare class FeatureOptions {
|
|
|
100
100
|
* const featureOpts = new FeatureOptions(categories, options, ["Enable.motion.detect"]);
|
|
101
101
|
* ```
|
|
102
102
|
*/
|
|
103
|
-
constructor(categories: FeatureCategoryEntry[], options:
|
|
104
|
-
[index: string]: FeatureOptionEntry[];
|
|
105
|
-
}, configuredOptions?: never[]);
|
|
103
|
+
constructor(categories: FeatureCategoryEntry[], options: Record<string, FeatureOptionEntry[]>, configuredOptions?: string[]);
|
|
106
104
|
/**
|
|
107
105
|
* Return a Bootstrap-specific color reference depending on the scope of a given feature option.
|
|
108
106
|
*
|
|
@@ -244,25 +242,19 @@ export declare class FeatureOptions {
|
|
|
244
242
|
*
|
|
245
243
|
* @returns Returns the current list of available feature option groups.
|
|
246
244
|
*/
|
|
247
|
-
get groups():
|
|
248
|
-
[index: string]: string[];
|
|
249
|
-
};
|
|
245
|
+
get groups(): Record<string, string[]>;
|
|
250
246
|
/**
|
|
251
247
|
* Return the list of available feature options.
|
|
252
248
|
*
|
|
253
249
|
* @returns Returns the current list of available feature options.
|
|
254
250
|
*/
|
|
255
|
-
get options():
|
|
256
|
-
[index: string]: FeatureOptionEntry[];
|
|
257
|
-
};
|
|
251
|
+
get options(): Record<string, FeatureOptionEntry[]>;
|
|
258
252
|
/**
|
|
259
253
|
* Set the list of available feature options.
|
|
260
254
|
*
|
|
261
255
|
* @param options - Array of available feature options.
|
|
262
256
|
*/
|
|
263
|
-
set options(options:
|
|
264
|
-
[index: string]: FeatureOptionEntry[];
|
|
265
|
-
});
|
|
257
|
+
set options(options: Record<string, FeatureOptionEntry[]>);
|
|
266
258
|
private generateDefaults;
|
|
267
259
|
private optionInfo;
|
|
268
260
|
private isOptionEnabled;
|
package/dist/featureoptions.js
CHANGED
|
@@ -135,10 +135,10 @@ export class FeatureOptions {
|
|
|
135
135
|
expandOption(category, option) {
|
|
136
136
|
const categoryName = (typeof category === "string") ? category : category.name;
|
|
137
137
|
const optionName = (typeof option === "string") ? option : option.name;
|
|
138
|
-
if (!categoryName
|
|
138
|
+
if (!categoryName.length) {
|
|
139
139
|
return "";
|
|
140
140
|
}
|
|
141
|
-
return (!optionName
|
|
141
|
+
return (!optionName.length) ? categoryName : categoryName + "." + optionName;
|
|
142
142
|
}
|
|
143
143
|
/**
|
|
144
144
|
* Parse a floating point feature option value.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"featureoptions.js","sourceRoot":"","sources":["../src/featureoptions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA0DH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,MAAM,OAAO,cAAc;IAEzB;;OAEG;IACI,kBAAkB,CAAU;IAE3B,WAAW,CAAyB;IACpC,kBAAkB,CAAW;IAC7B,OAAO,
|
|
1
|
+
{"version":3,"file":"featureoptions.js","sourceRoot":"","sources":["../src/featureoptions.ts"],"names":[],"mappings":"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"}
|
package/dist/ffmpeg/codecs.js
CHANGED
|
@@ -83,7 +83,7 @@ export class FfmpegCodecs {
|
|
|
83
83
|
constructor(options) {
|
|
84
84
|
this.ffmpegExec = options.ffmpegExec ?? "ffmpeg";
|
|
85
85
|
this.ffmpegCodecs = {};
|
|
86
|
-
this.ffmpegHwAccels =
|
|
86
|
+
this.ffmpegHwAccels = new Set();
|
|
87
87
|
this.log = options.log;
|
|
88
88
|
this.verbose = options.verbose ?? false;
|
|
89
89
|
// Detect our host system type.
|
|
@@ -195,7 +195,7 @@ export class FfmpegCodecs {
|
|
|
195
195
|
* ```
|
|
196
196
|
*/
|
|
197
197
|
hasHwAccel(accel) {
|
|
198
|
-
return this.ffmpegHwAccels
|
|
198
|
+
return this.ffmpegHwAccels.has(accel.toLowerCase());
|
|
199
199
|
}
|
|
200
200
|
/**
|
|
201
201
|
* Returns the amount of GPU memory available on the host system, in megabytes.
|
|
@@ -253,7 +253,7 @@ export class FfmpegCodecs {
|
|
|
253
253
|
continue;
|
|
254
254
|
}
|
|
255
255
|
// We've found a hardware acceleration method, let's add it.
|
|
256
|
-
this.ffmpegHwAccels
|
|
256
|
+
this.ffmpegHwAccels.add(accel.toLowerCase());
|
|
257
257
|
}
|
|
258
258
|
}))) {
|
|
259
259
|
return false;
|
|
@@ -261,12 +261,12 @@ export class FfmpegCodecs {
|
|
|
261
261
|
// Let's test to ensure that just because we have a codec or capability available to us, it doesn't necessarily mean that the user has the hardware capabilities
|
|
262
262
|
// needed to use it, resulting in an FFmpeg error. We catch that here and prevent those capabilities from being exposed unless both software and hardware capabilities
|
|
263
263
|
// enable it. This simple test, generates a one-second video that is processed by the requested codec. If it fails, we discard the codec.
|
|
264
|
-
for (const accel of
|
|
264
|
+
for (const accel of this.ffmpegHwAccels) {
|
|
265
265
|
// eslint-disable-next-line no-await-in-loop
|
|
266
266
|
if (!(await this.probeCmd(this.ffmpegExec, [
|
|
267
267
|
"-hide_banner", "-hwaccel", accel, "-v", "quiet", "-t", "1", "-f", "lavfi", "-i", "color=black:1920x1080", "-c:v", "libx264", "-f", "null", "-"
|
|
268
268
|
], () => { }, true))) {
|
|
269
|
-
|
|
269
|
+
this.ffmpegHwAccels.delete(accel);
|
|
270
270
|
if (this.verbose) {
|
|
271
271
|
this.log.error("Hardware-accelerated decoding and encoding using %s will be unavailable: unable to successfully validate capabilities.", accel);
|
|
272
272
|
}
|
|
@@ -311,9 +311,9 @@ export class FfmpegCodecs {
|
|
|
311
311
|
// Identify what generation of Apple Silicon we have.
|
|
312
312
|
if (cpus()[0].model.includes("Apple")) {
|
|
313
313
|
// Extract the CPU model.
|
|
314
|
-
const cpuModel =
|
|
314
|
+
const cpuModel = /Apple M(\d+) .*/i.exec(cpus()[0].model);
|
|
315
315
|
this._cpuGeneration = 0;
|
|
316
|
-
if (cpuModel
|
|
316
|
+
if (cpuModel?.[1]) {
|
|
317
317
|
this._cpuGeneration = Number(cpuModel[1]);
|
|
318
318
|
}
|
|
319
319
|
}
|
|
@@ -335,9 +335,9 @@ export class FfmpegCodecs {
|
|
|
335
335
|
// Identify what generation of Intel CPU we have if we're on Intel.
|
|
336
336
|
if (cpus()[0].model.includes("Intel")) {
|
|
337
337
|
// Extract the CPU model.
|
|
338
|
-
const cpuModel =
|
|
338
|
+
const cpuModel = /Intel.*Core.*i\d+-(\d{3,5})/i.exec(cpus()[0].model);
|
|
339
339
|
this._cpuGeneration = 0;
|
|
340
|
-
if (cpuModel
|
|
340
|
+
if (cpuModel?.[1]) {
|
|
341
341
|
// Grab the individual SKU as both a number and string.
|
|
342
342
|
const skuStr = cpuModel[1];
|
|
343
343
|
const skuNum = Number(skuStr);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../src/ffmpeg/codecs.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAA0B,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACtE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG7C,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,IAAI,MAAM,WAAW,CAAC;AAyB7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,OAAO,YAAY;IAEvB;;OAEG;IACa,UAAU,CAAS;IAE3B,cAAc,CAAU;IACxB,OAAO,CAAU;IACjB,WAAW,CAAU;IACrB,cAAc,CAAU;IACf,GAAG,CAAoC;IACvC,YAAY,
|
|
1
|
+
{"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../src/ffmpeg/codecs.ts"],"names":[],"mappings":"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"}
|
package/dist/ffmpeg/exec.d.ts
CHANGED
|
@@ -28,11 +28,11 @@ import type { Nullable } from "../util.js";
|
|
|
28
28
|
*
|
|
29
29
|
* @category FFmpeg
|
|
30
30
|
*/
|
|
31
|
-
export
|
|
31
|
+
export interface ProcessResult {
|
|
32
32
|
exitCode: Nullable<number>;
|
|
33
33
|
stderr: Buffer;
|
|
34
34
|
stdout: Buffer;
|
|
35
|
-
}
|
|
35
|
+
}
|
|
36
36
|
/**
|
|
37
37
|
* Executes arbitrary FFmpeg commands and returns the results.
|
|
38
38
|
*
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ISO BMFF (fMP4) box parsing utilities for working with fragmented MP4 data.
|
|
3
|
+
*
|
|
4
|
+
* This module provides lightweight, Buffer-based utilities for inspecting ISO Base Media File Format (ISO BMFF) structures commonly found in fragmented MP4 (fMP4)
|
|
5
|
+
* streams. It enables locating specific box types, splitting fragments into their moof/mdat components, and detecting keyframe (sync sample) segments by parsing the
|
|
6
|
+
* TRUN sample flags.
|
|
7
|
+
*
|
|
8
|
+
* These utilities operate on complete Buffers and are independent of FFmpeg processes or streaming pipelines.
|
|
9
|
+
*
|
|
10
|
+
* @module
|
|
11
|
+
*/
|
|
12
|
+
import type { Nullable } from "../util.js";
|
|
13
|
+
/**
|
|
14
|
+
* Describes the location of an ISO BMFF box within a buffer.
|
|
15
|
+
*
|
|
16
|
+
* @property offset - The byte offset of the box start (including the header).
|
|
17
|
+
* @property size - The total box size in bytes (including the header).
|
|
18
|
+
*
|
|
19
|
+
* @category FFmpeg
|
|
20
|
+
*/
|
|
21
|
+
export interface FMp4Box {
|
|
22
|
+
offset: number;
|
|
23
|
+
size: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Locates the first ISO BMFF box of a given type within a byte range.
|
|
27
|
+
*
|
|
28
|
+
* Walks the standard box headers (4-byte big-endian size + 4-byte ASCII type) starting at `start` and ending at `end`. Returns the offset and size of the first
|
|
29
|
+
* matching box, or `null` if no match is found. Does not handle extended-size boxes (64-bit size field) as these are uncommon in fMP4 livestream contexts.
|
|
30
|
+
*
|
|
31
|
+
* @param buffer - The buffer containing ISO BMFF box data.
|
|
32
|
+
* @param type - The 4-character ASCII box type to search for (e.g. "moof", "traf", "trun"). Must be exactly 4 characters.
|
|
33
|
+
* @param start - Optional. The byte offset to begin searching from. Defaults to 0.
|
|
34
|
+
* @param end - Optional. The byte offset to stop searching at. Defaults to the buffer length.
|
|
35
|
+
*
|
|
36
|
+
* @returns The box location, or `null` if not found.
|
|
37
|
+
*
|
|
38
|
+
* @category FFmpeg
|
|
39
|
+
*/
|
|
40
|
+
export declare function findBox(buffer: Buffer, type: string, start?: number, end?: number): Nullable<FMp4Box>;
|
|
41
|
+
/**
|
|
42
|
+
* Determines whether an fMP4 segment contains a keyframe (sync sample) by parsing the TRUN sample flags.
|
|
43
|
+
*
|
|
44
|
+
* Traverses the box hierarchy `moof -> traf -> trun` and inspects the sample flags to determine if the first sample is a sync sample (keyframe/IDR frame). Checks
|
|
45
|
+
* `first_sample_flags` first (the common case for fragments generated with `frag_keyframe`), then falls back to per-sample flags if available. Returns `false` if the
|
|
46
|
+
* box structure cannot be parsed or if the flags indicate a non-sync sample.
|
|
47
|
+
*
|
|
48
|
+
* @param segment - A buffer containing a complete fMP4 segment (typically a moof+mdat pair).
|
|
49
|
+
*
|
|
50
|
+
* @returns `true` if the segment's first sample is a sync sample (keyframe), `false` otherwise.
|
|
51
|
+
*
|
|
52
|
+
* @category FFmpeg
|
|
53
|
+
*/
|
|
54
|
+
export declare function isKeyframe(segment: Buffer): boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Splits an fMP4 fragment into its moof and mdat components.
|
|
57
|
+
*
|
|
58
|
+
* Locates the `mdat` box and returns everything before it as the moof portion (which includes the moof box and any preceding metadata boxes) and everything from the
|
|
59
|
+
* mdat box to the end of the fragment as the mdat portion. The returned buffers are subarray views into the original buffer, so no data is copied. Returns `null` if
|
|
60
|
+
* the mdat box cannot be found.
|
|
61
|
+
*
|
|
62
|
+
* @param fragment - A buffer containing a complete fMP4 fragment.
|
|
63
|
+
*
|
|
64
|
+
* @returns An object with `moof` and `mdat` sub-buffers, or `null` if the structure cannot be parsed.
|
|
65
|
+
*
|
|
66
|
+
* @category FFmpeg
|
|
67
|
+
*/
|
|
68
|
+
export declare function splitMoofMdat(fragment: Buffer): Nullable<{
|
|
69
|
+
mdat: Buffer;
|
|
70
|
+
moof: Buffer;
|
|
71
|
+
}>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* Copyright(C) 2017-2026, HJD (https://github.com/hjdhjd). All rights reserved.
|
|
2
|
+
*
|
|
3
|
+
* ffmpeg/fmp4.ts: ISO BMFF (fMP4) box parsing utilities.
|
|
4
|
+
*/
|
|
5
|
+
// ISO BMFF box header size: 4 bytes big-endian size + 4 bytes ASCII type.
|
|
6
|
+
const BOX_HEADER_SIZE = 8;
|
|
7
|
+
// TRUN fullbox header size: standard box header + 4 bytes version/flags + 4 bytes sample_count.
|
|
8
|
+
const TRUN_HEADER_SIZE = BOX_HEADER_SIZE + 8;
|
|
9
|
+
// TRUN box flags indicating the presence of optional fields.
|
|
10
|
+
const TRUN_FLAG_DATA_OFFSET = 0x000001;
|
|
11
|
+
const TRUN_FLAG_FIRST_SAMPLE_FLAGS = 0x000004;
|
|
12
|
+
const TRUN_FLAG_SAMPLE_DURATION = 0x000100;
|
|
13
|
+
const TRUN_FLAG_SAMPLE_SIZE = 0x000200;
|
|
14
|
+
const TRUN_FLAG_SAMPLE_FLAGS = 0x000400;
|
|
15
|
+
// Sample flags bit indicating a non-sync sample. When this bit is clear (0), the sample is a sync sample (keyframe/IDR).
|
|
16
|
+
const SAMPLE_FLAG_NON_SYNC = 0x00010000;
|
|
17
|
+
/**
|
|
18
|
+
* Locates the first ISO BMFF box of a given type within a byte range.
|
|
19
|
+
*
|
|
20
|
+
* Walks the standard box headers (4-byte big-endian size + 4-byte ASCII type) starting at `start` and ending at `end`. Returns the offset and size of the first
|
|
21
|
+
* matching box, or `null` if no match is found. Does not handle extended-size boxes (64-bit size field) as these are uncommon in fMP4 livestream contexts.
|
|
22
|
+
*
|
|
23
|
+
* @param buffer - The buffer containing ISO BMFF box data.
|
|
24
|
+
* @param type - The 4-character ASCII box type to search for (e.g. "moof", "traf", "trun"). Must be exactly 4 characters.
|
|
25
|
+
* @param start - Optional. The byte offset to begin searching from. Defaults to 0.
|
|
26
|
+
* @param end - Optional. The byte offset to stop searching at. Defaults to the buffer length.
|
|
27
|
+
*
|
|
28
|
+
* @returns The box location, or `null` if not found.
|
|
29
|
+
*
|
|
30
|
+
* @category FFmpeg
|
|
31
|
+
*/
|
|
32
|
+
export function findBox(buffer, type, start = 0, end) {
|
|
33
|
+
const limit = end ?? buffer.length;
|
|
34
|
+
// Encode the target type as a 32-bit integer for comparison, avoiding string allocation on every box visited. Box types in ISO BMFF are always exactly 4 ASCII bytes.
|
|
35
|
+
if (type.length !== 4) {
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
const target = ((type.charCodeAt(0) << 24) | (type.charCodeAt(1) << 16) | (type.charCodeAt(2) << 8) | type.charCodeAt(3)) >>> 0;
|
|
39
|
+
let offset = start;
|
|
40
|
+
// Walk boxes by reading each header: 4 bytes size (big-endian) + 4 bytes type.
|
|
41
|
+
while ((offset + BOX_HEADER_SIZE) <= limit) {
|
|
42
|
+
const size = buffer.readUInt32BE(offset);
|
|
43
|
+
// A valid box must be at least the header size and must not extend beyond the search range. Size values below the header size indicate corruption, misalignment,
|
|
44
|
+
// extended-size boxes (size === 1), or open-ended boxes (size === 0) - none of which are supported in this context.
|
|
45
|
+
if ((size < BOX_HEADER_SIZE) || (size > (limit - offset))) {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
// Compare the box type as a 32-bit integer to avoid allocating a string on every iteration.
|
|
49
|
+
if (buffer.readUInt32BE(offset + 4) === target) {
|
|
50
|
+
return { offset, size };
|
|
51
|
+
}
|
|
52
|
+
// Advance to the next box.
|
|
53
|
+
offset += size;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Determines whether an fMP4 segment contains a keyframe (sync sample) by parsing the TRUN sample flags.
|
|
59
|
+
*
|
|
60
|
+
* Traverses the box hierarchy `moof -> traf -> trun` and inspects the sample flags to determine if the first sample is a sync sample (keyframe/IDR frame). Checks
|
|
61
|
+
* `first_sample_flags` first (the common case for fragments generated with `frag_keyframe`), then falls back to per-sample flags if available. Returns `false` if the
|
|
62
|
+
* box structure cannot be parsed or if the flags indicate a non-sync sample.
|
|
63
|
+
*
|
|
64
|
+
* @param segment - A buffer containing a complete fMP4 segment (typically a moof+mdat pair).
|
|
65
|
+
*
|
|
66
|
+
* @returns `true` if the segment's first sample is a sync sample (keyframe), `false` otherwise.
|
|
67
|
+
*
|
|
68
|
+
* @category FFmpeg
|
|
69
|
+
*/
|
|
70
|
+
export function isKeyframe(segment) {
|
|
71
|
+
// Locate the moof box at the top level.
|
|
72
|
+
const moof = findBox(segment, "moof");
|
|
73
|
+
if (!moof) {
|
|
74
|
+
return false;
|
|
75
|
+
}
|
|
76
|
+
// Locate the traf box inside the moof. Child boxes start after the parent's header.
|
|
77
|
+
const traf = findBox(segment, "traf", moof.offset + BOX_HEADER_SIZE, moof.offset + moof.size);
|
|
78
|
+
if (!traf) {
|
|
79
|
+
return false;
|
|
80
|
+
}
|
|
81
|
+
// Locate the trun box inside the traf.
|
|
82
|
+
const trun = findBox(segment, "trun", traf.offset + BOX_HEADER_SIZE, traf.offset + traf.size);
|
|
83
|
+
if (!trun) {
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
// The trun is a fullbox: after the standard box header come 4 bytes of version/flags and 4 bytes of sample_count. We need the full header to read the flags and
|
|
87
|
+
// determine which optional fields follow.
|
|
88
|
+
if (trun.size < TRUN_HEADER_SIZE) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
// Read the flags from the fullbox header. The version occupies the top byte and the flags occupy the lower 24 bits.
|
|
92
|
+
const flags = segment.readUInt32BE(trun.offset + BOX_HEADER_SIZE) & 0x00FFFFFF;
|
|
93
|
+
// Start after the trun header (box header + version/flags + sample_count).
|
|
94
|
+
let pos = trun.offset + TRUN_HEADER_SIZE;
|
|
95
|
+
// Skip the optional data_offset field if present.
|
|
96
|
+
if (flags & TRUN_FLAG_DATA_OFFSET) {
|
|
97
|
+
pos += 4;
|
|
98
|
+
}
|
|
99
|
+
// Check first_sample_flags if present. This is the most common path for fMP4 fragments generated with the frag_keyframe movflag, where each fragment starts at a
|
|
100
|
+
// keyframe and the first sample's flags are stored separately from the per-sample entries.
|
|
101
|
+
if (flags & TRUN_FLAG_FIRST_SAMPLE_FLAGS) {
|
|
102
|
+
if ((pos + 4) > (trun.offset + trun.size)) {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return (segment.readUInt32BE(pos) & SAMPLE_FLAG_NON_SYNC) === 0;
|
|
106
|
+
}
|
|
107
|
+
// Fall back to per-sample flags. The per-sample entry fields appear in a fixed order: duration, size, flags, composition time offset. We skip duration and size to
|
|
108
|
+
// reach the first sample's flags field.
|
|
109
|
+
if (flags & TRUN_FLAG_SAMPLE_FLAGS) {
|
|
110
|
+
if (flags & TRUN_FLAG_SAMPLE_DURATION) {
|
|
111
|
+
pos += 4;
|
|
112
|
+
}
|
|
113
|
+
if (flags & TRUN_FLAG_SAMPLE_SIZE) {
|
|
114
|
+
pos += 4;
|
|
115
|
+
}
|
|
116
|
+
if ((pos + 4) > (trun.offset + trun.size)) {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
return (segment.readUInt32BE(pos) & SAMPLE_FLAG_NON_SYNC) === 0;
|
|
120
|
+
}
|
|
121
|
+
// No sample flags information available in the trun...we can't determine keyframe status.
|
|
122
|
+
return false;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Splits an fMP4 fragment into its moof and mdat components.
|
|
126
|
+
*
|
|
127
|
+
* Locates the `mdat` box and returns everything before it as the moof portion (which includes the moof box and any preceding metadata boxes) and everything from the
|
|
128
|
+
* mdat box to the end of the fragment as the mdat portion. The returned buffers are subarray views into the original buffer, so no data is copied. Returns `null` if
|
|
129
|
+
* the mdat box cannot be found.
|
|
130
|
+
*
|
|
131
|
+
* @param fragment - A buffer containing a complete fMP4 fragment.
|
|
132
|
+
*
|
|
133
|
+
* @returns An object with `moof` and `mdat` sub-buffers, or `null` if the structure cannot be parsed.
|
|
134
|
+
*
|
|
135
|
+
* @category FFmpeg
|
|
136
|
+
*/
|
|
137
|
+
export function splitMoofMdat(fragment) {
|
|
138
|
+
const mdat = findBox(fragment, "mdat");
|
|
139
|
+
if (!mdat) {
|
|
140
|
+
return null;
|
|
141
|
+
}
|
|
142
|
+
return { mdat: fragment.subarray(mdat.offset), moof: fragment.subarray(0, mdat.offset) };
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=fmp4.js.map
|