@temelj/ffmpeg 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured.mjs","names":[],"sources":["../src/structured.ts"],"sourcesContent":["import type {\n MetadataSpecifier,\n OutputMetadataOptions as GeneratedOutputMetadataOptions,\n OutputOptions as GeneratedOutputOptions,\n} from \"./generated/options.ts\";\n\nexport interface MetadataAssignment {\n key: string;\n value: string | number | boolean;\n}\n\nexport interface MetadataMap {\n inputFileIndex: number;\n inputScope?: MetadataSpecifier;\n outputScope?: MetadataSpecifier;\n}\n\nexport interface ProgramDefinition {\n title?: string;\n programNum?: number;\n streams: Array<number | string>;\n}\n\nexport interface StreamGroupDefinition {\n inputFileId?: number;\n inputGroupId?: number;\n type?: string;\n id?: number | string;\n streams?: Array<number | string>;\n streamGroups?: Array<number | string>;\n options?: Record<string, string | number | boolean>;\n}\n\nexport interface StreamIdDefinition {\n outputStreamIndex: number;\n newValue: number | string;\n}\n\nexport interface DispositionDefinition {\n clear?: boolean;\n set?: string[];\n add?: string[];\n remove?: string[];\n}\n\nexport type ForceKeyFramesDefinition =\n | { mode: \"times\"; times: Array<string | number> }\n | { mode: \"expr\"; expr: string }\n | { mode: \"source\" }\n | { mode: \"scd_metadata\" };\n\nexport type MetadataValue = string | string[] | MetadataAssignment | MetadataAssignment[];\nexport type MetadataMapValue = string | string[] | MetadataMap | MetadataMap[];\nexport type ProgramValue = string | string[] | ProgramDefinition | ProgramDefinition[];\nexport type StreamGroupValue = string | string[] | StreamGroupDefinition | StreamGroupDefinition[];\nexport type StreamIdValue = string | string[] | StreamIdDefinition | StreamIdDefinition[];\nexport type DispositionValue = string | string[] | DispositionDefinition | DispositionDefinition[];\nexport type ForceKeyFramesValue = string | ForceKeyFramesDefinition;\n\nfunction isStringArray(value: unknown): value is string[] {\n return Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction ensureNonEmpty(value: string, label: string): string {\n if (value.length === 0) {\n throw new Error(`${label} cannot be empty`);\n }\n return value;\n}\n\nexport function serializeMetadataAssignments(\n value: MetadataValue | undefined,\n): string | string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\" || isStringArray(value)) {\n return value as string | string[];\n }\n\n const items = (Array.isArray(value) ? value : [value]) as MetadataAssignment[];\n const serialized = items.map(\n (item) => `${ensureNonEmpty(item.key, \"Metadata key\")}=${String(item.value)}`,\n );\n return serialized.length === 1 ? serialized[0] : serialized;\n}\n\nexport function serializeMetadataMaps(\n value: MetadataMapValue | undefined,\n): string | string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\" || isStringArray(value)) {\n return value as string | string[];\n }\n\n const items = (Array.isArray(value) ? value : [value]) as MetadataMap[];\n const serialized = items.map((item) => {\n const parts = [String(item.inputFileIndex)];\n if (item.inputScope) {\n parts.push(item.inputScope);\n }\n const source = parts.join(\":\");\n return item.outputScope ? `${source}:${item.outputScope}` : source;\n });\n return serialized.length === 1 ? serialized[0] : serialized;\n}\n\nexport function serializeProgramDefinitions(\n value: ProgramValue | undefined,\n): string | string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\" || isStringArray(value)) {\n return value as string | string[];\n }\n\n const items = (Array.isArray(value) ? value : [value]) as ProgramDefinition[];\n const serialized = items.map((item) => {\n if (item.streams.length === 0) {\n throw new Error(\"Program definition must include at least one stream\");\n }\n\n const parts: string[] = [];\n if (item.title !== undefined) parts.push(`title=${item.title}`);\n if (item.programNum !== undefined) parts.push(`program_num=${item.programNum}`);\n for (const stream of item.streams) {\n parts.push(`st=${stream}`);\n }\n return parts.join(\":\");\n });\n return serialized.length === 1 ? serialized[0] : serialized;\n}\n\nexport function serializeStreamGroupDefinitions(\n value: StreamGroupValue | undefined,\n): string | string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\" || isStringArray(value)) {\n return value as string | string[];\n }\n\n const items = (Array.isArray(value) ? value : [value]) as StreamGroupDefinition[];\n const serialized = items.map((item) => {\n const parts: string[] = [];\n\n if (item.inputFileId !== undefined || item.inputGroupId !== undefined) {\n if (item.inputFileId === undefined || item.inputGroupId === undefined) {\n throw new Error(\"Stream group input mapping requires both inputFileId and inputGroupId\");\n }\n parts.push(`map=${item.inputFileId}=${item.inputGroupId}`);\n }\n\n if (item.type !== undefined) {\n parts.push(`type=${item.type}`);\n }\n if (item.id !== undefined) {\n parts.push(`id=${item.id}`);\n }\n\n for (const stream of item.streams ?? []) {\n parts.push(`st=${stream}`);\n }\n\n for (const streamGroup of item.streamGroups ?? []) {\n parts.push(`stg=${streamGroup}`);\n }\n\n for (const [key, raw] of Object.entries(item.options ?? {})) {\n parts.push(`${key}=${String(raw)}`);\n }\n\n return parts.join(\":\");\n });\n return serialized.length === 1 ? serialized[0] : serialized;\n}\n\nexport function serializeStreamIds(\n value: StreamIdValue | undefined,\n): string | string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\" || isStringArray(value)) {\n return value as string | string[];\n }\n\n const items = (Array.isArray(value) ? value : [value]) as StreamIdDefinition[];\n const serialized = items.map((item) => `${item.outputStreamIndex}:${item.newValue}`);\n return serialized.length === 1 ? serialized[0] : serialized;\n}\n\nexport function serializeDispositions(\n value: DispositionValue | undefined,\n): string | string[] | undefined {\n if (value === undefined) {\n return undefined;\n }\n if (typeof value === \"string\" || isStringArray(value)) {\n return value as string | string[];\n }\n\n const items = (Array.isArray(value) ? value : [value]) as DispositionDefinition[];\n const serialized = items.map((item) => {\n if (item.clear) {\n if (\n (item.set?.length ?? 0) > 0 ||\n (item.add?.length ?? 0) > 0 ||\n (item.remove?.length ?? 0) > 0\n ) {\n throw new Error(\"Disposition definition cannot combine clear with set/add/remove\");\n }\n return \"0\";\n }\n\n if (\n (item.set?.length ?? 0) > 0 &&\n ((item.add?.length ?? 0) > 0 || (item.remove?.length ?? 0) > 0)\n ) {\n throw new Error(\"Disposition definition cannot combine set with add/remove\");\n }\n\n if (item.set && item.set.length > 0) {\n return item.set.join(\"+\");\n }\n\n const parts = [\n ...(item.add ?? []).map((flag: string) => `+${flag}`),\n ...(item.remove ?? []).map((flag: string) => `-${flag}`),\n ];\n\n if (parts.length === 0) {\n throw new Error(\"Disposition definition must include clear, set, add, or remove\");\n }\n\n return parts.join(\"\");\n });\n\n return serialized.length === 1 ? serialized[0] : serialized;\n}\n\nexport function serializeForceKeyFrames(\n value: ForceKeyFramesValue | undefined,\n): string | undefined {\n if (value === undefined || typeof value === \"string\") {\n return value;\n }\n\n switch (value.mode) {\n case \"times\":\n if (value.times.length === 0) {\n throw new Error(\"forceKeyFrames times mode requires at least one time\");\n }\n return value.times.map(String).join(\",\");\n case \"expr\":\n return `expr:${value.expr}`;\n case \"source\":\n return \"source\";\n case \"scd_metadata\":\n return \"scd_metadata\";\n }\n}\n\nexport function normalizeOutputMetadataOptions(\n options: GeneratedOutputMetadataOptions,\n): GeneratedOutputMetadataOptions {\n return {\n ...options,\n metadata: serializeMetadataAssignments(\n options.metadata as MetadataValue | undefined,\n ) as GeneratedOutputMetadataOptions[\"metadata\"],\n mapMetadata: serializeMetadataMaps(\n options.mapMetadata as MetadataMapValue | undefined,\n ) as GeneratedOutputMetadataOptions[\"mapMetadata\"],\n };\n}\n\nexport function normalizeOutputOptions(options: GeneratedOutputOptions): GeneratedOutputOptions {\n const metadataScopes =\n options.metadataScopes === undefined\n ? undefined\n : Object.fromEntries(\n Object.entries(options.metadataScopes)\n .filter(([, scopeOptions]) => scopeOptions !== undefined)\n .map(([scope, scopeOptions]) => [\n scope,\n normalizeOutputMetadataOptions(scopeOptions as GeneratedOutputMetadataOptions),\n ]),\n );\n\n return {\n ...options,\n metadata: serializeMetadataAssignments(\n options.metadata as MetadataValue | undefined,\n ) as GeneratedOutputOptions[\"metadata\"],\n mapMetadata: serializeMetadataMaps(\n options.mapMetadata as MetadataMapValue | undefined,\n ) as GeneratedOutputOptions[\"mapMetadata\"],\n disposition: serializeDispositions(\n options.disposition as DispositionValue | undefined,\n ) as GeneratedOutputOptions[\"disposition\"],\n forceKeyFrames: serializeForceKeyFrames(\n options.forceKeyFrames as ForceKeyFramesValue | undefined,\n ) as GeneratedOutputOptions[\"forceKeyFrames\"],\n program: serializeProgramDefinitions(\n options.program as ProgramValue | undefined,\n ) as GeneratedOutputOptions[\"program\"],\n streamGroup: serializeStreamGroupDefinitions(\n options.streamGroup as StreamGroupValue | undefined,\n ) as GeneratedOutputOptions[\"streamGroup\"],\n streamid: serializeStreamIds(\n options.streamid as StreamIdValue | undefined,\n ) as GeneratedOutputOptions[\"streamid\"],\n metadataScopes,\n };\n}\n"],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import { AspectRatio, Bitrate, Duration, FrameSize, GlobalOptions as GlobalOptions$1, InputOptions as InputOptions$1, InputStreamOptions as InputStreamOptions$1, LogLevel, MetadataOptionBag, MetadataSpecifier, OutputMetadataOptions as OutputMetadataOptions$1, OutputOptions as OutputOptions$1, OutputStreamOptions as OutputStreamOptions$1, RawOptionBag, SerializedOptionScalar, SerializedOptionValue, StreamOptionBag, StreamSpecifier, StreamType, Target, Vsync } from "./generated/options.mjs";
2
+ import { DispositionValue, ForceKeyFramesValue, MetadataMapValue, MetadataValue, ProgramValue, StreamGroupValue, StreamIdValue } from "./structured.mjs";
3
+
4
+ //#region src/types.d.ts
5
+ type StructuredOutputMetadataOptions = Omit<OutputMetadataOptions$1, "metadata" | "mapMetadata"> & {
6
+ metadata?: MetadataValue;
7
+ mapMetadata?: MetadataMapValue;
8
+ };
9
+ type InputOptions = InputOptions$1;
10
+ type GlobalOptions = GlobalOptions$1;
11
+ type InputStreamOptions = InputStreamOptions$1;
12
+ type OutputStreamOptions = OutputStreamOptions$1;
13
+ type OutputMetadataOptions = StructuredOutputMetadataOptions;
14
+ type OutputOptions = Omit<OutputOptions$1, "metadata" | "mapMetadata" | "disposition" | "forceKeyFrames" | "program" | "streamGroup" | "streamid" | "metadataScopes"> & {
15
+ metadata?: MetadataValue;
16
+ mapMetadata?: MetadataMapValue;
17
+ disposition?: DispositionValue;
18
+ forceKeyFrames?: ForceKeyFramesValue;
19
+ program?: ProgramValue;
20
+ streamGroup?: StreamGroupValue;
21
+ streamid?: StreamIdValue;
22
+ metadataScopes?: Partial<Record<MetadataSpecifier, StructuredOutputMetadataOptions>>;
23
+ };
24
+ //#endregion
25
+ export { type AspectRatio, type Bitrate, type Duration, type FrameSize, GlobalOptions, InputOptions, InputStreamOptions, type LogLevel, type MetadataOptionBag, type MetadataSpecifier, OutputMetadataOptions, OutputOptions, OutputStreamOptions, type RawOptionBag, type SerializedOptionScalar, type SerializedOptionValue, type StreamOptionBag, type StreamSpecifier, type StreamType, type Target, type Vsync };
26
+ //# sourceMappingURL=types.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.mts","names":[],"sources":["../src/types.ts"],"mappings":";;;;KAqCK,+BAAA,GAAkC,IAAA,CACrC,uBAAA;EAGA,QAAA,GAAW,aAAA;EACX,WAAA,GAAc,gBAAA;AAAA;AAAA,KAGJ,YAAA,GAAe,cAAqB;AAAA,KACpC,aAAA,GAAgB,eAAsB;AAAA,KACtC,kBAAA,GAAqB,oBAA2B;AAAA,KAChD,mBAAA,GAAsB,qBAA4B;AAAA,KAClD,qBAAA,GAAwB,+BAA+B;AAAA,KACvD,aAAA,GAAgB,IAAA,CAC1B,eAAA;EAUA,QAAA,GAAW,aAAA;EACX,WAAA,GAAc,gBAAA;EACd,WAAA,GAAc,gBAAA;EACd,cAAA,GAAiB,mBAAA;EACjB,OAAA,GAAU,YAAA;EACV,WAAA,GAAc,gBAAA;EACd,QAAA,GAAW,aAAA;EACX,cAAA,GAAiB,OAAA,CAAQ,MAAA,CAAO,iBAAA,EAAmB,+BAAA;AAAA"}
package/dist/types.mjs ADDED
@@ -0,0 +1 @@
1
+ export {};
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@temelj/ffmpeg",
3
+ "version": "0.1.0",
4
+ "description": "Type-safe fluent builder for ffmpeg.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "url": "https://github.com/tinrab/temelj"
8
+ },
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "type": "module",
13
+ "main": "./dist/mod.mjs",
14
+ "types": "./dist/mod.d.mts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/mod.d.mts",
18
+ "import": "./dist/mod.mjs"
19
+ }
20
+ },
21
+ "devDependencies": {
22
+ "@types/node": "25.9.1",
23
+ "cheerio": "^1.2.0",
24
+ "shx": "^0.4.0",
25
+ "tsdown": "^0.22.1",
26
+ "typescript": "^6.0.3",
27
+ "vitest": "^4.1.7"
28
+ },
29
+ "scripts": {
30
+ "script:scrape": "node --import tsx/esm ./scripts/scrape.ts",
31
+ "script:generate": "node --import tsx/esm ./scripts/generate.ts",
32
+ "build": "tsdown",
33
+ "test": "vitest run --config ./vitest.config.ts",
34
+ "typecheck": "tsc --noEmit",
35
+ "clean": "shx rm -rf dist"
36
+ }
37
+ }