feat: publish av-tools 0.1.0
This commit is contained in:
138
scripts/copy-ffmpeg-assets.mjs
Normal file
138
scripts/copy-ffmpeg-assets.mjs
Normal file
@@ -0,0 +1,138 @@
|
||||
import { createHash } from 'node:crypto';
|
||||
import { cp, mkdir, readFile, rm, writeFile } from 'node:fs/promises';
|
||||
import { dirname, join, relative } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
|
||||
const repositoryRoot = join(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
const expectedVersion = '0.12.10';
|
||||
const outputRoot = join(
|
||||
repositoryRoot,
|
||||
'public',
|
||||
'vendor',
|
||||
'ffmpeg',
|
||||
expectedVersion
|
||||
);
|
||||
|
||||
const packages = [
|
||||
{
|
||||
packageName: '@ffmpeg/core',
|
||||
mode: 'st',
|
||||
files: ['ffmpeg-core.js', 'ffmpeg-core.wasm'],
|
||||
},
|
||||
{
|
||||
packageName: '@ffmpeg/core-mt',
|
||||
mode: 'mt',
|
||||
files: ['ffmpeg-core.js', 'ffmpeg-core.wasm', 'ffmpeg-core.worker.js'],
|
||||
},
|
||||
];
|
||||
|
||||
const expectedHashes = new Map([
|
||||
[
|
||||
'@ffmpeg/core:ffmpeg-core.js',
|
||||
'67a48f11645f85439f3fde4f2119042c16b374b910206b7a7a24f342e28dcae3',
|
||||
],
|
||||
[
|
||||
'@ffmpeg/core:ffmpeg-core.wasm',
|
||||
'9f57947a5bd530d8f00c5b3f2cb2a3492faa7e5d823315342d6a8656d0a6b7b7',
|
||||
],
|
||||
[
|
||||
'@ffmpeg/core-mt:ffmpeg-core.js',
|
||||
'270a2e6ff945e173238610669a3f7132df5f9c52698a9bf708cf5c2ab6bda0de',
|
||||
],
|
||||
[
|
||||
'@ffmpeg/core-mt:ffmpeg-core.wasm',
|
||||
'be2c97605366b78f3f13e21b52e81a55a79e1f29c133b03a68ec187b1a2ec41a',
|
||||
],
|
||||
[
|
||||
'@ffmpeg/core-mt:ffmpeg-core.worker.js',
|
||||
'f77898d631dc010b45c29c23cb4379c611a7d7b131bf591d08a656bb729a4ca3',
|
||||
],
|
||||
]);
|
||||
|
||||
async function loadPackageVersion(packageName) {
|
||||
const packagePath = join(
|
||||
repositoryRoot,
|
||||
'node_modules',
|
||||
...packageName.split('/'),
|
||||
'package.json'
|
||||
);
|
||||
const parsed = JSON.parse(await readFile(packagePath, 'utf8'));
|
||||
if (parsed.version !== expectedVersion) {
|
||||
throw new Error(
|
||||
`${packageName} ${parsed.version ?? '<unknown>'} is installed; expected exactly ${expectedVersion}`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyAsset(packageName, mode, fileName) {
|
||||
const source = join(
|
||||
repositoryRoot,
|
||||
'node_modules',
|
||||
...packageName.split('/'),
|
||||
'dist',
|
||||
'esm',
|
||||
fileName
|
||||
);
|
||||
const destination = join(outputRoot, mode, fileName);
|
||||
const sourceBytes = await readFile(source).catch((error) => {
|
||||
throw new Error(`Required FFmpeg asset is missing: ${source}`, {
|
||||
cause: error,
|
||||
});
|
||||
});
|
||||
const sourceDigest = createHash('sha256').update(sourceBytes).digest('hex');
|
||||
const expectedDigest = expectedHashes.get(`${packageName}:${fileName}`);
|
||||
if (!expectedDigest || sourceDigest !== expectedDigest) {
|
||||
throw new Error(
|
||||
`Pinned FFmpeg asset checksum mismatch for ${packageName}/${fileName}`
|
||||
);
|
||||
}
|
||||
|
||||
await mkdir(dirname(destination), { recursive: true });
|
||||
await cp(source, destination, {
|
||||
dereference: true,
|
||||
errorOnExist: false,
|
||||
force: true,
|
||||
preserveTimestamps: false,
|
||||
});
|
||||
|
||||
const destinationBytes = await readFile(destination);
|
||||
if (!sourceBytes.equals(destinationBytes)) {
|
||||
throw new Error(`Copied FFmpeg asset differs from its source: ${fileName}`);
|
||||
}
|
||||
|
||||
return {
|
||||
path: relative(outputRoot, destination).replaceAll('\\', '/'),
|
||||
bytes: destinationBytes.byteLength,
|
||||
sha256: sourceDigest,
|
||||
};
|
||||
}
|
||||
|
||||
await rm(outputRoot, { force: true, recursive: true });
|
||||
|
||||
const assets = [];
|
||||
for (const entry of packages) {
|
||||
await loadPackageVersion(entry.packageName);
|
||||
for (const fileName of entry.files) {
|
||||
assets.push(await copyAsset(entry.packageName, entry.mode, fileName));
|
||||
}
|
||||
}
|
||||
|
||||
assets.sort((left, right) => left.path.localeCompare(right.path, 'en'));
|
||||
const versionManifest = {
|
||||
schemaVersion: 1,
|
||||
coreVersion: expectedVersion,
|
||||
packages: {
|
||||
'@ffmpeg/core': expectedVersion,
|
||||
'@ffmpeg/core-mt': expectedVersion,
|
||||
},
|
||||
assets,
|
||||
};
|
||||
|
||||
await writeFile(
|
||||
join(outputRoot, 'version.json'),
|
||||
`${JSON.stringify(versionManifest, null, 2)}\n`
|
||||
);
|
||||
|
||||
console.log(
|
||||
`Copied ${assets.length} pinned FFmpeg assets to ${relative(repositoryRoot, outputRoot)}`
|
||||
);
|
||||
Reference in New Issue
Block a user