node-av 0.0.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 (175) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +377 -0
  4. package/binding.gyp +78 -0
  5. package/dist/api/bitstream-filter.d.ts +246 -0
  6. package/dist/api/bitstream-filter.js +369 -0
  7. package/dist/api/bitstream-filter.js.map +1 -0
  8. package/dist/api/decoder.d.ts +257 -0
  9. package/dist/api/decoder.js +424 -0
  10. package/dist/api/decoder.js.map +1 -0
  11. package/dist/api/encoder.d.ts +298 -0
  12. package/dist/api/encoder.js +574 -0
  13. package/dist/api/encoder.js.map +1 -0
  14. package/dist/api/filter.d.ts +457 -0
  15. package/dist/api/filter.js +876 -0
  16. package/dist/api/filter.js.map +1 -0
  17. package/dist/api/hardware.d.ts +318 -0
  18. package/dist/api/hardware.js +558 -0
  19. package/dist/api/hardware.js.map +1 -0
  20. package/dist/api/index.d.ts +12 -0
  21. package/dist/api/index.js +20 -0
  22. package/dist/api/index.js.map +1 -0
  23. package/dist/api/io-stream.d.ts +109 -0
  24. package/dist/api/io-stream.js +124 -0
  25. package/dist/api/io-stream.js.map +1 -0
  26. package/dist/api/media-input.d.ts +295 -0
  27. package/dist/api/media-input.js +456 -0
  28. package/dist/api/media-input.js.map +1 -0
  29. package/dist/api/media-output.d.ts +274 -0
  30. package/dist/api/media-output.js +486 -0
  31. package/dist/api/media-output.js.map +1 -0
  32. package/dist/api/pipeline.d.ts +117 -0
  33. package/dist/api/pipeline.js +836 -0
  34. package/dist/api/pipeline.js.map +1 -0
  35. package/dist/api/types.d.ts +440 -0
  36. package/dist/api/types.js +2 -0
  37. package/dist/api/types.js.map +1 -0
  38. package/dist/api/utilities/audio-sample.d.ts +115 -0
  39. package/dist/api/utilities/audio-sample.js +110 -0
  40. package/dist/api/utilities/audio-sample.js.map +1 -0
  41. package/dist/api/utilities/channel-layout.d.ts +83 -0
  42. package/dist/api/utilities/channel-layout.js +87 -0
  43. package/dist/api/utilities/channel-layout.js.map +1 -0
  44. package/dist/api/utilities/image.d.ts +177 -0
  45. package/dist/api/utilities/image.js +183 -0
  46. package/dist/api/utilities/image.js.map +1 -0
  47. package/dist/api/utilities/index.d.ts +8 -0
  48. package/dist/api/utilities/index.js +17 -0
  49. package/dist/api/utilities/index.js.map +1 -0
  50. package/dist/api/utilities/media-type.d.ts +56 -0
  51. package/dist/api/utilities/media-type.js +60 -0
  52. package/dist/api/utilities/media-type.js.map +1 -0
  53. package/dist/api/utilities/pixel-format.d.ts +94 -0
  54. package/dist/api/utilities/pixel-format.js +102 -0
  55. package/dist/api/utilities/pixel-format.js.map +1 -0
  56. package/dist/api/utilities/sample-format.d.ts +132 -0
  57. package/dist/api/utilities/sample-format.js +144 -0
  58. package/dist/api/utilities/sample-format.js.map +1 -0
  59. package/dist/api/utilities/streaming.d.ts +104 -0
  60. package/dist/api/utilities/streaming.js +137 -0
  61. package/dist/api/utilities/streaming.js.map +1 -0
  62. package/dist/api/utilities/timestamp.d.ts +187 -0
  63. package/dist/api/utilities/timestamp.js +200 -0
  64. package/dist/api/utilities/timestamp.js.map +1 -0
  65. package/dist/api/utils.d.ts +61 -0
  66. package/dist/api/utils.js +330 -0
  67. package/dist/api/utils.js.map +1 -0
  68. package/dist/index.d.ts +2 -0
  69. package/dist/index.js +5 -0
  70. package/dist/index.js.map +1 -0
  71. package/dist/lib/audio-fifo.d.ts +339 -0
  72. package/dist/lib/audio-fifo.js +365 -0
  73. package/dist/lib/audio-fifo.js.map +1 -0
  74. package/dist/lib/binding.d.ts +192 -0
  75. package/dist/lib/binding.js +70 -0
  76. package/dist/lib/binding.js.map +1 -0
  77. package/dist/lib/bitstream-filter-context.d.ts +345 -0
  78. package/dist/lib/bitstream-filter-context.js +407 -0
  79. package/dist/lib/bitstream-filter-context.js.map +1 -0
  80. package/dist/lib/bitstream-filter.d.ts +124 -0
  81. package/dist/lib/bitstream-filter.js +138 -0
  82. package/dist/lib/bitstream-filter.js.map +1 -0
  83. package/dist/lib/channel-layouts.d.ts +51 -0
  84. package/dist/lib/channel-layouts.js +55 -0
  85. package/dist/lib/channel-layouts.js.map +1 -0
  86. package/dist/lib/codec-context.d.ts +763 -0
  87. package/dist/lib/codec-context.js +974 -0
  88. package/dist/lib/codec-context.js.map +1 -0
  89. package/dist/lib/codec-parameters.d.ts +362 -0
  90. package/dist/lib/codec-parameters.js +460 -0
  91. package/dist/lib/codec-parameters.js.map +1 -0
  92. package/dist/lib/codec-parser.d.ts +185 -0
  93. package/dist/lib/codec-parser.js +193 -0
  94. package/dist/lib/codec-parser.js.map +1 -0
  95. package/dist/lib/codec.d.ts +432 -0
  96. package/dist/lib/codec.js +492 -0
  97. package/dist/lib/codec.js.map +1 -0
  98. package/dist/lib/constants.d.ts +2037 -0
  99. package/dist/lib/constants.js +1659 -0
  100. package/dist/lib/constants.js.map +1 -0
  101. package/dist/lib/dictionary.d.ts +371 -0
  102. package/dist/lib/dictionary.js +406 -0
  103. package/dist/lib/dictionary.js.map +1 -0
  104. package/dist/lib/error.d.ts +216 -0
  105. package/dist/lib/error.js +254 -0
  106. package/dist/lib/error.js.map +1 -0
  107. package/dist/lib/filter-context.d.ts +445 -0
  108. package/dist/lib/filter-context.js +505 -0
  109. package/dist/lib/filter-context.js.map +1 -0
  110. package/dist/lib/filter-graph.d.ts +556 -0
  111. package/dist/lib/filter-graph.js +608 -0
  112. package/dist/lib/filter-graph.js.map +1 -0
  113. package/dist/lib/filter-inout.d.ts +205 -0
  114. package/dist/lib/filter-inout.js +264 -0
  115. package/dist/lib/filter-inout.js.map +1 -0
  116. package/dist/lib/filter.d.ts +231 -0
  117. package/dist/lib/filter.js +260 -0
  118. package/dist/lib/filter.js.map +1 -0
  119. package/dist/lib/format-context.d.ts +798 -0
  120. package/dist/lib/format-context.js +845 -0
  121. package/dist/lib/format-context.js.map +1 -0
  122. package/dist/lib/frame.d.ts +784 -0
  123. package/dist/lib/frame.js +933 -0
  124. package/dist/lib/frame.js.map +1 -0
  125. package/dist/lib/hardware-device-context.d.ts +407 -0
  126. package/dist/lib/hardware-device-context.js +429 -0
  127. package/dist/lib/hardware-device-context.js.map +1 -0
  128. package/dist/lib/hardware-frames-context.d.ts +374 -0
  129. package/dist/lib/hardware-frames-context.js +430 -0
  130. package/dist/lib/hardware-frames-context.js.map +1 -0
  131. package/dist/lib/index.d.ts +31 -0
  132. package/dist/lib/index.js +54 -0
  133. package/dist/lib/index.js.map +1 -0
  134. package/dist/lib/input-format.d.ts +216 -0
  135. package/dist/lib/input-format.js +246 -0
  136. package/dist/lib/input-format.js.map +1 -0
  137. package/dist/lib/io-context.d.ts +495 -0
  138. package/dist/lib/io-context.js +550 -0
  139. package/dist/lib/io-context.js.map +1 -0
  140. package/dist/lib/log.d.ts +201 -0
  141. package/dist/lib/log.js +219 -0
  142. package/dist/lib/log.js.map +1 -0
  143. package/dist/lib/native-types.d.ts +719 -0
  144. package/dist/lib/native-types.js +2 -0
  145. package/dist/lib/native-types.js.map +1 -0
  146. package/dist/lib/option.d.ts +589 -0
  147. package/dist/lib/option.js +853 -0
  148. package/dist/lib/option.js.map +1 -0
  149. package/dist/lib/output-format.d.ts +179 -0
  150. package/dist/lib/output-format.js +205 -0
  151. package/dist/lib/output-format.js.map +1 -0
  152. package/dist/lib/packet.d.ts +487 -0
  153. package/dist/lib/packet.js +558 -0
  154. package/dist/lib/packet.js.map +1 -0
  155. package/dist/lib/rational.d.ts +210 -0
  156. package/dist/lib/rational.js +233 -0
  157. package/dist/lib/rational.js.map +1 -0
  158. package/dist/lib/software-resample-context.d.ts +572 -0
  159. package/dist/lib/software-resample-context.js +610 -0
  160. package/dist/lib/software-resample-context.js.map +1 -0
  161. package/dist/lib/software-scale-context.d.ts +290 -0
  162. package/dist/lib/software-scale-context.js +308 -0
  163. package/dist/lib/software-scale-context.js.map +1 -0
  164. package/dist/lib/stream.d.ts +322 -0
  165. package/dist/lib/stream.js +408 -0
  166. package/dist/lib/stream.js.map +1 -0
  167. package/dist/lib/types.d.ts +59 -0
  168. package/dist/lib/types.js +8 -0
  169. package/dist/lib/types.js.map +1 -0
  170. package/dist/lib/utilities.d.ts +346 -0
  171. package/dist/lib/utilities.js +424 -0
  172. package/dist/lib/utilities.js.map +1 -0
  173. package/install/check.js +113 -0
  174. package/install/ffmpeg.js +163 -0
  175. package/package.json +107 -0
@@ -0,0 +1,486 @@
1
+ /**
2
+ * MediaOutput - Unified Output Handler for FFmpeg
3
+ *
4
+ * Provides a high-level interface for writing media to various destinations.
5
+ * Supports files, streams, and custom IO with automatic format configuration.
6
+ *
7
+ * Central entry point for all media output operations.
8
+ * Manages FormatContext lifecycle and provides stream management.
9
+ *
10
+ * @module api/media-output
11
+ */
12
+ import { AVFMT_FLAG_CUSTOM_IO, AVFMT_NOFILE, AVIO_FLAG_WRITE, FFmpegError, FormatContext, IOContext, Rational } from '../lib/index.js';
13
+ import { Encoder } from './encoder.js';
14
+ /**
15
+ * MediaOutput - High-level media output handler.
16
+ *
17
+ * Creates and manages media containers for writing encoded streams.
18
+ * Automatically handles format setup and stream configuration.
19
+ *
20
+ * Manages the FormatContext and provides convenient methods for
21
+ * adding streams, writing packets, and finalizing output.
22
+ *
23
+ * @example
24
+ * ```typescript
25
+ * import { MediaOutput, Encoder } from 'node-av/api';
26
+ *
27
+ * // Open output file
28
+ * const output = await MediaOutput.open('output.mp4');
29
+ *
30
+ * // Add encoder stream
31
+ * const encoder = await Encoder.create('libx264', {
32
+ * width: 1920,
33
+ * height: 1080,
34
+ * pixelFormat: AV_PIX_FMT_YUV420P
35
+ * });
36
+ * const streamIdx = output.addStream(encoder);
37
+ *
38
+ * // Write header, packets, trailer
39
+ * await output.writeHeader();
40
+ * await output.writePacket(packet, streamIdx);
41
+ * await output.writeTrailer();
42
+ * await output.close();
43
+ * ```
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * // Stream copy without re-encoding
48
+ * const input = await MediaInput.open('input.mp4');
49
+ * const output = await MediaOutput.open('output.mkv');
50
+ *
51
+ * const videoStream = input.video();
52
+ * const streamIdx = output.addStream(videoStream);
53
+ *
54
+ * await output.writeHeader();
55
+ * for await (const packet of input.packets()) {
56
+ * if (packet.streamIndex === videoStream.index) {
57
+ * await output.writePacket(packet, streamIdx);
58
+ * }
59
+ * }
60
+ * await output.writeTrailer();
61
+ * ```
62
+ */
63
+ export class MediaOutput {
64
+ formatContext;
65
+ streams = new Map();
66
+ ioContext;
67
+ headerWritten = false;
68
+ trailerWritten = false;
69
+ closed = false;
70
+ /**
71
+ * Private constructor - use MediaOutput.open() instead.
72
+ *
73
+ * Initializes the output with a new FormatContext.
74
+ * The actual format setup happens in the static factory method.
75
+ */
76
+ constructor() {
77
+ this.formatContext = new FormatContext();
78
+ }
79
+ /**
80
+ * Opens a media output for writing with custom IO callbacks or stream URL or file output
81
+ *
82
+ * Creates a FormatContext and prepares the output for writing.
83
+ * Automatically detects format from filename/URL if not specified.
84
+ *
85
+ * If io callbacks is used, it creates a FormatContext with custom IO handling.
86
+ * Format must be explicitly specified for custom IO.
87
+ *
88
+ * Uses avformat_alloc_output_context2() and avio_alloc_context() internally.
89
+ *
90
+ * @param target - File path or stream URL or custom IO callbacks
91
+ * @param options - Optional configuration
92
+ *
93
+ * @returns Promise resolving to MediaOutput instance
94
+ *
95
+ * @throws {Error} If format not specified or context allocation fails
96
+ *
97
+ * @example
98
+ * ```typescript
99
+ * const callbacks = {
100
+ * write: (buffer) => myStream.write(buffer),
101
+ * seek: (offset, whence) => offset
102
+ * };
103
+ * const output = await MediaOutput.open(callbacks, { format: 'mp4' });
104
+ * ```
105
+ *
106
+ * @example
107
+ * ```typescript
108
+ * const output = await MediaOutput.open('output.mp4');
109
+ * ```
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const output = await MediaOutput.open('rtmp://server/live/streamkey', { format: 'flv' });
114
+ * ```
115
+ */
116
+ static async open(target, options) {
117
+ const output = new MediaOutput();
118
+ try {
119
+ if (typeof target === 'string') {
120
+ // File or stream URL
121
+ const ret = output.formatContext.allocOutputContext2(null, options?.format ?? null, target === '' ? null : target);
122
+ FFmpegError.throwIfError(ret, 'Failed to allocate output context');
123
+ // Check if we need to open IO
124
+ const oformat = output.formatContext.oformat;
125
+ if (target && oformat && !(oformat.flags & AVFMT_NOFILE)) {
126
+ // For file-based formats, we need to open the file using avio_open2
127
+ // FFmpeg will manage the AVIOContext internally
128
+ output.ioContext = new IOContext();
129
+ const openRet = await output.ioContext.open2(target, AVIO_FLAG_WRITE);
130
+ FFmpegError.throwIfError(openRet, `Failed to open output file: ${target}`);
131
+ output.formatContext.pb = output.ioContext;
132
+ }
133
+ }
134
+ else {
135
+ // Custom IO with callbacks - format is required
136
+ if (!options?.format) {
137
+ throw new Error('Format must be specified for custom IO');
138
+ }
139
+ const ret = output.formatContext.allocOutputContext2(null, options.format, null);
140
+ FFmpegError.throwIfError(ret, 'Failed to allocate output context');
141
+ // Setup custom IO with callbacks
142
+ output.ioContext = new IOContext();
143
+ output.ioContext.allocContextWithCallbacks(options.bufferSize ?? 4096, 1, target.read, target.write, target.seek);
144
+ output.ioContext.maxPacketSize = options.bufferSize ?? 4096;
145
+ output.formatContext.pb = output.ioContext;
146
+ output.formatContext.flags = AVFMT_FLAG_CUSTOM_IO;
147
+ }
148
+ return output;
149
+ }
150
+ catch (error) {
151
+ // Cleanup on error
152
+ if (output.ioContext) {
153
+ try {
154
+ if (output.formatContext.flags & AVFMT_FLAG_CUSTOM_IO) {
155
+ // Clear the pb reference first
156
+ output.formatContext.pb = null;
157
+ // For custom IO with callbacks, free the context
158
+ output.ioContext.freeContext();
159
+ }
160
+ else {
161
+ // For file-based IO, close the file handle
162
+ await output.ioContext.closep();
163
+ }
164
+ }
165
+ catch {
166
+ // Ignore errors
167
+ }
168
+ }
169
+ if (output.formatContext) {
170
+ try {
171
+ output.formatContext.freeContext();
172
+ }
173
+ catch {
174
+ // Ignore errors
175
+ }
176
+ }
177
+ throw error;
178
+ }
179
+ }
180
+ /**
181
+ * Adds a stream to the output container.
182
+ *
183
+ * Creates a new stream in the output format context.
184
+ * Copies codec parameters from encoder or input stream.
185
+ *
186
+ * Uses avformat_new_stream() and avcodec_parameters_copy() internally.
187
+ *
188
+ * @param source - Encoder for transcoding or Stream for copying
189
+ * @param options - Optional stream configuration
190
+ * @param options.timeBase - Custom output timebase for the stream.
191
+ * If not specified, uses the source's timebase.
192
+ * When set, packets will be automatically rescaled
193
+ * from source timebase to this output timebase.
194
+ *
195
+ * @returns Stream index for packet writing
196
+ *
197
+ * @throws {Error} If called after header is written or output is closed
198
+ *
199
+ * @example
200
+ * ```typescript
201
+ * // Add encoder stream (transcoding) - uses encoder's timebase
202
+ * const encoder = await Encoder.create('libx264', { width: 1920, height: 1080 });
203
+ * const streamIdx = output.addStream(encoder);
204
+ * ```
205
+ *
206
+ * @example
207
+ * ```typescript
208
+ * // Add stream for direct copy - uses input stream's timebase
209
+ * const inputStream = input.video();
210
+ * const streamIdx = output.addStream(inputStream);
211
+ * ```
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * // Custom output timebase (e.g., for format requirements)
216
+ * const streamIdx = output.addStream(encoder, {
217
+ * timeBase: { num: 1, den: 90000 } // MPEG-TS standard
218
+ * });
219
+ * // Packets from encoder will be automatically rescaled to 1/90000
220
+ * ```
221
+ */
222
+ addStream(source, options) {
223
+ if (this.closed) {
224
+ throw new Error('MediaOutput is closed');
225
+ }
226
+ if (this.headerWritten) {
227
+ throw new Error('Cannot add streams after header is written');
228
+ }
229
+ const stream = this.formatContext.newStream(null);
230
+ if (!stream) {
231
+ throw new Error('Failed to create new stream');
232
+ }
233
+ let isStreamCopy = false;
234
+ let sourceTimeBase;
235
+ if (source instanceof Encoder) {
236
+ // Transcoding with encoder
237
+ const codecContext = source.getCodecContext();
238
+ if (!codecContext) {
239
+ throw new Error('Failed to get codec context from encoder');
240
+ }
241
+ const ret = stream.codecpar.fromContext(codecContext);
242
+ FFmpegError.throwIfError(ret, 'Failed to copy codec parameters from encoder');
243
+ // Store the encoder's timebase as source (we'll need it for rescaling)
244
+ sourceTimeBase = codecContext.timeBase;
245
+ // Output stream uses encoder's timebase (or custom if specified)
246
+ stream.timeBase = options?.timeBase ? new Rational(options.timeBase.num, options.timeBase.den) : codecContext.timeBase;
247
+ }
248
+ else {
249
+ // Stream copy
250
+ const ret = source.codecpar.copy(stream.codecpar);
251
+ FFmpegError.throwIfError(ret, 'Failed to copy codec parameters');
252
+ // Store the input stream's timebase as source (we'll need it for rescaling)
253
+ sourceTimeBase = source.timeBase;
254
+ // Output stream uses input stream's timebase (or custom if specified)
255
+ stream.timeBase = options?.timeBase ? new Rational(options.timeBase.num, options.timeBase.den) : source.timeBase;
256
+ stream.codecpar.codecTag = 0; // Important for format compatibility
257
+ isStreamCopy = true;
258
+ }
259
+ this.streams.set(stream.index, {
260
+ stream,
261
+ timeBase: stream.timeBase,
262
+ isStreamCopy,
263
+ sourceTimeBase,
264
+ });
265
+ return stream.index;
266
+ }
267
+ /**
268
+ * Writes a packet to the output container.
269
+ *
270
+ * Writes an encoded packet to the specified stream.
271
+ * Automatically sets the stream index on the packet.
272
+ *
273
+ * Uses av_interleaved_write_frame() internally.
274
+ *
275
+ * @param packet - Packet to write
276
+ * @param streamIndex - Target stream index
277
+ *
278
+ * @throws {Error} If header not written, trailer already written, or invalid stream
279
+ *
280
+ * @example
281
+ * ```typescript
282
+ * const encoded = await encoder.encode(frame);
283
+ * if (encoded) {
284
+ * await output.writePacket(encoded, streamIdx);
285
+ * encoded.free();
286
+ * }
287
+ * ```
288
+ */
289
+ async writePacket(packet, streamIndex) {
290
+ if (this.closed) {
291
+ throw new Error('MediaOutput is closed');
292
+ }
293
+ if (!this.headerWritten) {
294
+ throw new Error('Header must be written before packets');
295
+ }
296
+ if (this.trailerWritten) {
297
+ throw new Error('Cannot write packets after trailer');
298
+ }
299
+ const streamInfo = this.streams.get(streamIndex);
300
+ if (!streamInfo) {
301
+ throw new Error(`Invalid stream index: ${streamIndex}`);
302
+ }
303
+ // Set stream index
304
+ packet.streamIndex = streamIndex;
305
+ // Rescale packet timestamps if source and output timebases differ
306
+ // Note: The stream's timebase may have been changed by writeHeader (e.g., MP4 uses 1/time_scale)
307
+ if (streamInfo.sourceTimeBase) {
308
+ const outputStream = this.formatContext.streams?.[streamIndex];
309
+ if (outputStream) {
310
+ // Only rescale if timebases actually differ
311
+ const srcTb = streamInfo.sourceTimeBase;
312
+ const dstTb = outputStream.timeBase;
313
+ if (srcTb.num !== dstTb.num || srcTb.den !== dstTb.den) {
314
+ packet.rescaleTs(streamInfo.sourceTimeBase, outputStream.timeBase);
315
+ }
316
+ }
317
+ }
318
+ // Write the packet
319
+ const ret = await this.formatContext.interleavedWriteFrame(packet);
320
+ FFmpegError.throwIfError(ret, 'Failed to write packet');
321
+ }
322
+ /**
323
+ * Writes the output file header.
324
+ *
325
+ * Writes the container header with stream information.
326
+ * Must be called before writing any packets.
327
+ *
328
+ * Uses avformat_write_header() internally.
329
+ *
330
+ * @param options - Optional header options (format-specific)
331
+ *
332
+ * @throws {Error} If header already written or output is closed
333
+ *
334
+ * @example
335
+ * ```typescript
336
+ * await output.writeHeader();
337
+ * ```
338
+ */
339
+ async writeHeader() {
340
+ if (this.closed) {
341
+ throw new Error('MediaOutput is closed');
342
+ }
343
+ if (this.headerWritten) {
344
+ throw new Error('Header already written');
345
+ }
346
+ const ret = await this.formatContext.writeHeader();
347
+ FFmpegError.throwIfError(ret, 'Failed to write header');
348
+ this.headerWritten = true;
349
+ }
350
+ /**
351
+ * Writes the output file trailer.
352
+ *
353
+ * Finalizes the output file with necessary metadata.
354
+ * Should be called after all packets have been written.
355
+ *
356
+ * Uses av_write_trailer() internally.
357
+ *
358
+ * @throws {Error} If header not written, trailer already written, or output is closed
359
+ *
360
+ * @example
361
+ * ```typescript
362
+ * await output.writeTrailer();
363
+ * ```
364
+ */
365
+ async writeTrailer() {
366
+ if (this.closed) {
367
+ throw new Error('MediaOutput is closed');
368
+ }
369
+ if (!this.headerWritten) {
370
+ throw new Error('Cannot write trailer without header');
371
+ }
372
+ if (this.trailerWritten) {
373
+ throw new Error('Trailer already written');
374
+ }
375
+ const ret = await this.formatContext.writeTrailer();
376
+ FFmpegError.throwIfError(ret, 'Failed to write trailer');
377
+ this.trailerWritten = true;
378
+ }
379
+ /**
380
+ * Closes the output and releases all resources.
381
+ *
382
+ * Writes trailer if needed, closes IO context, and frees format context.
383
+ * Safe to call multiple times.
384
+ *
385
+ * Uses av_write_trailer(), avio_closep(), and avformat_free_context() internally.
386
+ *
387
+ * @example
388
+ * ```typescript
389
+ * await output.close();
390
+ * ```
391
+ */
392
+ async close() {
393
+ if (this.closed) {
394
+ return;
395
+ }
396
+ this.closed = true;
397
+ // Try to write trailer if header was written but trailer wasn't
398
+ try {
399
+ if (this.headerWritten && !this.trailerWritten) {
400
+ await this.formatContext.writeTrailer();
401
+ }
402
+ }
403
+ catch {
404
+ // Ignore errors
405
+ }
406
+ // Clear pb reference first to prevent use-after-free
407
+ if (this.ioContext) {
408
+ this.formatContext.pb = null;
409
+ }
410
+ // For file-based IO, close the file handle via closep
411
+ // For custom IO, the context will be freed below
412
+ if (this.ioContext && !(this.formatContext.flags & AVFMT_FLAG_CUSTOM_IO)) {
413
+ try {
414
+ await this.ioContext.closep();
415
+ }
416
+ catch {
417
+ // Ignore errors
418
+ }
419
+ }
420
+ // Free format context
421
+ if (this.formatContext) {
422
+ try {
423
+ this.formatContext.freeContext();
424
+ }
425
+ catch {
426
+ // Ignore errors
427
+ }
428
+ }
429
+ // Now free custom IO context if present
430
+ if (this.ioContext && this.formatContext.flags & AVFMT_FLAG_CUSTOM_IO) {
431
+ try {
432
+ this.ioContext.freeContext();
433
+ }
434
+ catch {
435
+ // Ignore errors
436
+ }
437
+ }
438
+ }
439
+ /**
440
+ * Gets information about a specific stream.
441
+ */
442
+ getStreamInfo(streamIndex) {
443
+ return this.streams.get(streamIndex);
444
+ }
445
+ /**
446
+ * Gets all stream indices.
447
+ */
448
+ getStreamIndices() {
449
+ return Array.from(this.streams.keys());
450
+ }
451
+ /**
452
+ * Checks if header has been written.
453
+ */
454
+ isHeaderWritten() {
455
+ return this.headerWritten;
456
+ }
457
+ /**
458
+ * Checks if trailer has been written.
459
+ */
460
+ isTrailerWritten() {
461
+ return this.trailerWritten;
462
+ }
463
+ /**
464
+ * Gets the underlying format context.
465
+ *
466
+ * For advanced use cases requiring direct format context access.
467
+ */
468
+ getFormatContext() {
469
+ return this.formatContext;
470
+ }
471
+ /**
472
+ * AsyncDisposable implementation for using statement.
473
+ *
474
+ * Enables automatic resource cleanup with await using syntax.
475
+ *
476
+ * @example
477
+ * ```typescript
478
+ * await using output = await MediaOutput.open('output.mp4');
479
+ * // Output automatically closes when scope ends
480
+ * ```
481
+ */
482
+ async [Symbol.asyncDispose]() {
483
+ await this.close();
484
+ }
485
+ }
486
+ //# sourceMappingURL=media-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"media-output.js","sourceRoot":"","sources":["../../src/api/media-output.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,oBAAoB,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAC;AACvI,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAYvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH,MAAM,OAAO,WAAW;IACd,aAAa,CAAgB;IAC7B,OAAO,GAAG,IAAI,GAAG,EAAsB,CAAC;IACxC,SAAS,CAAa;IACtB,aAAa,GAAG,KAAK,CAAC;IACtB,cAAc,GAAG,KAAK,CAAC;IACvB,MAAM,GAAG,KAAK,CAAC;IAEvB;;;;;OAKG;IACH;QACE,IAAI,CAAC,aAAa,GAAG,IAAI,aAAa,EAAE,CAAC;IAC3C,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAoCG;IACH,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,MAAkC,EAAE,OAA4B;QAChF,MAAM,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAEjC,IAAI,CAAC;YACH,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC/B,qBAAqB;gBACrB,MAAM,GAAG,GAAG,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,EAAE,MAAM,IAAI,IAAI,EAAE,MAAM,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBACnH,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,mCAAmC,CAAC,CAAC;gBAEnE,8BAA8B;gBAC9B,MAAM,OAAO,GAAG,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC;gBAC7C,IAAI,MAAM,IAAI,OAAO,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,GAAG,YAAY,CAAC,EAAE,CAAC;oBACzD,oEAAoE;oBACpE,gDAAgD;oBAChD,MAAM,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;oBACnC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;oBACtE,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,+BAA+B,MAAM,EAAE,CAAC,CAAC;oBAC3E,MAAM,CAAC,aAAa,CAAC,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;gBAC7C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,gDAAgD;gBAChD,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,CAAC;oBACrB,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBAC5D,CAAC;gBAED,MAAM,GAAG,GAAG,MAAM,CAAC,aAAa,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gBACjF,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,mCAAmC,CAAC,CAAC;gBAEnE,iCAAiC;gBACjC,MAAM,CAAC,SAAS,GAAG,IAAI,SAAS,EAAE,CAAC;gBACnC,MAAM,CAAC,SAAS,CAAC,yBAAyB,CAAC,OAAO,CAAC,UAAU,IAAI,IAAI,EAAE,CAAC,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;gBAClH,MAAM,CAAC,SAAS,CAAC,aAAa,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;gBAC5D,MAAM,CAAC,aAAa,CAAC,EAAE,GAAG,MAAM,CAAC,SAAS,CAAC;gBAC3C,MAAM,CAAC,aAAa,CAAC,KAAK,GAAG,oBAAoB,CAAC;YACpD,CAAC;YAED,OAAO,MAAM,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,mBAAmB;YACnB,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACH,IAAI,MAAM,CAAC,aAAa,CAAC,KAAK,GAAG,oBAAoB,EAAE,CAAC;wBACtD,+BAA+B;wBAC/B,MAAM,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC;wBAC/B,iDAAiD;wBACjD,MAAM,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;oBACjC,CAAC;yBAAM,CAAC;wBACN,2CAA2C;wBAC3C,MAAM,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;oBAClC,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,gBAAgB;gBAClB,CAAC;YACH,CAAC;YACD,IAAI,MAAM,CAAC,aAAa,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,MAAM,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;gBACrC,CAAC;gBAAC,MAAM,CAAC;oBACP,gBAAgB;gBAClB,CAAC;YACH,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;IACH,SAAS,CACP,MAAwB,EACxB,OAEC;QAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,4CAA4C,CAAC,CAAC;QAChE,CAAC;QAED,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;QAED,IAAI,YAAY,GAAG,KAAK,CAAC;QACzB,IAAI,cAAqC,CAAC;QAE1C,IAAI,MAAM,YAAY,OAAO,EAAE,CAAC;YAC9B,2BAA2B;YAC3B,MAAM,YAAY,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;YAC9C,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YAC9D,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YACtD,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,8CAA8C,CAAC,CAAC;YAE9E,uEAAuE;YACvE,cAAc,GAAG,YAAY,CAAC,QAAQ,CAAC;YAEvC,iEAAiE;YACjE,MAAM,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,QAAQ,CAAC;QACzH,CAAC;aAAM,CAAC;YACN,cAAc;YACd,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YAClD,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;YAEjE,4EAA4E;YAC5E,cAAc,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEjC,sEAAsE;YACtE,MAAM,CAAC,QAAQ,GAAG,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,IAAI,QAAQ,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;YACjH,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,qCAAqC;YACnE,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,EAAE;YAC7B,MAAM;YACN,QAAQ,EAAE,MAAM,CAAC,QAAQ;YACzB,YAAY;YACZ,cAAc;SACf,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,KAAK,CAAC;IACtB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,WAAW,CAAC,MAAc,EAAE,WAAmB;QACnD,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;QAC3D,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;QACxD,CAAC;QAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,yBAAyB,WAAW,EAAE,CAAC,CAAC;QAC1D,CAAC;QAED,mBAAmB;QACnB,MAAM,CAAC,WAAW,GAAG,WAAW,CAAC;QAEjC,kEAAkE;QAClE,iGAAiG;QACjG,IAAI,UAAU,CAAC,cAAc,EAAE,CAAC;YAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC;YAC/D,IAAI,YAAY,EAAE,CAAC;gBACjB,4CAA4C;gBAC5C,MAAM,KAAK,GAAG,UAAU,CAAC,cAAc,CAAC;gBACxC,MAAM,KAAK,GAAG,YAAY,CAAC,QAAQ,CAAC;gBACpC,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,CAAC,GAAG,EAAE,CAAC;oBACvD,MAAM,CAAC,SAAS,CAAC,UAAU,CAAC,cAAc,EAAE,YAAY,CAAC,QAAQ,CAAC,CAAC;gBACrE,CAAC;YACH,CAAC;QACH,CAAC;QAED,mBAAmB;QACnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAAC;QACnE,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;IAC1D,CAAC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;QAC5C,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;QACnD,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAAC;QACxD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC5B,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,KAAK,CAAC,YAAY;QAChB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAC3C,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;QACpD,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;QACzD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC7B,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;QAEnB,gEAAgE;QAChE,IAAI,CAAC;YACH,IAAI,IAAI,CAAC,aAAa,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC/C,MAAM,IAAI,CAAC,aAAa,CAAC,YAAY,EAAE,CAAC;YAC1C,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,gBAAgB;QAClB,CAAC;QAED,qDAAqD;QACrD,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACnB,IAAI,CAAC,aAAa,CAAC,EAAE,GAAG,IAAI,CAAC;QAC/B,CAAC;QAED,sDAAsD;QACtD,iDAAiD;QACjD,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,oBAAoB,CAAC,EAAE,CAAC;YACzE,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC;YAChC,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;QAED,sBAAsB;QACtB,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACvB,IAAI,CAAC;gBACH,IAAI,CAAC,aAAa,CAAC,WAAW,EAAE,CAAC;YACnC,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,CAAC,KAAK,GAAG,oBAAoB,EAAE,CAAC;YACtE,IAAI,CAAC;gBACH,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,gBAAgB;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,aAAa,CAAC,WAAmB;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC;IACzC,CAAC;IAED;;OAEG;IACH,eAAe;QACb,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;IAED;;;;OAIG;IACH,gBAAgB;QACd,OAAO,IAAI,CAAC,aAAa,CAAC;IAC5B,CAAC;IAED;;;;;;;;;;OAUG;IACH,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC;QACzB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;CACF"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Pipeline - Stream-based media processing pipeline
3
+ *
4
+ * Provides a Node.js-style pipeline function for chaining media processing components.
5
+ * Automatically handles type conversions, buffering, and flushing.
6
+ *
7
+ * Supports two modes:
8
+ * 1. Simple: Single stream with variable parameters
9
+ * 2. Named: Multiple streams with named routing with variable parameters
10
+ *
11
+ * @module api/pipeline
12
+ */
13
+ import type { Frame, Packet } from '../lib/index.js';
14
+ import type { BitStreamFilterAPI } from './bitstream-filter.js';
15
+ import type { Decoder } from './decoder.js';
16
+ import type { Encoder } from './encoder.js';
17
+ import type { FilterAPI } from './filter.js';
18
+ import type { MediaInput } from './media-input.js';
19
+ import type { MediaOutput } from './media-output.js';
20
+ type StreamName = 'video' | 'audio';
21
+ type NamedInputs<K extends StreamName = StreamName> = Pick<Record<StreamName, MediaInput>, K>;
22
+ type NamedStages<K extends StreamName = StreamName> = Pick<Record<StreamName, (Decoder | FilterAPI | FilterAPI[] | Encoder | BitStreamFilterAPI | BitStreamFilterAPI[])[] | 'passthrough'>, K>;
23
+ type NamedOutputs<K extends StreamName = StreamName> = Pick<Record<StreamName, MediaOutput>, K>;
24
+ /**
25
+ * Pipeline control interface for managing pipeline execution
26
+ */
27
+ export interface PipelineControl {
28
+ /**
29
+ * Stop the pipeline gracefully
30
+ */
31
+ stop(): void;
32
+ /**
33
+ * Check if the pipeline has been stopped
34
+ */
35
+ isStopped(): boolean;
36
+ /**
37
+ * Promise that resolves when the pipeline completes
38
+ */
39
+ readonly completion: Promise<void>;
40
+ }
41
+ /**
42
+ * Full transcoding pipeline: input → decoder → encoder → output
43
+ */
44
+ export declare function pipeline(source: MediaInput, decoder: Decoder, encoder: Encoder, output: MediaOutput): PipelineControl;
45
+ /**
46
+ * Full transcoding pipeline with filter: input → decoder → filter → encoder → output
47
+ */
48
+ export declare function pipeline(source: MediaInput, decoder: Decoder, filter: FilterAPI | FilterAPI[], encoder: Encoder, output: MediaOutput): PipelineControl;
49
+ /**
50
+ * Transcoding with bitstream filter: input → decoder → encoder → bsf → output
51
+ */
52
+ export declare function pipeline(source: MediaInput, decoder: Decoder, encoder: Encoder, bsf: BitStreamFilterAPI | BitStreamFilterAPI[], output: MediaOutput): PipelineControl;
53
+ /**
54
+ * Full pipeline with filter and bsf: input → decoder → filter → encoder → bsf → output
55
+ */
56
+ export declare function pipeline(source: MediaInput, decoder: Decoder, filter: FilterAPI | FilterAPI[], encoder: Encoder, bsf: BitStreamFilterAPI | BitStreamFilterAPI[], output: MediaOutput): PipelineControl;
57
+ /**
58
+ * Decode + multiple filters + encode: input → decoder → filter1 → filter2 → encoder → output
59
+ */
60
+ export declare function pipeline(source: MediaInput, decoder: Decoder, filter1: FilterAPI, filter2: FilterAPI, encoder: Encoder, output: MediaOutput): PipelineControl;
61
+ /**
62
+ * Stream copy pipeline: input → output (copies all streams)
63
+ */
64
+ export declare function pipeline(source: MediaInput, output: MediaOutput): PipelineControl;
65
+ /**
66
+ * Stream copy with bitstream filter: input → bsf → output
67
+ */
68
+ export declare function pipeline(source: MediaInput, bsf: BitStreamFilterAPI | BitStreamFilterAPI[], output: MediaOutput): PipelineControl;
69
+ /**
70
+ * Filter + encode + output: frames → filter → encoder → output
71
+ */
72
+ export declare function pipeline(source: AsyncIterable<Frame>, filter: FilterAPI | FilterAPI[], encoder: Encoder, output: MediaOutput): PipelineControl;
73
+ /**
74
+ * Encode + output: frames → encoder → output
75
+ */
76
+ export declare function pipeline(source: AsyncIterable<Frame>, encoder: Encoder, output: MediaOutput): PipelineControl;
77
+ /**
78
+ * Partial pipeline: input → decoder (returns frames)
79
+ */
80
+ export declare function pipeline(source: MediaInput, decoder: Decoder): AsyncGenerator<Frame>;
81
+ /**
82
+ * Partial pipeline: input → decoder → filter (returns frames)
83
+ */
84
+ export declare function pipeline(source: MediaInput, decoder: Decoder, filter: FilterAPI | FilterAPI[]): AsyncGenerator<Frame>;
85
+ /**
86
+ * Partial pipeline: input → decoder → filter → encoder (returns packets)
87
+ */
88
+ export declare function pipeline(source: MediaInput, decoder: Decoder, filter: FilterAPI | FilterAPI[], encoder: Encoder): AsyncGenerator<Packet>;
89
+ /**
90
+ * Partial pipeline: input → decoder → encoder (returns packets)
91
+ */
92
+ export declare function pipeline(source: MediaInput, decoder: Decoder, encoder: Encoder): AsyncGenerator<Packet>;
93
+ /**
94
+ * Partial pipeline: frames → filter (returns frames)
95
+ */
96
+ export declare function pipeline(source: AsyncIterable<Frame>, filter: FilterAPI | FilterAPI[]): AsyncGenerator<Frame>;
97
+ /**
98
+ * Partial pipeline: frames → encoder (returns packets)
99
+ */
100
+ export declare function pipeline(source: AsyncIterable<Frame>, encoder: Encoder): AsyncGenerator<Packet>;
101
+ /**
102
+ * Partial pipeline: frames → filter → encoder (returns packets)
103
+ */
104
+ export declare function pipeline(source: AsyncIterable<Frame>, filter: FilterAPI | FilterAPI[], encoder: Encoder): AsyncGenerator<Packet>;
105
+ /**
106
+ * Named pipeline with single output - all streams go to the same output
107
+ */
108
+ export declare function pipeline<K extends StreamName>(inputs: NamedInputs<K>, stages: NamedStages<K>, output: MediaOutput): PipelineControl;
109
+ /**
110
+ * Named pipeline with multiple outputs - each stream has its own output
111
+ */
112
+ export declare function pipeline<K extends StreamName>(inputs: NamedInputs<K>, stages: NamedStages<K>, outputs: NamedOutputs<K>): PipelineControl;
113
+ /**
114
+ * Partial named pipeline (returns generators for further processing)
115
+ */
116
+ export declare function pipeline<K extends StreamName, T extends Packet | Frame = Packet | Frame>(inputs: NamedInputs<K>, stages: NamedStages<K>): Record<K, AsyncGenerator<T>>;
117
+ export {};