@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,206 @@
1
+ //#region src/filter-graph.ts
2
+ function escapeFilterValue(value) {
3
+ if (typeof value === "boolean") return value ? "1" : "0";
4
+ return String(value);
5
+ }
6
+ function serializeFilter(spec) {
7
+ const parts = [];
8
+ if (spec.positional && spec.positional.length > 0) parts.push(spec.positional.map(escapeFilterValue).join(":"));
9
+ if (spec.named) {
10
+ const entries = Object.entries(spec.named).filter(([, value]) => value !== void 0).map(([key, value]) => `${key}=${escapeFilterValue(value)}`);
11
+ if (entries.length > 0) parts.push(...entries);
12
+ }
13
+ if (parts.length === 0) return spec.name;
14
+ return `${spec.name}=${parts.join(":")}`;
15
+ }
16
+ function joinInputs(inputs) {
17
+ return inputs.map((stream) => stream.toString()).join("");
18
+ }
19
+ function joinOutputs(outputs) {
20
+ return outputs.map((label) => `[${label}]`).join("");
21
+ }
22
+ let autoLabelId = 0;
23
+ function nextAutoLabel(prefix) {
24
+ const label = `${prefix}${autoLabelId}`;
25
+ autoLabelId += 1;
26
+ return label;
27
+ }
28
+ function resetFilterGraphLabelCounter() {
29
+ autoLabelId = 0;
30
+ }
31
+ var FilterGraphStream = class {
32
+ label;
33
+ mediaType;
34
+ constructor(label, mediaType) {
35
+ this.label = label;
36
+ this.mediaType = mediaType;
37
+ }
38
+ toString() {
39
+ return `[${this.label}]`;
40
+ }
41
+ };
42
+ var FilterGraphChain = class {
43
+ filters = [];
44
+ graph;
45
+ inputs;
46
+ outputMediaTypes;
47
+ constructor(graph, inputs, outputMediaTypes) {
48
+ this.graph = graph;
49
+ this.inputs = inputs;
50
+ this.outputMediaTypes = outputMediaTypes;
51
+ }
52
+ raw(filter) {
53
+ this.filters.push(filter);
54
+ return this;
55
+ }
56
+ filter(name, positional = [], named = {}) {
57
+ this.filters.push(serializeFilter({
58
+ name,
59
+ positional,
60
+ named
61
+ }));
62
+ return this;
63
+ }
64
+ scale(width, height, named = {}) {
65
+ return this.filter("scale", [width, height], named);
66
+ }
67
+ fps(rate) {
68
+ return this.filter("fps", [rate]);
69
+ }
70
+ format(pixelFormat) {
71
+ return this.filter("format", [pixelFormat]);
72
+ }
73
+ trim(options) {
74
+ return this.filter("trim", [], {
75
+ start: options.start,
76
+ end: options.end,
77
+ duration: options.duration,
78
+ start_frame: options.startFrame,
79
+ end_frame: options.endFrame
80
+ });
81
+ }
82
+ setpts(expression) {
83
+ return this.filter("setpts", [expression]);
84
+ }
85
+ asetpts(expression) {
86
+ return this.filter("asetpts", [expression]);
87
+ }
88
+ hflip() {
89
+ return this.filter("hflip");
90
+ }
91
+ vflip() {
92
+ return this.filter("vflip");
93
+ }
94
+ volume(value) {
95
+ return this.filter("volume", [value]);
96
+ }
97
+ atempo(value) {
98
+ return this.filter("atempo", [value]);
99
+ }
100
+ split(...labels) {
101
+ const outputLabels = labels.length > 0 ? labels : [nextAutoLabel("v"), nextAutoLabel("v")];
102
+ return this.commit(outputLabels, outputLabels.map(() => this.outputMediaTypes[0] ?? "unknown"), serializeFilter({
103
+ name: "split",
104
+ named: { outputs: outputLabels.length }
105
+ }));
106
+ }
107
+ asplit(...labels) {
108
+ const outputLabels = labels.length > 0 ? labels : [nextAutoLabel("a"), nextAutoLabel("a")];
109
+ return this.commit(outputLabels, outputLabels.map(() => "audio"), serializeFilter({
110
+ name: "asplit",
111
+ named: { outputs: outputLabels.length }
112
+ }));
113
+ }
114
+ label(label) {
115
+ return this.commit([label], [this.outputMediaTypes[0] ?? "unknown"])[0];
116
+ }
117
+ labels(...labels) {
118
+ const outputLabels = labels.length > 0 ? labels : [nextAutoLabel("out")];
119
+ return this.commit(outputLabels, outputLabels.map((_, index) => this.outputMediaTypes[index] ?? this.outputMediaTypes[0] ?? "unknown"));
120
+ }
121
+ autoLabel(prefix) {
122
+ const mediaType = this.outputMediaTypes[0] ?? "unknown";
123
+ const fallbackPrefix = prefix ?? (mediaType === "audio" ? "a" : mediaType === "video" ? "v" : "out");
124
+ return this.label(nextAutoLabel(fallbackPrefix));
125
+ }
126
+ commit(labels, outputMediaTypes, terminalFilter) {
127
+ const chain = [...this.filters];
128
+ if (terminalFilter) chain.push(terminalFilter);
129
+ if (chain.length === 0) throw new Error("Cannot label an empty filter graph chain");
130
+ this.graph.addSegment(`${joinInputs(this.inputs)}${chain.join(",")}${joinOutputs(labels)}`, labels);
131
+ return labels.map((label, index) => new FilterGraphStream(label, outputMediaTypes[index] ?? "unknown"));
132
+ }
133
+ };
134
+ var FilterGraph = class {
135
+ segments = [];
136
+ outputLabels = /* @__PURE__ */ new Set();
137
+ addSegment(segment, labels) {
138
+ for (const label of labels) {
139
+ if (this.outputLabels.has(label)) throw new Error(`Duplicate filter graph output label "${label}"`);
140
+ this.outputLabels.add(label);
141
+ }
142
+ this.segments.push(segment);
143
+ }
144
+ hasOutputLabel(label) {
145
+ return this.outputLabels.has(label);
146
+ }
147
+ getOutputLabels() {
148
+ return [...this.outputLabels];
149
+ }
150
+ input(index, streamType, streamIndex) {
151
+ return new FilterGraphStream(streamType === void 0 ? String(index) : streamIndex === void 0 ? `${index}:${streamType}` : `${index}:${streamType}:${streamIndex}`, streamType === "v" ? "video" : streamType === "a" ? "audio" : "unknown");
152
+ }
153
+ videoInput(index, streamIndex) {
154
+ return new FilterGraphChain(this, [this.input(index, "v", streamIndex)], ["video"]);
155
+ }
156
+ audioInput(index, streamIndex) {
157
+ return new FilterGraphChain(this, [this.input(index, "a", streamIndex)], ["audio"]);
158
+ }
159
+ from(...streams) {
160
+ const mediaType = streams[0]?.mediaType ?? "unknown";
161
+ return new FilterGraphChain(this, streams, [mediaType]);
162
+ }
163
+ overlay(main, overlay, options = {}) {
164
+ return new FilterGraphChain(this, [main, overlay], ["video"]).filter("overlay", [], {
165
+ x: options.x,
166
+ y: options.y,
167
+ eof_action: options.eofAction,
168
+ shortest: options.shortest,
169
+ repeatlast: options.repeatlast
170
+ });
171
+ }
172
+ amerge(...streams) {
173
+ return new FilterGraphChain(this, streams, ["audio"]).filter("amerge", [], { inputs: streams.length });
174
+ }
175
+ amix(streams, options = {}) {
176
+ return new FilterGraphChain(this, streams, ["audio"]).filter("amix", [], {
177
+ inputs: options.inputs ?? streams.length,
178
+ duration: options.duration,
179
+ dropout_transition: options.dropoutTransition,
180
+ normalize: options.normalize
181
+ });
182
+ }
183
+ concat(streams, options) {
184
+ const outputMediaTypes = [];
185
+ const videoStreams = options.videoStreams ?? 1;
186
+ const audioStreams = options.audioStreams ?? 0;
187
+ for (let index = 0; index < videoStreams; index += 1) outputMediaTypes.push("video");
188
+ for (let index = 0; index < audioStreams; index += 1) outputMediaTypes.push("audio");
189
+ return new FilterGraphChain(this, streams, outputMediaTypes.length > 0 ? outputMediaTypes : ["unknown"]).filter("concat", [], {
190
+ n: options.segments,
191
+ v: videoStreams,
192
+ a: audioStreams,
193
+ unsafe: options.unsafe
194
+ });
195
+ }
196
+ toString() {
197
+ return this.segments.join(";");
198
+ }
199
+ };
200
+ function filterGraph() {
201
+ return new FilterGraph();
202
+ }
203
+ //#endregion
204
+ export { FilterGraph, FilterGraphStream, filterGraph, resetFilterGraphLabelCounter };
205
+
206
+ //# sourceMappingURL=filter-graph.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"filter-graph.mjs","names":[],"sources":["../src/filter-graph.ts"],"sourcesContent":["export type FilterGraphMediaType = \"video\" | \"audio\" | \"unknown\";\n\nexport type FilterScalar = string | number | boolean;\n\nexport type FilterNamedOptions = Record<string, FilterScalar | undefined>;\n\nexport interface FilterNodeSpec {\n name: string;\n positional?: readonly FilterScalar[];\n named?: FilterNamedOptions;\n}\n\nexport interface TrimOptions {\n start?: string | number;\n end?: string | number;\n duration?: string | number;\n startFrame?: number;\n endFrame?: number;\n}\n\nexport interface OverlayOptions {\n x?: string | number;\n y?: string | number;\n eofAction?: string;\n shortest?: boolean;\n repeatlast?: boolean;\n}\n\nexport interface AmixOptions {\n inputs?: number;\n duration?: string;\n dropoutTransition?: number;\n normalize?: boolean;\n}\n\nexport interface ConcatOptions {\n segments: number;\n videoStreams?: number;\n audioStreams?: number;\n unsafe?: boolean;\n}\n\nfunction escapeFilterValue(value: FilterScalar): string {\n if (typeof value === \"boolean\") {\n return value ? \"1\" : \"0\";\n }\n\n return String(value);\n}\n\nfunction serializeFilter(spec: FilterNodeSpec): string {\n const parts: string[] = [];\n\n if (spec.positional && spec.positional.length > 0) {\n parts.push(spec.positional.map(escapeFilterValue).join(\":\"));\n }\n\n if (spec.named) {\n const entries = Object.entries(spec.named)\n .filter(([, value]) => value !== undefined)\n .map(([key, value]) => `${key}=${escapeFilterValue(value as FilterScalar)}`);\n\n if (entries.length > 0) {\n parts.push(...entries);\n }\n }\n\n if (parts.length === 0) {\n return spec.name;\n }\n\n return `${spec.name}=${parts.join(\":\")}`;\n}\n\nfunction joinInputs(inputs: readonly FilterGraphStream[]): string {\n return inputs.map((stream) => stream.toString()).join(\"\");\n}\n\nfunction joinOutputs(outputs: readonly string[]): string {\n return outputs.map((label) => `[${label}]`).join(\"\");\n}\n\nlet autoLabelId = 0;\n\nfunction nextAutoLabel(prefix: string): string {\n const label = `${prefix}${autoLabelId}`;\n autoLabelId += 1;\n return label;\n}\n\nexport function resetFilterGraphLabelCounter(): void {\n autoLabelId = 0;\n}\n\nexport class FilterGraphStream {\n public readonly label: string;\n public readonly mediaType: FilterGraphMediaType;\n\n constructor(label: string, mediaType: FilterGraphMediaType) {\n this.label = label;\n this.mediaType = mediaType;\n }\n\n toString(): string {\n return `[${this.label}]`;\n }\n}\n\nclass FilterGraphChain {\n private readonly filters: string[] = [];\n private readonly graph: FilterGraph;\n private readonly inputs: readonly FilterGraphStream[];\n private readonly outputMediaTypes: readonly FilterGraphMediaType[];\n\n constructor(\n graph: FilterGraph,\n inputs: readonly FilterGraphStream[],\n outputMediaTypes: readonly FilterGraphMediaType[],\n ) {\n this.graph = graph;\n this.inputs = inputs;\n this.outputMediaTypes = outputMediaTypes;\n }\n\n raw(filter: string): this {\n this.filters.push(filter);\n return this;\n }\n\n filter(\n name: string,\n positional: readonly FilterScalar[] = [],\n named: FilterNamedOptions = {},\n ): this {\n this.filters.push(serializeFilter({ name, positional, named }));\n return this;\n }\n\n scale(width: string | number, height: string | number, named: FilterNamedOptions = {}): this {\n return this.filter(\"scale\", [width, height], named);\n }\n\n fps(rate: string | number): this {\n return this.filter(\"fps\", [rate]);\n }\n\n format(pixelFormat: string): this {\n return this.filter(\"format\", [pixelFormat]);\n }\n\n trim(options: TrimOptions): this {\n return this.filter(\"trim\", [], {\n start: options.start,\n end: options.end,\n duration: options.duration,\n start_frame: options.startFrame,\n end_frame: options.endFrame,\n });\n }\n\n setpts(expression: string): this {\n return this.filter(\"setpts\", [expression]);\n }\n\n asetpts(expression: string): this {\n return this.filter(\"asetpts\", [expression]);\n }\n\n hflip(): this {\n return this.filter(\"hflip\");\n }\n\n vflip(): this {\n return this.filter(\"vflip\");\n }\n\n volume(value: string | number): this {\n return this.filter(\"volume\", [value]);\n }\n\n atempo(value: number): this {\n return this.filter(\"atempo\", [value]);\n }\n\n split(...labels: string[]): FilterGraphStream[] {\n const outputLabels = labels.length > 0 ? labels : [nextAutoLabel(\"v\"), nextAutoLabel(\"v\")];\n\n return this.commit(\n outputLabels,\n outputLabels.map(() => this.outputMediaTypes[0] ?? \"unknown\"),\n serializeFilter({ name: \"split\", named: { outputs: outputLabels.length } }),\n );\n }\n\n asplit(...labels: string[]): FilterGraphStream[] {\n const outputLabels = labels.length > 0 ? labels : [nextAutoLabel(\"a\"), nextAutoLabel(\"a\")];\n\n return this.commit(\n outputLabels,\n outputLabels.map(() => \"audio\"),\n serializeFilter({ name: \"asplit\", named: { outputs: outputLabels.length } }),\n );\n }\n\n label(label: string): FilterGraphStream {\n return this.commit([label], [this.outputMediaTypes[0] ?? \"unknown\"])[0];\n }\n\n labels(...labels: string[]): FilterGraphStream[] {\n const outputLabels = labels.length > 0 ? labels : [nextAutoLabel(\"out\")];\n return this.commit(\n outputLabels,\n outputLabels.map(\n (_, index) => this.outputMediaTypes[index] ?? this.outputMediaTypes[0] ?? \"unknown\",\n ),\n );\n }\n\n autoLabel(prefix?: string): FilterGraphStream {\n const mediaType = this.outputMediaTypes[0] ?? \"unknown\";\n const fallbackPrefix =\n prefix ?? (mediaType === \"audio\" ? \"a\" : mediaType === \"video\" ? \"v\" : \"out\");\n return this.label(nextAutoLabel(fallbackPrefix));\n }\n\n private commit(\n labels: readonly string[],\n outputMediaTypes: readonly FilterGraphMediaType[],\n terminalFilter?: string,\n ): FilterGraphStream[] {\n const chain = [...this.filters];\n if (terminalFilter) {\n chain.push(terminalFilter);\n }\n\n if (chain.length === 0) {\n throw new Error(\"Cannot label an empty filter graph chain\");\n }\n\n this.graph.addSegment(\n `${joinInputs(this.inputs)}${chain.join(\",\")}${joinOutputs(labels)}`,\n labels,\n );\n\n return labels.map(\n (label, index) => new FilterGraphStream(label, outputMediaTypes[index] ?? \"unknown\"),\n );\n }\n}\n\nexport class FilterGraph {\n private readonly segments: string[] = [];\n private readonly outputLabels = new Set<string>();\n\n addSegment(segment: string, labels: readonly string[]): void {\n for (const label of labels) {\n if (this.outputLabels.has(label)) {\n throw new Error(`Duplicate filter graph output label \"${label}\"`);\n }\n this.outputLabels.add(label);\n }\n this.segments.push(segment);\n }\n\n hasOutputLabel(label: string): boolean {\n return this.outputLabels.has(label);\n }\n\n getOutputLabels(): string[] {\n return [...this.outputLabels];\n }\n\n input(\n index: number,\n streamType?: \"v\" | \"a\" | \"s\" | \"d\" | \"t\",\n streamIndex?: number,\n ): FilterGraphStream {\n const label =\n streamType === undefined\n ? String(index)\n : streamIndex === undefined\n ? `${index}:${streamType}`\n : `${index}:${streamType}:${streamIndex}`;\n\n const mediaType: FilterGraphMediaType =\n streamType === \"v\" ? \"video\" : streamType === \"a\" ? \"audio\" : \"unknown\";\n\n return new FilterGraphStream(label, mediaType);\n }\n\n videoInput(index: number, streamIndex?: number): FilterGraphChain {\n return new FilterGraphChain(this, [this.input(index, \"v\", streamIndex)], [\"video\"]);\n }\n\n audioInput(index: number, streamIndex?: number): FilterGraphChain {\n return new FilterGraphChain(this, [this.input(index, \"a\", streamIndex)], [\"audio\"]);\n }\n\n from(...streams: readonly FilterGraphStream[]): FilterGraphChain {\n const mediaType = streams[0]?.mediaType ?? \"unknown\";\n return new FilterGraphChain(this, streams, [mediaType]);\n }\n\n overlay(\n main: FilterGraphStream,\n overlay: FilterGraphStream,\n options: OverlayOptions = {},\n ): FilterGraphChain {\n return new FilterGraphChain(this, [main, overlay], [\"video\"]).filter(\"overlay\", [], {\n x: options.x,\n y: options.y,\n eof_action: options.eofAction,\n shortest: options.shortest,\n repeatlast: options.repeatlast,\n });\n }\n\n amerge(...streams: readonly FilterGraphStream[]): FilterGraphChain {\n return new FilterGraphChain(this, streams, [\"audio\"]).filter(\"amerge\", [], {\n inputs: streams.length,\n });\n }\n\n amix(streams: readonly FilterGraphStream[], options: AmixOptions = {}): FilterGraphChain {\n return new FilterGraphChain(this, streams, [\"audio\"]).filter(\"amix\", [], {\n inputs: options.inputs ?? streams.length,\n duration: options.duration,\n dropout_transition: options.dropoutTransition,\n normalize: options.normalize,\n });\n }\n\n concat(streams: readonly FilterGraphStream[], options: ConcatOptions): FilterGraphChain {\n const outputMediaTypes: FilterGraphMediaType[] = [];\n\n const videoStreams = options.videoStreams ?? 1;\n const audioStreams = options.audioStreams ?? 0;\n\n for (let index = 0; index < videoStreams; index += 1) {\n outputMediaTypes.push(\"video\");\n }\n\n for (let index = 0; index < audioStreams; index += 1) {\n outputMediaTypes.push(\"audio\");\n }\n\n return new FilterGraphChain(\n this,\n streams,\n outputMediaTypes.length > 0 ? outputMediaTypes : [\"unknown\"],\n ).filter(\"concat\", [], {\n n: options.segments,\n v: videoStreams,\n a: audioStreams,\n unsafe: options.unsafe,\n });\n }\n\n toString(): string {\n return this.segments.join(\";\");\n }\n}\n\nexport function filterGraph(): FilterGraph {\n return new FilterGraph();\n}\n"],"mappings":"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"}