feat: add basic web codecs

This commit is contained in:
2025-03-23 06:03:05 +08:00
parent 0b681d4fd1
commit 54edfd2fdc
26 changed files with 1690 additions and 562 deletions

View File

@@ -43,15 +43,15 @@ const EbmlTypeMetas = {
},
uinteger: {
code: 'Uint',
primitive: () => 'type.number',
primitive: () => 'type.number.or(type.bigint)',
default: (d: string): string => d,
primitiveStr: () => 'number',
primitiveStr: () => '(number | bigint)',
},
integer: {
code: 'Int',
primitive: () => 'type.number',
primitive: () => 'type.number.or(type.bigint)',
default: (d: string) => d,
primitiveStr: () => 'number',
primitiveStr: () => '(number | bigint)',
},
float: {
code: 'Float',
@@ -160,7 +160,7 @@ function extractElement(element: Element) {
);
assert(typeof path_ === 'string', `path of ${name} is not string ${element}`);
const path = path_.split('\\').filter(Boolean);
const path = path_.replace(/\\\+/g, '\\').split('\\').filter(Boolean);
const parentPath = path.at(-2);
const prefix = path.slice(0, -1);
const level = path.length - 1;
@@ -391,7 +391,7 @@ function generateMkvSchemaHierarchy(elements_: EbmlElementType[]) {
if (v.maxOccurs !== 1) {
expr = `${expr}.array()`;
if (v.maxOccurs !== 1 && v.minOccurs === 1 && !v.default) {
expr = `${expr}.atLeastLength(1)`
expr = `${expr}.atLeastLength(1)`;
}
idMulti.add(v.name);
}
@@ -401,9 +401,8 @@ function generateMkvSchemaHierarchy(elements_: EbmlElementType[]) {
} else {
childrenSchema.push(`export const ${v.name}Schema = match({
"${meta.primitiveStr(v.name)}[]": v => v.length > 0 ? v : [${meta.default(v.default)}],
"undefined": () => [${meta.default(v.default)}],
default: "assert"
});`);
default: () => [${meta.default(v.default)}],
}).optional();`);
expr = `${v.name}Schema`;
}
} else if (!v.minOccurs) {

View File

@@ -0,0 +1,54 @@
import { exec } from 'node:child_process';
import { promisify } from 'node:util';
import path from 'node:path';
import os from 'node:os';
import fsp from 'node:fs/promises';
async function downloadAndExtract() {
try {
// 目标目录
const targetDir = path.join(import.meta.dirname, '..', 'apps', 'mock', 'public', 'video', 'huge');
const url = 'https://sourceforge.net/projects/matroska/files/test_files/matroska_test_w1_1.zip/download';
const zipFile = 'matroska_test_w1_1.zip';
const platform = os.platform();
const execPromise = (cmd: string) => promisify(exec)(cmd, {
cwd: targetDir,
shell: platform === 'win32' ? 'powershell' : undefined
});
await fsp.mkdir(targetDir, { recursive: true })
console.log(`Working directory switched to: ${targetDir}`);
if (platform === 'win32') {
// Windows: 使用 PowerShell 的 Invoke-WebRequest 和 Expand-Archive
console.log('Downloading on Windows...');
await execPromise(`Invoke-WebRequest -Uri '${url}' -OutFile '${zipFile}' -UserAgent "wget"`);
console.log('Extracting on Windows...');
await execPromise(`Expand-Archive -Path '${zipFile}' -DestinationPath '.' -Force`);
console.log('Cleaning up...');
await execPromise(`rm '${zipFile}'`);
} else {
// *nix: 使用 curl 和 unzip
console.log('Downloading on *nix...');
await execPromise(`curl -L "${url}" -o "${zipFile}"`);
console.log('Extracting on *nix...');
await execPromise(`unzip -o "${zipFile}"`);
console.log('Cleaning up...');
await execPromise(`rm "${zipFile}"`);
}
console.log('Download and extraction completed successfully!');
} catch (error) {
console.error('An error occurred:', error);
throw error;
}
}
// 执行
downloadAndExtract().catch((err) => {
console.error(err)
process.exit(1);
});