@revizly/node-av 5.2.2-beta.1

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.
Files changed (254) hide show
  1. package/BUILD_LINUX.md +61 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +662 -0
  4. package/build_mac_local.sh +69 -0
  5. package/dist/api/audio-frame-buffer.d.ts +205 -0
  6. package/dist/api/audio-frame-buffer.js +287 -0
  7. package/dist/api/audio-frame-buffer.js.map +1 -0
  8. package/dist/api/bitstream-filter.d.ts +820 -0
  9. package/dist/api/bitstream-filter.js +1242 -0
  10. package/dist/api/bitstream-filter.js.map +1 -0
  11. package/dist/api/constants.d.ts +44 -0
  12. package/dist/api/constants.js +45 -0
  13. package/dist/api/constants.js.map +1 -0
  14. package/dist/api/data/test_av1.ivf +0 -0
  15. package/dist/api/data/test_h264.h264 +0 -0
  16. package/dist/api/data/test_hevc.h265 +0 -0
  17. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  18. package/dist/api/data/test_vp8.ivf +0 -0
  19. package/dist/api/data/test_vp9.ivf +0 -0
  20. package/dist/api/decoder.d.ts +1088 -0
  21. package/dist/api/decoder.js +1775 -0
  22. package/dist/api/decoder.js.map +1 -0
  23. package/dist/api/demuxer.d.ts +1219 -0
  24. package/dist/api/demuxer.js +2081 -0
  25. package/dist/api/demuxer.js.map +1 -0
  26. package/dist/api/device.d.ts +586 -0
  27. package/dist/api/device.js +961 -0
  28. package/dist/api/device.js.map +1 -0
  29. package/dist/api/encoder.d.ts +1132 -0
  30. package/dist/api/encoder.js +1988 -0
  31. package/dist/api/encoder.js.map +1 -0
  32. package/dist/api/filter-complex.d.ts +821 -0
  33. package/dist/api/filter-complex.js +1604 -0
  34. package/dist/api/filter-complex.js.map +1 -0
  35. package/dist/api/filter-presets.d.ts +1286 -0
  36. package/dist/api/filter-presets.js +2152 -0
  37. package/dist/api/filter-presets.js.map +1 -0
  38. package/dist/api/filter.d.ts +1234 -0
  39. package/dist/api/filter.js +1976 -0
  40. package/dist/api/filter.js.map +1 -0
  41. package/dist/api/fmp4-stream.d.ts +426 -0
  42. package/dist/api/fmp4-stream.js +739 -0
  43. package/dist/api/fmp4-stream.js.map +1 -0
  44. package/dist/api/hardware.d.ts +651 -0
  45. package/dist/api/hardware.js +1260 -0
  46. package/dist/api/hardware.js.map +1 -0
  47. package/dist/api/index.d.ts +17 -0
  48. package/dist/api/index.js +32 -0
  49. package/dist/api/index.js.map +1 -0
  50. package/dist/api/io-stream.d.ts +307 -0
  51. package/dist/api/io-stream.js +282 -0
  52. package/dist/api/io-stream.js.map +1 -0
  53. package/dist/api/muxer.d.ts +957 -0
  54. package/dist/api/muxer.js +2002 -0
  55. package/dist/api/muxer.js.map +1 -0
  56. package/dist/api/pipeline.d.ts +607 -0
  57. package/dist/api/pipeline.js +1145 -0
  58. package/dist/api/pipeline.js.map +1 -0
  59. package/dist/api/utilities/async-queue.d.ts +120 -0
  60. package/dist/api/utilities/async-queue.js +211 -0
  61. package/dist/api/utilities/async-queue.js.map +1 -0
  62. package/dist/api/utilities/audio-sample.d.ts +117 -0
  63. package/dist/api/utilities/audio-sample.js +112 -0
  64. package/dist/api/utilities/audio-sample.js.map +1 -0
  65. package/dist/api/utilities/channel-layout.d.ts +76 -0
  66. package/dist/api/utilities/channel-layout.js +80 -0
  67. package/dist/api/utilities/channel-layout.js.map +1 -0
  68. package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
  69. package/dist/api/utilities/electron-shared-texture.js +503 -0
  70. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  71. package/dist/api/utilities/image.d.ts +207 -0
  72. package/dist/api/utilities/image.js +213 -0
  73. package/dist/api/utilities/image.js.map +1 -0
  74. package/dist/api/utilities/index.d.ts +12 -0
  75. package/dist/api/utilities/index.js +25 -0
  76. package/dist/api/utilities/index.js.map +1 -0
  77. package/dist/api/utilities/media-type.d.ts +49 -0
  78. package/dist/api/utilities/media-type.js +53 -0
  79. package/dist/api/utilities/media-type.js.map +1 -0
  80. package/dist/api/utilities/pixel-format.d.ts +89 -0
  81. package/dist/api/utilities/pixel-format.js +97 -0
  82. package/dist/api/utilities/pixel-format.js.map +1 -0
  83. package/dist/api/utilities/sample-format.d.ts +129 -0
  84. package/dist/api/utilities/sample-format.js +141 -0
  85. package/dist/api/utilities/sample-format.js.map +1 -0
  86. package/dist/api/utilities/scheduler.d.ts +138 -0
  87. package/dist/api/utilities/scheduler.js +98 -0
  88. package/dist/api/utilities/scheduler.js.map +1 -0
  89. package/dist/api/utilities/streaming.d.ts +186 -0
  90. package/dist/api/utilities/streaming.js +309 -0
  91. package/dist/api/utilities/streaming.js.map +1 -0
  92. package/dist/api/utilities/timestamp.d.ts +193 -0
  93. package/dist/api/utilities/timestamp.js +206 -0
  94. package/dist/api/utilities/timestamp.js.map +1 -0
  95. package/dist/api/utilities/whisper-model.d.ts +310 -0
  96. package/dist/api/utilities/whisper-model.js +528 -0
  97. package/dist/api/utilities/whisper-model.js.map +1 -0
  98. package/dist/api/utils.d.ts +19 -0
  99. package/dist/api/utils.js +39 -0
  100. package/dist/api/utils.js.map +1 -0
  101. package/dist/api/whisper.d.ts +324 -0
  102. package/dist/api/whisper.js +362 -0
  103. package/dist/api/whisper.js.map +1 -0
  104. package/dist/constants/channel-layouts.d.ts +53 -0
  105. package/dist/constants/channel-layouts.js +57 -0
  106. package/dist/constants/channel-layouts.js.map +1 -0
  107. package/dist/constants/constants.d.ts +2325 -0
  108. package/dist/constants/constants.js +1887 -0
  109. package/dist/constants/constants.js.map +1 -0
  110. package/dist/constants/decoders.d.ts +633 -0
  111. package/dist/constants/decoders.js +641 -0
  112. package/dist/constants/decoders.js.map +1 -0
  113. package/dist/constants/encoders.d.ts +295 -0
  114. package/dist/constants/encoders.js +308 -0
  115. package/dist/constants/encoders.js.map +1 -0
  116. package/dist/constants/hardware.d.ts +26 -0
  117. package/dist/constants/hardware.js +27 -0
  118. package/dist/constants/hardware.js.map +1 -0
  119. package/dist/constants/index.d.ts +5 -0
  120. package/dist/constants/index.js +6 -0
  121. package/dist/constants/index.js.map +1 -0
  122. package/dist/ffmpeg/index.d.ts +99 -0
  123. package/dist/ffmpeg/index.js +115 -0
  124. package/dist/ffmpeg/index.js.map +1 -0
  125. package/dist/ffmpeg/utils.d.ts +31 -0
  126. package/dist/ffmpeg/utils.js +68 -0
  127. package/dist/ffmpeg/utils.js.map +1 -0
  128. package/dist/ffmpeg/version.d.ts +6 -0
  129. package/dist/ffmpeg/version.js +7 -0
  130. package/dist/ffmpeg/version.js.map +1 -0
  131. package/dist/index.d.ts +4 -0
  132. package/dist/index.js +9 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/lib/audio-fifo.d.ts +399 -0
  135. package/dist/lib/audio-fifo.js +431 -0
  136. package/dist/lib/audio-fifo.js.map +1 -0
  137. package/dist/lib/binding.d.ts +228 -0
  138. package/dist/lib/binding.js +60 -0
  139. package/dist/lib/binding.js.map +1 -0
  140. package/dist/lib/bitstream-filter-context.d.ts +379 -0
  141. package/dist/lib/bitstream-filter-context.js +441 -0
  142. package/dist/lib/bitstream-filter-context.js.map +1 -0
  143. package/dist/lib/bitstream-filter.d.ts +140 -0
  144. package/dist/lib/bitstream-filter.js +154 -0
  145. package/dist/lib/bitstream-filter.js.map +1 -0
  146. package/dist/lib/codec-context.d.ts +1071 -0
  147. package/dist/lib/codec-context.js +1354 -0
  148. package/dist/lib/codec-context.js.map +1 -0
  149. package/dist/lib/codec-parameters.d.ts +616 -0
  150. package/dist/lib/codec-parameters.js +761 -0
  151. package/dist/lib/codec-parameters.js.map +1 -0
  152. package/dist/lib/codec-parser.d.ts +201 -0
  153. package/dist/lib/codec-parser.js +213 -0
  154. package/dist/lib/codec-parser.js.map +1 -0
  155. package/dist/lib/codec.d.ts +586 -0
  156. package/dist/lib/codec.js +713 -0
  157. package/dist/lib/codec.js.map +1 -0
  158. package/dist/lib/device.d.ts +291 -0
  159. package/dist/lib/device.js +324 -0
  160. package/dist/lib/device.js.map +1 -0
  161. package/dist/lib/dictionary.d.ts +333 -0
  162. package/dist/lib/dictionary.js +372 -0
  163. package/dist/lib/dictionary.js.map +1 -0
  164. package/dist/lib/error.d.ts +242 -0
  165. package/dist/lib/error.js +303 -0
  166. package/dist/lib/error.js.map +1 -0
  167. package/dist/lib/fifo.d.ts +416 -0
  168. package/dist/lib/fifo.js +453 -0
  169. package/dist/lib/fifo.js.map +1 -0
  170. package/dist/lib/filter-context.d.ts +712 -0
  171. package/dist/lib/filter-context.js +789 -0
  172. package/dist/lib/filter-context.js.map +1 -0
  173. package/dist/lib/filter-graph-segment.d.ts +160 -0
  174. package/dist/lib/filter-graph-segment.js +171 -0
  175. package/dist/lib/filter-graph-segment.js.map +1 -0
  176. package/dist/lib/filter-graph.d.ts +641 -0
  177. package/dist/lib/filter-graph.js +704 -0
  178. package/dist/lib/filter-graph.js.map +1 -0
  179. package/dist/lib/filter-inout.d.ts +198 -0
  180. package/dist/lib/filter-inout.js +257 -0
  181. package/dist/lib/filter-inout.js.map +1 -0
  182. package/dist/lib/filter.d.ts +243 -0
  183. package/dist/lib/filter.js +272 -0
  184. package/dist/lib/filter.js.map +1 -0
  185. package/dist/lib/format-context.d.ts +1254 -0
  186. package/dist/lib/format-context.js +1379 -0
  187. package/dist/lib/format-context.js.map +1 -0
  188. package/dist/lib/frame-utils.d.ts +116 -0
  189. package/dist/lib/frame-utils.js +98 -0
  190. package/dist/lib/frame-utils.js.map +1 -0
  191. package/dist/lib/frame.d.ts +1222 -0
  192. package/dist/lib/frame.js +1435 -0
  193. package/dist/lib/frame.js.map +1 -0
  194. package/dist/lib/hardware-device-context.d.ts +362 -0
  195. package/dist/lib/hardware-device-context.js +383 -0
  196. package/dist/lib/hardware-device-context.js.map +1 -0
  197. package/dist/lib/hardware-frames-context.d.ts +419 -0
  198. package/dist/lib/hardware-frames-context.js +477 -0
  199. package/dist/lib/hardware-frames-context.js.map +1 -0
  200. package/dist/lib/index.d.ts +35 -0
  201. package/dist/lib/index.js +60 -0
  202. package/dist/lib/index.js.map +1 -0
  203. package/dist/lib/input-format.d.ts +249 -0
  204. package/dist/lib/input-format.js +306 -0
  205. package/dist/lib/input-format.js.map +1 -0
  206. package/dist/lib/io-context.d.ts +696 -0
  207. package/dist/lib/io-context.js +769 -0
  208. package/dist/lib/io-context.js.map +1 -0
  209. package/dist/lib/log.d.ts +174 -0
  210. package/dist/lib/log.js +184 -0
  211. package/dist/lib/log.js.map +1 -0
  212. package/dist/lib/native-types.d.ts +946 -0
  213. package/dist/lib/native-types.js +2 -0
  214. package/dist/lib/native-types.js.map +1 -0
  215. package/dist/lib/option.d.ts +927 -0
  216. package/dist/lib/option.js +1583 -0
  217. package/dist/lib/option.js.map +1 -0
  218. package/dist/lib/output-format.d.ts +180 -0
  219. package/dist/lib/output-format.js +213 -0
  220. package/dist/lib/output-format.js.map +1 -0
  221. package/dist/lib/packet.d.ts +501 -0
  222. package/dist/lib/packet.js +590 -0
  223. package/dist/lib/packet.js.map +1 -0
  224. package/dist/lib/rational.d.ts +251 -0
  225. package/dist/lib/rational.js +278 -0
  226. package/dist/lib/rational.js.map +1 -0
  227. package/dist/lib/software-resample-context.d.ts +552 -0
  228. package/dist/lib/software-resample-context.js +592 -0
  229. package/dist/lib/software-resample-context.js.map +1 -0
  230. package/dist/lib/software-scale-context.d.ts +344 -0
  231. package/dist/lib/software-scale-context.js +366 -0
  232. package/dist/lib/software-scale-context.js.map +1 -0
  233. package/dist/lib/stream.d.ts +379 -0
  234. package/dist/lib/stream.js +526 -0
  235. package/dist/lib/stream.js.map +1 -0
  236. package/dist/lib/sync-queue.d.ts +179 -0
  237. package/dist/lib/sync-queue.js +197 -0
  238. package/dist/lib/sync-queue.js.map +1 -0
  239. package/dist/lib/types.d.ts +34 -0
  240. package/dist/lib/types.js +2 -0
  241. package/dist/lib/types.js.map +1 -0
  242. package/dist/lib/utilities.d.ts +1127 -0
  243. package/dist/lib/utilities.js +1225 -0
  244. package/dist/lib/utilities.js.map +1 -0
  245. package/dist/utils/electron.d.ts +49 -0
  246. package/dist/utils/electron.js +63 -0
  247. package/dist/utils/electron.js.map +1 -0
  248. package/dist/utils/index.d.ts +4 -0
  249. package/dist/utils/index.js +5 -0
  250. package/dist/utils/index.js.map +1 -0
  251. package/install/check.js +121 -0
  252. package/install/ffmpeg.js +66 -0
  253. package/jellyfin-ffmpeg.patch +181 -0
  254. package/package.json +129 -0
@@ -0,0 +1,821 @@
1
+ import { Frame } from '../lib/frame.js';
2
+ import type { AVMediaType, EOFSignal } from '../constants/index.js';
3
+ import type { IRational } from '../lib/types.js';
4
+ import type { FilterOptions } from './filter.js';
5
+ /**
6
+ * Input configuration for FilterComplexAPI.
7
+ */
8
+ export interface FilterComplexInput {
9
+ /**
10
+ * Input label identifier.
11
+ *
12
+ * Matches labels in filter_complex description (e.g., '0:v', '1:v', '0:a').
13
+ * Used to identify which buffersrc filter to send frames to via process() method.
14
+ */
15
+ label: string;
16
+ }
17
+ /**
18
+ * Output configuration for FilterComplexAPI.
19
+ */
20
+ export interface FilterComplexOutput {
21
+ /**
22
+ * Output label identifier.
23
+ *
24
+ * Matches labels in filter_complex description (e.g., 'out', 'thumb', 'main').
25
+ * Used to identify which buffersink to read from via output() method.
26
+ */
27
+ label: string;
28
+ /**
29
+ * Media type for this output.
30
+ *
31
+ * If not specified, defaults to the media type of the first input.
32
+ * Set to 'AVMEDIA_TYPE_VIDEO' or 'AVMEDIA_TYPE_AUDIO' explicitly if needed (e.g., for audio extraction filters).
33
+ *
34
+ * @default Inferred from first input
35
+ */
36
+ mediaType?: AVMediaType;
37
+ }
38
+ /**
39
+ * Options for creating a complex filter graph.
40
+ */
41
+ export interface FilterComplexOptions extends FilterOptions {
42
+ /**
43
+ * Input sources for the filter graph.
44
+ *
45
+ * Array of labeled frame sources that feed into the filter graph.
46
+ * Labels must match those referenced in the description string.
47
+ */
48
+ inputs: FilterComplexInput[];
49
+ /**
50
+ * Output labels from the filter graph.
51
+ *
52
+ * Array of output identifiers that can be consumed via output() method.
53
+ * Labels must match those defined in the description string.
54
+ */
55
+ outputs: FilterComplexOutput[];
56
+ }
57
+ /**
58
+ * High-level filter_complex API for multi-input/output filtering.
59
+ *
60
+ * Provides simplified interface for complex FFmpeg filter graphs with multiple inputs and outputs.
61
+ * Supports both high-level generator API and low-level manual control.
62
+ *
63
+ * @example
64
+ * ```typescript
65
+ * // High-level API: Simple overlay with frames() generator
66
+ * using complex = FilterComplexAPI.create('[0:v][1:v]overlay=x=100:y=50[out]', {
67
+ * inputs: [{ label: '0:v' }, { label: '1:v' }],
68
+ * outputs: [{ label: 'out' }]
69
+ * });
70
+ *
71
+ * // Process multiple input streams automatically
72
+ * for await (using frame of complex.frames('out', {
73
+ * '0:v': decoder1.frames(packets1),
74
+ * '1:v': decoder2.frames(packets2)
75
+ * })) {
76
+ * await encoder.encode(frame);
77
+ * }
78
+ * ```
79
+ *
80
+ * @see {@link FilterAPI} For simple single-input/output filtering
81
+ * @see {@link FilterGraph} For low-level filter graph API
82
+ * @see {@link frames} For high-level stream processing
83
+ * @see {@link process} For low-level manual frame sending
84
+ * @see {@link receive} For low-level manual frame receiving
85
+ */
86
+ export declare class FilterComplexAPI implements Disposable {
87
+ private graph;
88
+ private description;
89
+ private options;
90
+ private inputs;
91
+ private outputs;
92
+ private initialized;
93
+ private isClosed;
94
+ private initializePromise;
95
+ private frame;
96
+ /**
97
+ * @param graph - Filter graph instance
98
+ *
99
+ * @param description - Filter description string
100
+ *
101
+ * @param options - Filter complex options
102
+ *
103
+ * @internal
104
+ */
105
+ private constructor();
106
+ /**
107
+ * Create a complex filter with specified configuration.
108
+ *
109
+ * Direct mapping to avfilter_graph_segment_parse() and avfilter_graph_config().
110
+ *
111
+ * @param description - Filter description string (e.g., '[0:v][1:v]overlay[out]')
112
+ *
113
+ * @param options - Filter complex configuration including inputs and outputs
114
+ *
115
+ * @returns Filter complex instance ready to process frames
116
+ *
117
+ * @throws {Error} If configuration is invalid (duplicate labels, no inputs/outputs)
118
+ *
119
+ * @example
120
+ * ```typescript
121
+ * // Simple overlay example
122
+ * using complex = FilterComplexAPI.create(
123
+ * '[0:v][1:v]overlay=x=100:y=50[out]',
124
+ * {
125
+ * inputs: [
126
+ * { label: '0:v' }, // Base video
127
+ * { label: '1:v' } // Overlay video
128
+ * ],
129
+ * outputs: [{ label: 'out' }]
130
+ * }
131
+ * );
132
+ *
133
+ * // Send frames manually
134
+ * await complex.process('0:v', baseFrame);
135
+ * await complex.process('1:v', overlayFrame);
136
+ * using outFrame = await complex.receive('out');
137
+ * ```
138
+ *
139
+ * @see {@link process} For sending frames to inputs
140
+ * @see {@link receive} For getting frames from outputs
141
+ */
142
+ static create(description: string, options: FilterComplexOptions): FilterComplexAPI;
143
+ /**
144
+ * Check if filter complex is open.
145
+ *
146
+ * @returns true if not closed
147
+ *
148
+ * @example
149
+ * ```typescript
150
+ * if (complex.isOpen) {
151
+ * // Can still consume frames
152
+ * }
153
+ * ```
154
+ */
155
+ get isOpen(): boolean;
156
+ /**
157
+ * Check if filter complex has been initialized.
158
+ *
159
+ * Returns true after first frame set has been processed from all inputs.
160
+ *
161
+ * @returns true if filter graph has been configured
162
+ *
163
+ * @example
164
+ * ```typescript
165
+ * if (!complex.isInitialized) {
166
+ * console.log('Filter will initialize on first frame set');
167
+ * }
168
+ * ```
169
+ */
170
+ get isInitialized(): boolean;
171
+ /**
172
+ * Get output frame rate.
173
+ *
174
+ * Returns frame rate from the first output's buffersink.
175
+ * Returns null if not initialized or frame rate is not set.
176
+ *
177
+ * @returns Frame rate as rational number or null
178
+ *
179
+ * @example
180
+ * ```typescript
181
+ * const frameRate = complex.frameRate;
182
+ * if (frameRate) {
183
+ * console.log(`Output: ${frameRate.num}/${frameRate.den} fps`);
184
+ * }
185
+ * ```
186
+ *
187
+ * @see {@link FilterAPI.frameRate} For single-output filter frame rate
188
+ */
189
+ get frameRate(): IRational | null;
190
+ /**
191
+ * Get output time base.
192
+ *
193
+ * Returns time base from the first output's buffersink.
194
+ * Returns null if not initialized.
195
+ *
196
+ * @returns Time base as rational number or null
197
+ *
198
+ * @example
199
+ * ```typescript
200
+ * const timeBase = complex.timeBase;
201
+ * if (timeBase) {
202
+ * console.log(`Output timeBase: ${timeBase.num}/${timeBase.den}`);
203
+ * }
204
+ * ```
205
+ *
206
+ * @see {@link FilterAPI.timeBase} For single-output filter time base
207
+ */
208
+ get timeBase(): IRational | null;
209
+ /**
210
+ * Process frame by sending to specified input.
211
+ *
212
+ * Sends a frame to the buffersrc of the specified input label.
213
+ * Automatically rescales timestamps to the input's calculated timeBase (CFR/VFR).
214
+ * Pass null to signal end-of-stream for that input.
215
+ *
216
+ * Direct mapping to av_buffersrc_add_frame().
217
+ *
218
+ * @param inLabel - Input label to send frame to
219
+ *
220
+ * @param frame - Frame to process
221
+ *
222
+ * @throws {Error} If input label not found or filter closed
223
+ *
224
+ * @throws {FFmpegError} If processing fails
225
+ *
226
+ * @example
227
+ * ```typescript
228
+ * // Process frames one at a time
229
+ * await complex.process('0:v', frame1);
230
+ * await complex.process('1:v', frame2);
231
+ * const outFrame = await complex.receive('out');
232
+ * ```
233
+ *
234
+ * @see {@link receive} For receiving output frames
235
+ * @see {@link flush} For flushing inputs
236
+ * @see {@link processSync} For synchronous version
237
+ */
238
+ process(inLabel: string, frame: Frame): Promise<void>;
239
+ /**
240
+ * Process frame by sending to specified input synchronously.
241
+ * Synchronous version of process.
242
+ *
243
+ * Sends a frame to the buffersrc of the specified input label.
244
+ * Automatically rescales timestamps to the input's calculated timeBase (CFR/VFR).
245
+ * Pass null to signal end-of-stream for that input.
246
+ *
247
+ * Direct mapping to av_buffersrc_add_frame().
248
+ *
249
+ * @param inLabel - Input label to send frame to
250
+ *
251
+ * @param frame - Frame to process
252
+ *
253
+ * @throws {Error} If input label not found or filter closed
254
+ *
255
+ * @throws {FFmpegError} If processing fails
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * // Process frames one at a time
260
+ * complex.processSync('0:v', frame1);
261
+ * complex.processSync('1:v', frame2);
262
+ * const outFrame = complex.receiveSync('out');
263
+ * ```
264
+ *
265
+ * @see {@link receiveSync} For receiving output frames
266
+ * @see {@link flushSync} For flushing inputs
267
+ * @see {@link process} For async version
268
+ */
269
+ processSync(inLabel: string, frame: Frame): void;
270
+ /**
271
+ * Process frame streams from multiple inputs and yield frames from specified output.
272
+ *
273
+ * High-level async generator for multi-input filtering.
274
+ * Filter is only flushed when EOF (null) is explicitly sent to any input.
275
+ *
276
+ * **EOF Handling:**
277
+ * - Filter is only flushed when EOF (null) is explicitly sent to ANY input
278
+ * - Generator yields null after flushing when null is received
279
+ * - No automatic flushing - filter stays open until EOF or close()
280
+ * - Iterator completion without null does not trigger flush
281
+ *
282
+ * @param outLabel - Output label to receive frames from
283
+ *
284
+ * @param inputs - Record mapping input labels to frame sources (AsyncIterable, single Frame, or null)
285
+ *
286
+ * @yields {Frame | null} Filtered frames from output, followed by null when flushed
287
+ *
288
+ * @throws {Error} If input label not found
289
+ *
290
+ * @throws {FFmpegError} If processing fails
291
+ *
292
+ * @example
293
+ * ```typescript
294
+ * // Stream processing: 2 inputs, 1 output
295
+ * using complex = FilterComplexAPI.create('[0:v][1:v]overlay[out]', {
296
+ * inputs: [{ label: '0:v' }, { label: '1:v' }],
297
+ * outputs: [{ label: 'out' }]
298
+ * });
299
+ *
300
+ * for await (using frame of complex.frames('out', {
301
+ * '0:v': decoder1.frames(packets1),
302
+ * '1:v': decoder2.frames(packets2)
303
+ * })) {
304
+ * await encoder.encode(frame);
305
+ * }
306
+ * ```
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * // Single frames - no automatic flush
311
+ * for await (using frame of complex.frames('out', {
312
+ * '0:v': frame1,
313
+ * '1:v': frame2
314
+ * })) {
315
+ * await encoder.encode(frame);
316
+ * }
317
+ * // Filter remains open, buffered frames not flushed
318
+ * ```
319
+ *
320
+ * @example
321
+ * ```typescript
322
+ * // Explicit flush with null
323
+ * for await (using frame of complex.frames('out', {
324
+ * '0:v': null,
325
+ * '1:v': null
326
+ * })) {
327
+ * await encoder.encode(frame);
328
+ * }
329
+ * ```
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * // Mixed: stream + single frame
334
+ * for await (using frame of complex.frames('out', {
335
+ * '0:v': decoder.frames(packets), // Stream
336
+ * '1:v': watermarkFrame // Single frame (used for all)
337
+ * })) {
338
+ * await encoder.encode(frame);
339
+ * }
340
+ * ```
341
+ *
342
+ * @see {@link process} For manual frame sending
343
+ * @see {@link receive} For manual frame receiving
344
+ * @see {@link framesSync} For sync version
345
+ */
346
+ frames(outLabel: string, inputs: Record<string, AsyncIterable<Frame | null> | Frame | null>): AsyncGenerator<Frame | null>;
347
+ /**
348
+ * Process frame streams from multiple inputs and yield frames from specified output synchronously.
349
+ * Synchronous version of frames.
350
+ *
351
+ * High-level sync generator for multi-input filtering.
352
+ * Filter is only flushed when EOF (null) is explicitly sent to any input.
353
+ *
354
+ * **EOF Handling:**
355
+ * - Filter is only flushed when EOF (null) is explicitly sent to ANY input
356
+ * - Generator yields null after flushing when null is received
357
+ * - No automatic flushing - filter stays open until EOF or close()
358
+ * - Iterator completion without null does not trigger flush
359
+ *
360
+ * @param outLabel - Output label to receive frames from
361
+ *
362
+ * @param inputs - Record mapping input labels to frame sources (Iterable, single Frame, or null)
363
+ *
364
+ * @yields {Frame | null} Filtered frames from output, followed by null when flushed
365
+ *
366
+ * @throws {Error} If input label not found or filter not initialized
367
+ *
368
+ * @throws {FFmpegError} If processing fails
369
+ *
370
+ * @example
371
+ * ```typescript
372
+ * // Stream processing: 2 inputs, 1 output
373
+ * using complex = FilterComplexAPI.create('[0:v][1:v]overlay[out]', {
374
+ * inputs: [{ label: '0:v' }, { label: '1:v' }],
375
+ * outputs: [{ label: 'out' }]
376
+ * });
377
+ *
378
+ * // Note: Sync version requires async initialization first
379
+ * await complex.process('0:v', firstFrame1);
380
+ * await complex.process('1:v', firstFrame2);
381
+ *
382
+ * for (using frame of complex.framesSync('out', {
383
+ * '0:v': decoder1.framesSync(packets1),
384
+ * '1:v': decoder2.framesSync(packets2)
385
+ * })) {
386
+ * encoder.encodeSync(frame);
387
+ * }
388
+ * ```
389
+ *
390
+ * @example
391
+ * ```typescript
392
+ * // Single frames
393
+ * for (using frame of complex.framesSync('out', {
394
+ * '0:v': frame1,
395
+ * '1:v': frame2
396
+ * })) {
397
+ * encoder.encodeSync(frame);
398
+ * }
399
+ * ```
400
+ *
401
+ * @example
402
+ * ```typescript
403
+ * // Explicit flush
404
+ * for (using frame of complex.framesSync('out', {
405
+ * '0:v': null,
406
+ * '1:v': null
407
+ * })) {
408
+ * encoder.encodeSync(frame);
409
+ * }
410
+ * ```
411
+ *
412
+ * @see {@link processSync} For manual frame sending
413
+ * @see {@link receiveSync} For manual frame receiving
414
+ * @see {@link frames} For async version with lazy initialization
415
+ */
416
+ framesSync(outLabel: string, inputs: Record<string, Iterable<Frame | null> | Frame | null>): Generator<Frame | null>;
417
+ /**
418
+ * Flush input(s) and signal end-of-stream.
419
+ *
420
+ * Sends null frame to buffersrc filter(s) to flush buffered data.
421
+ * Must call receive() on outputs to get flushed frames.
422
+ * Does nothing if filter is closed or was never initialized.
423
+ *
424
+ * Direct mapping to av_buffersrc_add_frame(NULL).
425
+ *
426
+ * @param inLabel - Input label to flush. If not specified, flushes all inputs.
427
+ *
428
+ * @throws {Error} If input label not found
429
+ *
430
+ * @throws {FFmpegError} If flush fails
431
+ *
432
+ * @example
433
+ * ```typescript
434
+ * // Flush specific input
435
+ * await complex.flush('0:v');
436
+ *
437
+ * // Flush all inputs
438
+ * await complex.flush();
439
+ *
440
+ * // Get remaining frames from output
441
+ * let frame;
442
+ * while ((frame = await complex.receive('out')) !== null) {
443
+ * frame.free();
444
+ * }
445
+ * ```
446
+ *
447
+ * @see {@link flushFrames} For async iteration
448
+ * @see {@link receive} For getting flushed frames
449
+ * @see {@link flushSync} For synchronous version
450
+ */
451
+ flush(inLabel?: string): Promise<void>;
452
+ /**
453
+ * Flush input(s) and signal end-of-stream synchronously.
454
+ * Synchronous version of flush.
455
+ *
456
+ * Sends null frame to buffersrc filter(s) to flush buffered data.
457
+ * Must call receiveSync() on outputs to get flushed frames.
458
+ * Does nothing if filter is closed or was never initialized.
459
+ *
460
+ * Direct mapping to av_buffersrc_add_frame(NULL).
461
+ *
462
+ * @param inLabel - Input label to flush. If not specified, flushes all inputs.
463
+ *
464
+ * @throws {Error} If input label not found
465
+ *
466
+ * @throws {FFmpegError} If flush fails
467
+ *
468
+ * @example
469
+ * ```typescript
470
+ * // Flush specific input
471
+ * complex.flushSync('0:v');
472
+ *
473
+ * // Flush all inputs
474
+ * complex.flushSync();
475
+ *
476
+ * // Get remaining frames from output
477
+ * let frame;
478
+ * while ((frame = complex.receiveSync('out')) !== null) {
479
+ * frame.free();
480
+ * }
481
+ * ```
482
+ *
483
+ * @see {@link flushFramesSync} For sync iteration
484
+ * @see {@link receiveSync} For getting flushed frames
485
+ * @see {@link flush} For async version
486
+ */
487
+ flushSync(inLabel?: string): void;
488
+ /**
489
+ * Flush all inputs and yield remaining frames from specified output.
490
+ *
491
+ * Convenience method that:
492
+ * 1. Calls flush() to send EOF to all inputs
493
+ * 2. Yields all remaining frames from the specified output
494
+ * 3. Continues until EOF is reached
495
+ *
496
+ * Automatically frees yielded frames after use (using declaration).
497
+ *
498
+ * @param outLabel - Output label to receive flushed frames from
499
+ *
500
+ * @yields {Frame} Remaining frames from filter after flush
501
+ *
502
+ * @throws {Error} If output label not found or filter not initialized
503
+ *
504
+ * @throws {FFmpegError} If flushing or receiving fails
505
+ *
506
+ * @example
507
+ * ```typescript
508
+ * // Process all frames, then flush
509
+ * for await (using frame of inputFrames) {
510
+ * await complex.process('0:v', frame);
511
+ * }
512
+ *
513
+ * // Get all remaining frames
514
+ * for await (using frame of complex.flushFrames('out')) {
515
+ * await encoder.encode(frame);
516
+ * }
517
+ * ```
518
+ *
519
+ * @see {@link flush} For flushing without iteration
520
+ * @see {@link receive} For manual frame retrieval
521
+ * @see {@link flushFramesSync} For synchronous version
522
+ */
523
+ flushFrames(outLabel: string): AsyncGenerator<Frame>;
524
+ /**
525
+ * Flush all inputs and yield remaining frames from specified output synchronously.
526
+ * Synchronous version of flushFrames.
527
+ *
528
+ * Convenience method that:
529
+ * 1. Calls flushSync() to send EOF to all inputs
530
+ * 2. Yields all remaining frames from the specified output
531
+ * 3. Continues until EOF is reached
532
+ *
533
+ * Automatically frees yielded frames after use (using declaration).
534
+ *
535
+ * @param outLabel - Output label to receive flushed frames from
536
+ *
537
+ * @yields {Frame} Remaining frames from filter after flush
538
+ *
539
+ * @throws {Error} If output label not found or filter not initialized
540
+ *
541
+ * @throws {FFmpegError} If flushing or receiving fails
542
+ *
543
+ * @example
544
+ * ```typescript
545
+ * // Process all frames, then flush
546
+ * for (using frame of inputFrames) {
547
+ * complex.processSync('0:v', frame);
548
+ * }
549
+ *
550
+ * // Get all remaining frames
551
+ * for (using frame of complex.flushFramesSync('out')) {
552
+ * encoder.encodeSync(frame);
553
+ * }
554
+ * ```
555
+ *
556
+ * @see {@link flushSync} For flushing without iteration
557
+ * @see {@link receiveSync} For manual frame retrieval
558
+ * @see {@link flushFrames} For async version
559
+ */
560
+ flushFramesSync(outLabel: string): Generator<Frame>;
561
+ /**
562
+ * Receive filtered frame from specified output.
563
+ *
564
+ * Pulls a single frame from the buffersink of the specified output.
565
+ * Automatically post-processes frame (sets timeBase, calculates duration).
566
+ * Returns cloned frame - caller must free it.
567
+ *
568
+ * Return values:
569
+ * - Frame: Successfully received frame (caller must free)
570
+ * - null: Need more input (AVERROR_EAGAIN) - call process() to send more frames
571
+ * - EOF: End of stream reached
572
+ *
573
+ * Direct mapping to av_buffersink_get_frame().
574
+ *
575
+ * @param outLabel - Output label to receive from
576
+ *
577
+ * @returns Frame on success, null if need more input, EOF if finished
578
+ *
579
+ * @throws {Error} If output label not found or filter not initialized
580
+ *
581
+ * @throws {FFmpegError} If receive fails with unexpected error
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * // Process frames one at a time
586
+ * await complex.process('0:v', frame1);
587
+ * const outFrame = await complex.receive('out');
588
+ * if (outFrame && outFrame !== EOF) {
589
+ * // Use frame
590
+ * outFrame.free();
591
+ * }
592
+ * ```
593
+ *
594
+ * @see {@link process} For sending input frames
595
+ * @see {@link flush} For flushing after all input
596
+ * @see {@link receiveSync} For synchronous version
597
+ */
598
+ receive(outLabel: string): Promise<Frame | EOFSignal | null>;
599
+ /**
600
+ * Receive filtered frame from specified output synchronously.
601
+ * Synchronous version of receive.
602
+ *
603
+ * Pulls a single frame from the buffersink of the specified output.
604
+ * Automatically post-processes frame (sets timeBase, calculates duration).
605
+ * Returns cloned frame - caller must free it.
606
+ *
607
+ * Return values:
608
+ * - Frame: Successfully received frame (caller must free)
609
+ * - null: Need more input (AVERROR_EAGAIN) - call processSync() to send more frames
610
+ * - EOF: End of stream reached
611
+ *
612
+ * Direct mapping to av_buffersink_get_frame().
613
+ *
614
+ * @param outLabel - Output label to receive from
615
+ *
616
+ * @returns Frame on success, null if need more input, EOF if finished
617
+ *
618
+ * @throws {Error} If output label not found or filter not initialized
619
+ *
620
+ * @throws {FFmpegError} If receive fails with unexpected error
621
+ *
622
+ * @example
623
+ * ```typescript
624
+ * // Process frames one at a time
625
+ * complex.processSync('0:v', frame1);
626
+ * const outFrame = complex.receiveSync('out');
627
+ * if (outFrame && outFrame !== EOF) {
628
+ * // Use frame
629
+ * outFrame.free();
630
+ * }
631
+ * ```
632
+ *
633
+ * @see {@link processSync} For sending input frames
634
+ * @see {@link flushSync} For flushing after all input
635
+ * @see {@link receive} For async version
636
+ */
637
+ receiveSync(outLabel: string): Frame | EOFSignal | null;
638
+ /**
639
+ * Check if all inputs have received at least one frame (have format information).
640
+ *
641
+ * @returns true if all inputs have format info (first frame received)
642
+ *
643
+ * @internal
644
+ */
645
+ private hasAllInputFormats;
646
+ /**
647
+ * Initialize filter graph from queued frames.
648
+ *
649
+ * Implements FFmpeg's configure_filtergraph() logic:
650
+ * 1. Create buffersrc filters from first queued frame of each input
651
+ * 2. Parse filter description
652
+ * 3. Create buffersink filters
653
+ * 4. Configure graph with avfilter_graph_config()
654
+ * 5. Send all queued frames to buffersrc
655
+ *
656
+ * @throws {Error} If initialization fails
657
+ *
658
+ * @throws {FFmpegError} If configuration fails
659
+ *
660
+ * @internal
661
+ */
662
+ private initializeFromQueuedFrames;
663
+ /**
664
+ * Initialize filter graph from queued frames synchronously.
665
+ * Synchronous version of initializeFromQueuedFrames.
666
+ *
667
+ * @throws {Error} If closed or inputs have no queued frames
668
+ *
669
+ * @throws {FFmpegError} If graph configuration or frame processing fails
670
+ *
671
+ * @internal
672
+ */
673
+ private initializeFromQueuedFramesSync;
674
+ /**
675
+ * Calculate timeBase from frame based on media type and CFR option.
676
+ *
677
+ * Implements FFmpeg's ifilter_parameters_from_frame logic:
678
+ * - Audio: Always { 1, sample_rate }
679
+ * - Video CFR: 1/framerate (inverse of framerate)
680
+ * - Video VFR: Use frame.timeBase
681
+ *
682
+ * @param frame - Input frame
683
+ *
684
+ * @returns Calculated timeBase
685
+ *
686
+ * @internal
687
+ */
688
+ private calculateTimeBase;
689
+ /**
690
+ * Rescale frame timestamps to calculated timeBase.
691
+ *
692
+ * Helper to avoid code duplication when rescaling timestamps.
693
+ * Modifies the frame in-place.
694
+ *
695
+ * @param frame - Frame to rescale
696
+ *
697
+ * @param calculatedTimeBase - Target timeBase
698
+ *
699
+ * @internal
700
+ */
701
+ private rescaleFrameTimestamps;
702
+ /**
703
+ * Create buffer source for an input.
704
+ *
705
+ * @param label - Input label
706
+ *
707
+ * @param frame - First frame from this input
708
+ *
709
+ * @param timeBase - Calculated timeBase for this input (from calculateTimeBase)
710
+ *
711
+ * @returns BufferSrc filter context
712
+ *
713
+ * @throws {Error} If creation fails
714
+ *
715
+ * @internal
716
+ */
717
+ private createBufferSource;
718
+ /**
719
+ * Create buffer sink for an output.
720
+ *
721
+ * @param label - Output label
722
+ *
723
+ * @param isVideo - Whether this is a video output
724
+ *
725
+ * @returns BufferSink filter context
726
+ *
727
+ * @throws {Error} If creation fails
728
+ *
729
+ * @internal
730
+ */
731
+ private createBufferSink;
732
+ /**
733
+ * Parse filter description and build graph using segment API.
734
+ *
735
+ * @throws {Error} If parsing fails
736
+ *
737
+ * @throws {FFmpegError} If graph construction fails
738
+ *
739
+ * @internal
740
+ */
741
+ private parseFilterDescription;
742
+ /**
743
+ * Link buffersrc filters to segment inputs.
744
+ *
745
+ * Iterates through FilterInOut chain and links by label.
746
+ *
747
+ * @param inputs - FilterInOut chain of segment inputs
748
+ *
749
+ * @throws {Error} If linking fails
750
+ *
751
+ * @internal
752
+ */
753
+ private linkBufferSources;
754
+ /**
755
+ * Link segment outputs to buffersink filters.
756
+ *
757
+ * Iterates through FilterInOut chain and links by label.
758
+ *
759
+ * @param outputs - FilterInOut chain of segment outputs
760
+ *
761
+ * @throws {Error} If linking fails
762
+ *
763
+ * @internal
764
+ */
765
+ private linkBufferSinks;
766
+ /**
767
+ * Post-process output frame from buffersink.
768
+ *
769
+ * Applies FFmpeg's fg_output_step() behavior:
770
+ * 1. Sets frame.timeBase from buffersink (filters can change timeBase)
771
+ * 2. Calculates video frame duration from frame rate if not set
772
+ *
773
+ * This must be called AFTER buffersinkGetFrame() for every output frame.
774
+ *
775
+ * @param frame - Output frame from buffersink
776
+ *
777
+ * @param buffersink - The buffersink context
778
+ *
779
+ * @internal
780
+ */
781
+ private postProcessOutputFrame;
782
+ /**
783
+ * Close filter complex and release resources.
784
+ *
785
+ * Frees queued frames, filter graph and all filter contexts.
786
+ * Safe to call multiple times.
787
+ *
788
+ * @example
789
+ * ```typescript
790
+ * complex.close();
791
+ * ```
792
+ *
793
+ * @example
794
+ * ```typescript
795
+ * // Automatic cleanup with using
796
+ * {
797
+ * using complex = FilterComplexAPI.create('[0:v]scale=640:480[out]', { ... });
798
+ * // Use complex...
799
+ * } // Automatically freed
800
+ * ```
801
+ *
802
+ * @see {@link Symbol.dispose} For automatic cleanup
803
+ */
804
+ close(): void;
805
+ /**
806
+ * Dispose of filter complex.
807
+ *
808
+ * Implements Disposable interface for automatic cleanup.
809
+ *
810
+ * @example
811
+ * ```typescript
812
+ * {
813
+ * using complex = FilterComplexAPI.create('[0:v]scale=640:480[out]', { ... });
814
+ * // Use complex...
815
+ * } // Automatically freed
816
+ * ```
817
+ *
818
+ * @see {@link close} For manual cleanup
819
+ */
820
+ [Symbol.dispose](): void;
821
+ }