@camstack/types 1.2.226 → 1.2.227
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/deps/ffmpeg-downloader.d.ts +31 -5
- package/dist/deps/index.d.ts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +48 -34
- package/dist/node.mjs +48 -35
- package/package.json +1 -1
|
@@ -1,10 +1,36 @@
|
|
|
1
1
|
import type { IScopedLogger } from '../interfaces/logging.js';
|
|
2
|
+
/**
|
|
3
|
+
* One artifact per platform+arch: the URL, how it is packed, and what the
|
|
4
|
+
* binary inside is SUPPOSED to be able to do.
|
|
5
|
+
*
|
|
6
|
+
* It is a table rather than two functions computing strings because the three
|
|
7
|
+
* facts belong together and drifted apart when they did not:
|
|
8
|
+
*
|
|
9
|
+
* - the darwin branch computed an arch and then discarded it, handing an
|
|
10
|
+
* Intel Mac an arm64 Mach-O it cannot execute under any translation;
|
|
11
|
+
* - a single `FFMPEG_VERSION = '7.1'` named the version of nothing — the linux
|
|
12
|
+
* URL is unversioned and serves 7.0.2 — so the inner path built from it never
|
|
13
|
+
* matched and only the extractor's recursive fallback saved it;
|
|
14
|
+
* - and nothing recorded what a download was expected to be capable of, which
|
|
15
|
+
* is how a build with no VAAPI at all served every transcode on this fleet
|
|
16
|
+
* for months (D536).
|
|
17
|
+
*
|
|
18
|
+
* `expectedHwaccels` is that missing claim. It is deliberately EMPTY for the
|
|
19
|
+
* linux static builds: they carry no hardware support and pretending otherwise
|
|
20
|
+
* would make the assertion a lie. That emptiness is the honest description of
|
|
21
|
+
* a portable build, and the reason a node that has an image prefers the image's
|
|
22
|
+
* ffmpeg over this one.
|
|
23
|
+
*/
|
|
24
|
+
export interface FfmpegArtifact {
|
|
25
|
+
readonly url: string;
|
|
26
|
+
readonly archiveFormat: 'zip' | 'tar.gz' | 'tar.xz';
|
|
27
|
+
/** `-hwaccels` names this artifact is built with. Empty = none, honestly. */
|
|
28
|
+
readonly expectedHwaccels: readonly string[];
|
|
29
|
+
}
|
|
30
|
+
/** The artifact for this node, or a refusal naming what was asked for. */
|
|
31
|
+
export declare function getFfmpegArtifact(platform: string, arch: string): FfmpegArtifact;
|
|
32
|
+
/** The URL alone, for a caller that wants nothing else. */
|
|
2
33
|
export declare function getFfmpegDownloadUrl(platform: string, arch: string): string;
|
|
3
|
-
export declare function getFfmpegArchiveInfo(platform: string): {
|
|
4
|
-
isArchive: boolean;
|
|
5
|
-
archiveFormat: 'zip' | 'tar.gz' | 'tar.xz';
|
|
6
|
-
archiveInnerPath: string;
|
|
7
|
-
};
|
|
8
34
|
/**
|
|
9
35
|
* Ensure an ffmpeg binary WE provide is available on this node, and report
|
|
10
36
|
* which one and what it can do.
|
package/dist/deps/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { ensureBinary, downloadBinary, findInPath, getPlatformInfo, buildBinaryPath, } from './binary-downloader.js';
|
|
2
|
-
export { ensureFfmpeg, getFfmpegDownloadUrl } from './ffmpeg-downloader.js';
|
|
2
|
+
export { ensureFfmpeg, getFfmpegArtifact, getFfmpegDownloadUrl } from './ffmpeg-downloader.js';
|
|
3
3
|
export { ensurePython, installPythonPackages, installPythonRequirements, getPythonDownloadUrl, PYTHON_VERSION, } from './python-downloader.js';
|
package/dist/node.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export type { PlatformInfo } from './deps/binary-downloader.js';
|
|
2
2
|
export { buildBinaryPath, downloadBinary, ensureBinary, findInPath, getPlatformInfo, } from './deps/binary-downloader.js';
|
|
3
|
-
export { ensureFfmpeg, getFfmpegDownloadUrl } from './deps/ffmpeg-downloader.js';
|
|
3
|
+
export { ensureFfmpeg, getFfmpegArtifact, getFfmpegDownloadUrl } from './deps/ffmpeg-downloader.js';
|
|
4
4
|
export { probeFfmpegBinary, parseFfmpegCapabilities, type FfmpegBinaryCapabilities, } from './ffmpeg/binary-capabilities.js';
|
|
5
5
|
export { ensurePython, getPythonDownloadUrl, installPythonPackages, installPythonRequirements, PYTHON_VERSION, } from './deps/python-downloader.js';
|
|
6
6
|
export type { Fmp4FragmentChildArgs, Fmp4FragmentChildDeps, } from './ffmpeg/fmp4-fragment-child.js';
|
package/dist/node.js
CHANGED
|
@@ -388,40 +388,42 @@ function bundledFfmpegPath(platform) {
|
|
|
388
388
|
* - Linux: https://johnvansickle.com/ffmpeg/ (static builds)
|
|
389
389
|
* - macOS: https://www.osxexperts.net/
|
|
390
390
|
*/
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
391
|
+
/**
|
|
392
|
+
* johnvansickle for linux (unversioned "release" URLs, so no version appears
|
|
393
|
+
* here), osxexperts for macOS — two different builds, and the Intel one is a
|
|
394
|
+
* different file at a different version from the arm one.
|
|
395
|
+
*/
|
|
396
|
+
var FFMPEG_ARTIFACTS = {
|
|
397
|
+
"linux-x64": {
|
|
398
|
+
url: "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz",
|
|
399
|
+
archiveFormat: "tar.xz",
|
|
400
|
+
expectedHwaccels: []
|
|
401
|
+
},
|
|
402
|
+
"linux-arm64": {
|
|
403
|
+
url: "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz",
|
|
404
|
+
archiveFormat: "tar.xz",
|
|
405
|
+
expectedHwaccels: []
|
|
406
|
+
},
|
|
407
|
+
"darwin-arm64": {
|
|
408
|
+
url: "https://www.osxexperts.net/ffmpeg71arm.zip",
|
|
409
|
+
archiveFormat: "zip",
|
|
410
|
+
expectedHwaccels: ["videotoolbox"]
|
|
411
|
+
},
|
|
412
|
+
"darwin-x64": {
|
|
413
|
+
url: "https://www.osxexperts.net/ffmpeg80intel.zip",
|
|
414
|
+
archiveFormat: "zip",
|
|
415
|
+
expectedHwaccels: ["videotoolbox"]
|
|
409
416
|
}
|
|
417
|
+
};
|
|
418
|
+
/** The artifact for this node, or a refusal naming what was asked for. */
|
|
419
|
+
function getFfmpegArtifact(platform, arch) {
|
|
420
|
+
const artifact = FFMPEG_ARTIFACTS[`${platform}-${arch}`];
|
|
421
|
+
if (!artifact) throw new Error(`Unsupported platform/architecture for ffmpeg: ${platform}-${arch}`);
|
|
422
|
+
return artifact;
|
|
410
423
|
}
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
isArchive: true,
|
|
415
|
-
archiveFormat: "tar.xz",
|
|
416
|
-
archiveInnerPath: `ffmpeg-${FFMPEG_VERSION}-amd64-static/ffmpeg`
|
|
417
|
-
};
|
|
418
|
-
case "darwin": return {
|
|
419
|
-
isArchive: true,
|
|
420
|
-
archiveFormat: "zip",
|
|
421
|
-
archiveInnerPath: "ffmpeg"
|
|
422
|
-
};
|
|
423
|
-
default: throw new Error(`Unsupported platform: ${platform}`);
|
|
424
|
-
}
|
|
424
|
+
/** The URL alone, for a caller that wants nothing else. */
|
|
425
|
+
function getFfmpegDownloadUrl(platform, arch) {
|
|
426
|
+
return getFfmpegArtifact(platform, arch).url;
|
|
425
427
|
}
|
|
426
428
|
/**
|
|
427
429
|
* Ensure an ffmpeg binary WE provide is available on this node, and report
|
|
@@ -450,13 +452,15 @@ async function ensureFfmpeg(dataDir, logger) {
|
|
|
450
452
|
exists: node_fs.existsSync
|
|
451
453
|
});
|
|
452
454
|
if (override !== void 0 && override.trim().length > 0 && chosen?.origin !== "override") logger.error(`${FFMPEG_PATH_ENV} names a binary that does not exist — ignoring it`, { meta: { [FFMPEG_PATH_ENV]: override } });
|
|
455
|
+
const artifact = chosen === null ? getFfmpegArtifact(platform, arch) : null;
|
|
453
456
|
const path = chosen?.path ?? await downloadBinary({
|
|
454
457
|
name: "ffmpeg",
|
|
455
|
-
url: getFfmpegDownloadUrl(platform, arch),
|
|
458
|
+
url: artifact?.url ?? getFfmpegDownloadUrl(platform, arch),
|
|
456
459
|
targetDir: depsDir,
|
|
457
460
|
targetName: `ffmpeg${ext}`,
|
|
458
461
|
logger,
|
|
459
|
-
|
|
462
|
+
isArchive: true,
|
|
463
|
+
archiveFormat: artifact?.archiveFormat ?? "tar.xz"
|
|
460
464
|
});
|
|
461
465
|
const capabilities = await probeFfmpegBinary(path);
|
|
462
466
|
logger.info("ffmpeg binary resolved", { meta: {
|
|
@@ -465,6 +469,15 @@ async function ensureFfmpeg(dataDir, logger) {
|
|
|
465
469
|
version: capabilities.version,
|
|
466
470
|
hwaccels: [...capabilities.hwaccels].join(",") || "none"
|
|
467
471
|
} });
|
|
472
|
+
if (artifact !== null) {
|
|
473
|
+
const missing = artifact.expectedHwaccels.filter((name) => !capabilities.hwaccels.has(name));
|
|
474
|
+
if (missing.length > 0) logger.error("the ffmpeg we downloaded cannot do what this artifact is supposed to — the source changed under us", { meta: {
|
|
475
|
+
url: artifact.url,
|
|
476
|
+
expected: artifact.expectedHwaccels.join(","),
|
|
477
|
+
missing: missing.join(","),
|
|
478
|
+
got: [...capabilities.hwaccels].join(",") || "none"
|
|
479
|
+
} });
|
|
480
|
+
}
|
|
468
481
|
return path;
|
|
469
482
|
}
|
|
470
483
|
//#endregion
|
|
@@ -1964,6 +1977,7 @@ exports.ensureBinary = ensureBinary;
|
|
|
1964
1977
|
exports.ensureFfmpeg = ensureFfmpeg;
|
|
1965
1978
|
exports.ensurePython = ensurePython;
|
|
1966
1979
|
exports.findInPath = findInPath;
|
|
1980
|
+
exports.getFfmpegArtifact = getFfmpegArtifact;
|
|
1967
1981
|
exports.getFfmpegDownloadUrl = getFfmpegDownloadUrl;
|
|
1968
1982
|
exports.getPlatformInfo = getPlatformInfo;
|
|
1969
1983
|
exports.getPythonDownloadUrl = getPythonDownloadUrl;
|
package/dist/node.mjs
CHANGED
|
@@ -365,40 +365,42 @@ function bundledFfmpegPath(platform) {
|
|
|
365
365
|
* - Linux: https://johnvansickle.com/ffmpeg/ (static builds)
|
|
366
366
|
* - macOS: https://www.osxexperts.net/
|
|
367
367
|
*/
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
368
|
+
/**
|
|
369
|
+
* johnvansickle for linux (unversioned "release" URLs, so no version appears
|
|
370
|
+
* here), osxexperts for macOS — two different builds, and the Intel one is a
|
|
371
|
+
* different file at a different version from the arm one.
|
|
372
|
+
*/
|
|
373
|
+
var FFMPEG_ARTIFACTS = {
|
|
374
|
+
"linux-x64": {
|
|
375
|
+
url: "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-amd64-static.tar.xz",
|
|
376
|
+
archiveFormat: "tar.xz",
|
|
377
|
+
expectedHwaccels: []
|
|
378
|
+
},
|
|
379
|
+
"linux-arm64": {
|
|
380
|
+
url: "https://johnvansickle.com/ffmpeg/releases/ffmpeg-release-arm64-static.tar.xz",
|
|
381
|
+
archiveFormat: "tar.xz",
|
|
382
|
+
expectedHwaccels: []
|
|
383
|
+
},
|
|
384
|
+
"darwin-arm64": {
|
|
385
|
+
url: "https://www.osxexperts.net/ffmpeg71arm.zip",
|
|
386
|
+
archiveFormat: "zip",
|
|
387
|
+
expectedHwaccels: ["videotoolbox"]
|
|
388
|
+
},
|
|
389
|
+
"darwin-x64": {
|
|
390
|
+
url: "https://www.osxexperts.net/ffmpeg80intel.zip",
|
|
391
|
+
archiveFormat: "zip",
|
|
392
|
+
expectedHwaccels: ["videotoolbox"]
|
|
386
393
|
}
|
|
394
|
+
};
|
|
395
|
+
/** The artifact for this node, or a refusal naming what was asked for. */
|
|
396
|
+
function getFfmpegArtifact(platform, arch) {
|
|
397
|
+
const artifact = FFMPEG_ARTIFACTS[`${platform}-${arch}`];
|
|
398
|
+
if (!artifact) throw new Error(`Unsupported platform/architecture for ffmpeg: ${platform}-${arch}`);
|
|
399
|
+
return artifact;
|
|
387
400
|
}
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
isArchive: true,
|
|
392
|
-
archiveFormat: "tar.xz",
|
|
393
|
-
archiveInnerPath: `ffmpeg-${FFMPEG_VERSION}-amd64-static/ffmpeg`
|
|
394
|
-
};
|
|
395
|
-
case "darwin": return {
|
|
396
|
-
isArchive: true,
|
|
397
|
-
archiveFormat: "zip",
|
|
398
|
-
archiveInnerPath: "ffmpeg"
|
|
399
|
-
};
|
|
400
|
-
default: throw new Error(`Unsupported platform: ${platform}`);
|
|
401
|
-
}
|
|
401
|
+
/** The URL alone, for a caller that wants nothing else. */
|
|
402
|
+
function getFfmpegDownloadUrl(platform, arch) {
|
|
403
|
+
return getFfmpegArtifact(platform, arch).url;
|
|
402
404
|
}
|
|
403
405
|
/**
|
|
404
406
|
* Ensure an ffmpeg binary WE provide is available on this node, and report
|
|
@@ -427,13 +429,15 @@ async function ensureFfmpeg(dataDir, logger) {
|
|
|
427
429
|
exists: existsSync
|
|
428
430
|
});
|
|
429
431
|
if (override !== void 0 && override.trim().length > 0 && chosen?.origin !== "override") logger.error(`${FFMPEG_PATH_ENV} names a binary that does not exist — ignoring it`, { meta: { [FFMPEG_PATH_ENV]: override } });
|
|
432
|
+
const artifact = chosen === null ? getFfmpegArtifact(platform, arch) : null;
|
|
430
433
|
const path = chosen?.path ?? await downloadBinary({
|
|
431
434
|
name: "ffmpeg",
|
|
432
|
-
url: getFfmpegDownloadUrl(platform, arch),
|
|
435
|
+
url: artifact?.url ?? getFfmpegDownloadUrl(platform, arch),
|
|
433
436
|
targetDir: depsDir,
|
|
434
437
|
targetName: `ffmpeg${ext}`,
|
|
435
438
|
logger,
|
|
436
|
-
|
|
439
|
+
isArchive: true,
|
|
440
|
+
archiveFormat: artifact?.archiveFormat ?? "tar.xz"
|
|
437
441
|
});
|
|
438
442
|
const capabilities = await probeFfmpegBinary(path);
|
|
439
443
|
logger.info("ffmpeg binary resolved", { meta: {
|
|
@@ -442,6 +446,15 @@ async function ensureFfmpeg(dataDir, logger) {
|
|
|
442
446
|
version: capabilities.version,
|
|
443
447
|
hwaccels: [...capabilities.hwaccels].join(",") || "none"
|
|
444
448
|
} });
|
|
449
|
+
if (artifact !== null) {
|
|
450
|
+
const missing = artifact.expectedHwaccels.filter((name) => !capabilities.hwaccels.has(name));
|
|
451
|
+
if (missing.length > 0) logger.error("the ffmpeg we downloaded cannot do what this artifact is supposed to — the source changed under us", { meta: {
|
|
452
|
+
url: artifact.url,
|
|
453
|
+
expected: artifact.expectedHwaccels.join(","),
|
|
454
|
+
missing: missing.join(","),
|
|
455
|
+
got: [...capabilities.hwaccels].join(",") || "none"
|
|
456
|
+
} });
|
|
457
|
+
}
|
|
445
458
|
return path;
|
|
446
459
|
}
|
|
447
460
|
//#endregion
|
|
@@ -1924,4 +1937,4 @@ function resolveExportFingerprint(input) {
|
|
|
1924
1937
|
return input.persisted ?? input.fresh;
|
|
1925
1938
|
}
|
|
1926
1939
|
//#endregion
|
|
1927
|
-
export { ChildCostRegistry, FfmpegProcess, FilesystemStorageProvider, Fmp4FragmentChild, Fmp4FragmentPlane, NO_COST_CLAIM, PYTHON_VERSION, buildBinaryPath, canonicalDeviceFingerprint, canonicalHash, containsOrEquals, diffExportTargets, downloadBinary, ensureBinary, ensureFfmpeg, ensurePython, findInPath, getFfmpegDownloadUrl, getPlatformInfo, getPythonDownloadUrl, installPythonPackages, installPythonRequirements, nodeProcStatReader, parseFfmpegCapabilities, parseProcCpuSeconds, parseProcRssBytes, physicalRootOf, probeFfmpegBinary, readProcessCost, resolveExportFingerprint, signExpiringUrl, verifyExpiringUrl };
|
|
1940
|
+
export { ChildCostRegistry, FfmpegProcess, FilesystemStorageProvider, Fmp4FragmentChild, Fmp4FragmentPlane, NO_COST_CLAIM, PYTHON_VERSION, buildBinaryPath, canonicalDeviceFingerprint, canonicalHash, containsOrEquals, diffExportTargets, downloadBinary, ensureBinary, ensureFfmpeg, ensurePython, findInPath, getFfmpegArtifact, getFfmpegDownloadUrl, getPlatformInfo, getPythonDownloadUrl, installPythonPackages, installPythonRequirements, nodeProcStatReader, parseFfmpegCapabilities, parseProcCpuSeconds, parseProcRssBytes, physicalRootOf, probeFfmpegBinary, readProcessCost, resolveExportFingerprint, signExpiringUrl, verifyExpiringUrl };
|