node-av 3.1.3 → 5.0.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.
Files changed (192) hide show
  1. package/README.md +88 -52
  2. package/binding.gyp +23 -11
  3. package/dist/api/audio-frame-buffer.d.ts +201 -0
  4. package/dist/api/audio-frame-buffer.js +275 -0
  5. package/dist/api/audio-frame-buffer.js.map +1 -0
  6. package/dist/api/bitstream-filter.d.ts +320 -78
  7. package/dist/api/bitstream-filter.js +684 -151
  8. package/dist/api/bitstream-filter.js.map +1 -1
  9. package/dist/api/constants.d.ts +44 -0
  10. package/dist/api/constants.js +45 -0
  11. package/dist/api/constants.js.map +1 -0
  12. package/dist/api/data/test_av1.ivf +0 -0
  13. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  14. package/dist/api/data/test_vp8.ivf +0 -0
  15. package/dist/api/data/test_vp9.ivf +0 -0
  16. package/dist/api/decoder.d.ts +454 -77
  17. package/dist/api/decoder.js +1081 -271
  18. package/dist/api/decoder.js.map +1 -1
  19. package/dist/api/{media-input.d.ts → demuxer.d.ts} +295 -45
  20. package/dist/api/demuxer.js +1965 -0
  21. package/dist/api/demuxer.js.map +1 -0
  22. package/dist/api/encoder.d.ts +423 -132
  23. package/dist/api/encoder.js +1089 -240
  24. package/dist/api/encoder.js.map +1 -1
  25. package/dist/api/filter-complex.d.ts +769 -0
  26. package/dist/api/filter-complex.js +1596 -0
  27. package/dist/api/filter-complex.js.map +1 -0
  28. package/dist/api/filter-presets.d.ts +80 -5
  29. package/dist/api/filter-presets.js +117 -7
  30. package/dist/api/filter-presets.js.map +1 -1
  31. package/dist/api/filter.d.ts +561 -125
  32. package/dist/api/filter.js +1083 -274
  33. package/dist/api/filter.js.map +1 -1
  34. package/dist/api/{fmp4.d.ts → fmp4-stream.d.ts} +141 -140
  35. package/dist/api/fmp4-stream.js +539 -0
  36. package/dist/api/fmp4-stream.js.map +1 -0
  37. package/dist/api/hardware.d.ts +58 -6
  38. package/dist/api/hardware.js +127 -11
  39. package/dist/api/hardware.js.map +1 -1
  40. package/dist/api/index.d.ts +8 -4
  41. package/dist/api/index.js +17 -8
  42. package/dist/api/index.js.map +1 -1
  43. package/dist/api/io-stream.d.ts +6 -6
  44. package/dist/api/io-stream.js +5 -4
  45. package/dist/api/io-stream.js.map +1 -1
  46. package/dist/api/{media-output.d.ts → muxer.d.ts} +280 -66
  47. package/dist/api/muxer.js +1934 -0
  48. package/dist/api/muxer.js.map +1 -0
  49. package/dist/api/pipeline.d.ts +77 -29
  50. package/dist/api/pipeline.js +449 -439
  51. package/dist/api/pipeline.js.map +1 -1
  52. package/dist/api/rtp-stream.d.ts +312 -0
  53. package/dist/api/rtp-stream.js +630 -0
  54. package/dist/api/rtp-stream.js.map +1 -0
  55. package/dist/api/types.d.ts +533 -56
  56. package/dist/api/utilities/async-queue.d.ts +91 -0
  57. package/dist/api/utilities/async-queue.js +162 -0
  58. package/dist/api/utilities/async-queue.js.map +1 -0
  59. package/dist/api/utilities/audio-sample.d.ts +11 -1
  60. package/dist/api/utilities/audio-sample.js +10 -0
  61. package/dist/api/utilities/audio-sample.js.map +1 -1
  62. package/dist/api/utilities/channel-layout.d.ts +1 -0
  63. package/dist/api/utilities/channel-layout.js +1 -0
  64. package/dist/api/utilities/channel-layout.js.map +1 -1
  65. package/dist/api/utilities/image.d.ts +39 -1
  66. package/dist/api/utilities/image.js +38 -0
  67. package/dist/api/utilities/image.js.map +1 -1
  68. package/dist/api/utilities/index.d.ts +3 -0
  69. package/dist/api/utilities/index.js +6 -0
  70. package/dist/api/utilities/index.js.map +1 -1
  71. package/dist/api/utilities/media-type.d.ts +2 -1
  72. package/dist/api/utilities/media-type.js +1 -0
  73. package/dist/api/utilities/media-type.js.map +1 -1
  74. package/dist/api/utilities/pixel-format.d.ts +4 -1
  75. package/dist/api/utilities/pixel-format.js +3 -0
  76. package/dist/api/utilities/pixel-format.js.map +1 -1
  77. package/dist/api/utilities/sample-format.d.ts +6 -1
  78. package/dist/api/utilities/sample-format.js +5 -0
  79. package/dist/api/utilities/sample-format.js.map +1 -1
  80. package/dist/api/utilities/scheduler.d.ts +138 -0
  81. package/dist/api/utilities/scheduler.js +98 -0
  82. package/dist/api/utilities/scheduler.js.map +1 -0
  83. package/dist/api/utilities/streaming.d.ts +105 -15
  84. package/dist/api/utilities/streaming.js +201 -12
  85. package/dist/api/utilities/streaming.js.map +1 -1
  86. package/dist/api/utilities/timestamp.d.ts +15 -1
  87. package/dist/api/utilities/timestamp.js +14 -0
  88. package/dist/api/utilities/timestamp.js.map +1 -1
  89. package/dist/api/utilities/whisper-model.d.ts +310 -0
  90. package/dist/api/utilities/whisper-model.js +528 -0
  91. package/dist/api/utilities/whisper-model.js.map +1 -0
  92. package/dist/api/webrtc-stream.d.ts +288 -0
  93. package/dist/api/webrtc-stream.js +440 -0
  94. package/dist/api/webrtc-stream.js.map +1 -0
  95. package/dist/api/whisper.d.ts +324 -0
  96. package/dist/api/whisper.js +362 -0
  97. package/dist/api/whisper.js.map +1 -0
  98. package/dist/constants/constants.d.ts +54 -2
  99. package/dist/constants/constants.js +48 -1
  100. package/dist/constants/constants.js.map +1 -1
  101. package/dist/constants/encoders.d.ts +2 -1
  102. package/dist/constants/encoders.js +4 -3
  103. package/dist/constants/encoders.js.map +1 -1
  104. package/dist/constants/hardware.d.ts +26 -0
  105. package/dist/constants/hardware.js +27 -0
  106. package/dist/constants/hardware.js.map +1 -0
  107. package/dist/constants/index.d.ts +1 -0
  108. package/dist/constants/index.js +1 -0
  109. package/dist/constants/index.js.map +1 -1
  110. package/dist/ffmpeg/index.d.ts +3 -3
  111. package/dist/ffmpeg/index.js +3 -3
  112. package/dist/ffmpeg/utils.d.ts +27 -0
  113. package/dist/ffmpeg/utils.js +28 -16
  114. package/dist/ffmpeg/utils.js.map +1 -1
  115. package/dist/lib/binding.d.ts +22 -11
  116. package/dist/lib/binding.js.map +1 -1
  117. package/dist/lib/codec-context.d.ts +87 -0
  118. package/dist/lib/codec-context.js +125 -4
  119. package/dist/lib/codec-context.js.map +1 -1
  120. package/dist/lib/codec-parameters.d.ts +229 -1
  121. package/dist/lib/codec-parameters.js +264 -0
  122. package/dist/lib/codec-parameters.js.map +1 -1
  123. package/dist/lib/codec-parser.d.ts +23 -0
  124. package/dist/lib/codec-parser.js +25 -0
  125. package/dist/lib/codec-parser.js.map +1 -1
  126. package/dist/lib/codec.d.ts +26 -4
  127. package/dist/lib/codec.js +35 -0
  128. package/dist/lib/codec.js.map +1 -1
  129. package/dist/lib/dictionary.js +1 -0
  130. package/dist/lib/dictionary.js.map +1 -1
  131. package/dist/lib/error.js +1 -1
  132. package/dist/lib/error.js.map +1 -1
  133. package/dist/lib/fifo.d.ts +416 -0
  134. package/dist/lib/fifo.js +453 -0
  135. package/dist/lib/fifo.js.map +1 -0
  136. package/dist/lib/filter-context.d.ts +52 -11
  137. package/dist/lib/filter-context.js +56 -12
  138. package/dist/lib/filter-context.js.map +1 -1
  139. package/dist/lib/filter-graph.d.ts +9 -0
  140. package/dist/lib/filter-graph.js +13 -0
  141. package/dist/lib/filter-graph.js.map +1 -1
  142. package/dist/lib/filter.d.ts +21 -0
  143. package/dist/lib/filter.js +28 -0
  144. package/dist/lib/filter.js.map +1 -1
  145. package/dist/lib/format-context.d.ts +48 -14
  146. package/dist/lib/format-context.js +76 -7
  147. package/dist/lib/format-context.js.map +1 -1
  148. package/dist/lib/frame.d.ts +264 -1
  149. package/dist/lib/frame.js +351 -1
  150. package/dist/lib/frame.js.map +1 -1
  151. package/dist/lib/hardware-device-context.d.ts +3 -2
  152. package/dist/lib/hardware-device-context.js.map +1 -1
  153. package/dist/lib/index.d.ts +2 -0
  154. package/dist/lib/index.js +4 -0
  155. package/dist/lib/index.js.map +1 -1
  156. package/dist/lib/input-format.d.ts +21 -0
  157. package/dist/lib/input-format.js +42 -2
  158. package/dist/lib/input-format.js.map +1 -1
  159. package/dist/lib/native-types.d.ts +76 -27
  160. package/dist/lib/option.d.ts +25 -13
  161. package/dist/lib/option.js +28 -0
  162. package/dist/lib/option.js.map +1 -1
  163. package/dist/lib/output-format.d.ts +22 -1
  164. package/dist/lib/output-format.js +28 -0
  165. package/dist/lib/output-format.js.map +1 -1
  166. package/dist/lib/packet.d.ts +35 -0
  167. package/dist/lib/packet.js +52 -2
  168. package/dist/lib/packet.js.map +1 -1
  169. package/dist/lib/rational.d.ts +18 -0
  170. package/dist/lib/rational.js +19 -0
  171. package/dist/lib/rational.js.map +1 -1
  172. package/dist/lib/stream.d.ts +126 -0
  173. package/dist/lib/stream.js +188 -5
  174. package/dist/lib/stream.js.map +1 -1
  175. package/dist/lib/sync-queue.d.ts +179 -0
  176. package/dist/lib/sync-queue.js +197 -0
  177. package/dist/lib/sync-queue.js.map +1 -0
  178. package/dist/lib/types.d.ts +49 -1
  179. package/dist/lib/utilities.d.ts +281 -53
  180. package/dist/lib/utilities.js +298 -55
  181. package/dist/lib/utilities.js.map +1 -1
  182. package/install/check.js +2 -2
  183. package/package.json +37 -26
  184. package/dist/api/fmp4.js +0 -710
  185. package/dist/api/fmp4.js.map +0 -1
  186. package/dist/api/media-input.js +0 -1075
  187. package/dist/api/media-input.js.map +0 -1
  188. package/dist/api/media-output.js +0 -1040
  189. package/dist/api/media-output.js.map +0 -1
  190. package/dist/api/webrtc.d.ts +0 -664
  191. package/dist/api/webrtc.js +0 -1132
  192. package/dist/api/webrtc.js.map +0 -1
@@ -1,7 +1,10 @@
1
- import { Codec, CodecContext, Packet } from '../lib/index.js';
2
- import type { AVCodecFlag, AVCodecID } from '../constants/constants.js';
3
- import type { FFEncoderCodec } from '../constants/encoders.js';
4
- import type { Frame } from '../lib/index.js';
1
+ import { CodecContext } from '../lib/codec-context.js';
2
+ import { Codec } from '../lib/codec.js';
3
+ import { Frame } from '../lib/frame.js';
4
+ import { Packet } from '../lib/packet.js';
5
+ import { SchedulerControl } from './utilities/scheduler.js';
6
+ import type { AVCodecFlag, AVCodecID, EOFSignal, FFEncoderCodec } from '../constants/index.js';
7
+ import type { Muxer } from './muxer.js';
5
8
  import type { EncoderOptions } from './types.js';
6
9
  /**
7
10
  * High-level encoder for audio and video streams.
@@ -58,17 +61,23 @@ import type { EncoderOptions } from './types.js';
58
61
  * ```
59
62
  *
60
63
  * @see {@link Decoder} For decoding packets to frames
61
- * @see {@link MediaOutput} For writing encoded packets
64
+ * @see {@link Muxer} For writing encoded packets
62
65
  * @see {@link HardwareContext} For GPU acceleration
63
66
  */
64
67
  export declare class Encoder implements Disposable {
65
68
  private codecContext;
66
69
  private packet;
67
70
  private codec;
71
+ private initializePromise;
68
72
  private initialized;
69
73
  private isClosed;
70
74
  private opts?;
71
75
  private options;
76
+ private audioFrameBuffer?;
77
+ private inputQueue;
78
+ private outputQueue;
79
+ private workerPromise;
80
+ private pipeToPromise;
72
81
  /**
73
82
  * @param codecContext - Configured codec context
74
83
  *
@@ -92,7 +101,7 @@ export declare class Encoder implements Disposable {
92
101
  *
93
102
  * @param encoderCodec - Codec name, ID, or instance to use for encoding
94
103
  *
95
- * @param options - Encoder configuration options including required timeBase
104
+ * @param options - Optional encoder configuration options including required timeBase
96
105
  *
97
106
  * @returns Configured encoder instance
98
107
  *
@@ -133,8 +142,9 @@ export declare class Encoder implements Disposable {
133
142
  * ```
134
143
  *
135
144
  * @see {@link EncoderOptions} For configuration options
145
+ * @see {@link createSync} For synchronous version
136
146
  */
137
- static create(encoderCodec: FFEncoderCodec | AVCodecID | Codec, options: EncoderOptions): Promise<Encoder>;
147
+ static create(encoderCodec: FFEncoderCodec | AVCodecID | Codec, options?: EncoderOptions): Promise<Encoder>;
138
148
  /**
139
149
  * Create an encoder with specified codec and options synchronously.
140
150
  * Synchronous version of create.
@@ -147,7 +157,7 @@ export declare class Encoder implements Disposable {
147
157
  *
148
158
  * @param encoderCodec - Codec name, ID, or instance to use for encoding
149
159
  *
150
- * @param options - Encoder configuration options including required timeBase
160
+ * @param options - Optional encoder configuration options including required timeBase
151
161
  *
152
162
  * @returns Configured encoder instance
153
163
  *
@@ -189,9 +199,10 @@ export declare class Encoder implements Disposable {
189
199
  * });
190
200
  * ```
191
201
  *
202
+ * @see {@link EncoderOptions} For configuration options
192
203
  * @see {@link create} For async version
193
204
  */
194
- static createSync(encoderCodec: FFEncoderCodec | AVCodecID | Codec, options: EncoderOptions): Encoder;
205
+ static createSync(encoderCodec: FFEncoderCodec | AVCodecID | Codec, options?: EncoderOptions): Encoder;
195
206
  /**
196
207
  * Check if encoder is open.
197
208
  *
@@ -219,6 +230,89 @@ export declare class Encoder implements Disposable {
219
230
  * ```
220
231
  */
221
232
  get isEncoderInitialized(): boolean;
233
+ /**
234
+ * Codec flags.
235
+ *
236
+ * @returns Current codec flags
237
+ *
238
+ * @throws {Error} If encoder is closed
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * const flags = encoder.codecFlags;
243
+ * console.log('Current flags:', flags);
244
+ * ```
245
+ *
246
+ * @see {@link setCodecFlags} To set flags
247
+ * @see {@link clearCodecFlags} To clear flags
248
+ * @see {@link hasCodecFlags} To check flags
249
+ */
250
+ get codecFlags(): AVCodecFlag;
251
+ /**
252
+ * Set codec flags.
253
+ *
254
+ * @param flags - One or more flag values to set
255
+ *
256
+ * @throws {Error} If encoder is already initialized or closed
257
+ *
258
+ * @example
259
+ * ```typescript
260
+ * import { AV_CODEC_FLAG_GLOBAL_HEADER, AV_CODEC_FLAG_QSCALE } from 'node-av/constants';
261
+ *
262
+ * // Set multiple flags before initialization
263
+ * encoder.setCodecFlags(AV_CODEC_FLAG_GLOBAL_HEADER, AV_CODEC_FLAG_QSCALE);
264
+ * ```
265
+ *
266
+ * @see {@link clearCodecFlags} To clear flags
267
+ * @see {@link hasCodecFlags} To check flags
268
+ * @see {@link codecFlags} For direct flag access
269
+ */
270
+ setCodecFlags(...flags: AVCodecFlag[]): void;
271
+ /**
272
+ * Clear codec flags.
273
+ *
274
+ * @param flags - One or more flag values to clear
275
+ *
276
+ * @throws {Error} If encoder is already initialized or closed
277
+ *
278
+ * @example
279
+ * ```typescript
280
+ * import { AV_CODEC_FLAG_QSCALE } from 'node-av/constants';
281
+ *
282
+ * // Clear specific flag before initialization
283
+ * encoder.clearCodecFlags(AV_CODEC_FLAG_QSCALE);
284
+ * ```
285
+ *
286
+ * @see {@link setCodecFlags} To set flags
287
+ * @see {@link hasCodecFlags} To check flags
288
+ * @see {@link codecFlags} For direct flag access
289
+ */
290
+ clearCodecFlags(...flags: AVCodecFlag[]): void;
291
+ /**
292
+ * Check if codec has specific flags.
293
+ *
294
+ * Tests whether all specified codec flags are set using bitwise AND.
295
+ *
296
+ * @param flags - One or more flag values to check
297
+ *
298
+ * @returns true if all specified flags are set, false otherwise
299
+ *
300
+ * @throws {Error} If encoder is closed
301
+ *
302
+ * @example
303
+ * ```typescript
304
+ * import { AV_CODEC_FLAG_GLOBAL_HEADER } from 'node-av/constants';
305
+ *
306
+ * if (encoder.hasCodecFlags(AV_CODEC_FLAG_GLOBAL_HEADER)) {
307
+ * console.log('Global header flag is set');
308
+ * }
309
+ * ```
310
+ *
311
+ * @see {@link setCodecFlags} To set flags
312
+ * @see {@link clearCodecFlags} To clear flags
313
+ * @see {@link codecFlags} For direct flag access
314
+ */
315
+ hasCodecFlags(...flags: AVCodecFlag[]): boolean;
222
316
  /**
223
317
  * Check if encoder uses hardware acceleration.
224
318
  *
@@ -248,24 +342,119 @@ export declare class Encoder implements Disposable {
248
342
  */
249
343
  isReady(): boolean;
250
344
  /**
251
- * Encode a frame to a packet.
345
+ * Send a frame to the encoder.
346
+ *
347
+ * Sends a raw frame to the encoder for encoding.
348
+ * Does not return encoded packets - use {@link receive} to retrieve packets.
349
+ * On first frame, automatically initializes encoder with frame properties.
350
+ * A single frame can produce zero, one, or multiple packets depending on codec buffering.
351
+ *
352
+ * **Important**: This method only SENDS the frame to the encoder.
353
+ * You must call {@link receive} separately (potentially multiple times) to get encoded packets.
354
+ *
355
+ * Direct mapping to avcodec_send_frame().
356
+ *
357
+ * @param frame - Raw frame to send to encoder
358
+ *
359
+ * @throws {FFmpegError} If sending frame fails
360
+ *
361
+ * @example
362
+ * ```typescript
363
+ * // Send frame and receive packets
364
+ * await encoder.encode(frame);
365
+ *
366
+ * // Receive all available packets
367
+ * while (true) {
368
+ * const packet = await encoder.receive();
369
+ * if (!packet) break;
370
+ * console.log(`Encoded packet with PTS: ${packet.pts}`);
371
+ * await output.writePacket(packet);
372
+ * packet.free();
373
+ * }
374
+ * ```
375
+ *
376
+ * @example
377
+ * ```typescript
378
+ * for await (const frame of decoder.frames(input.packets())) {
379
+ * // Send frame
380
+ * await encoder.encode(frame);
381
+ *
382
+ * // Receive available packets
383
+ * let packet;
384
+ * while ((packet = await encoder.receive())) {
385
+ * await output.writePacket(packet);
386
+ * packet.free();
387
+ * }
388
+ * frame.free();
389
+ * }
390
+ * ```
391
+ *
392
+ * @see {@link receive} For receiving encoded packets
393
+ * @see {@link encodeAll} For combined send+receive operation
394
+ * @see {@link packets} For automatic frame iteration
395
+ * @see {@link flush} For end-of-stream handling
396
+ * @see {@link encodeSync} For synchronous version
397
+ */
398
+ encode(frame: Frame): Promise<void>;
399
+ /**
400
+ * Send a frame to the encoder synchronously.
401
+ * Synchronous version of encode.
402
+ *
403
+ * Sends a raw frame to the encoder for encoding.
404
+ * Does not return encoded packets - use {@link receiveSync} to retrieve packets.
405
+ * On first frame, automatically initializes encoder with frame properties.
406
+ * A single frame can produce zero, one, or multiple packets depending on codec buffering.
407
+ *
408
+ * **Important**: This method only SENDS the frame to the encoder.
409
+ * You must call {@link receiveSync} separately (potentially multiple times) to get encoded packets.
410
+ *
411
+ * Direct mapping to avcodec_send_frame().
412
+ *
413
+ * @param frame - Raw frame to send to encoder
414
+ *
415
+ * @throws {FFmpegError} If sending frame fails
416
+ *
417
+ * @example
418
+ * ```typescript
419
+ * // Send frame and receive packets
420
+ * encoder.encodeSync(frame);
421
+ *
422
+ * // Receive all available packets
423
+ * let packet;
424
+ * while ((packet = encoder.receiveSync())) {
425
+ * console.log(`Encoded packet with PTS: ${packet.pts}`);
426
+ * output.writePacketSync(packet);
427
+ * packet.free();
428
+ * }
429
+ * ```
430
+ *
431
+ * @see {@link receiveSync} For receiving encoded packets
432
+ * @see {@link encodeAllSync} For combined send+receive operation
433
+ * @see {@link packetsSync} For automatic frame iteration
434
+ * @see {@link flushSync} For end-of-stream handling
435
+ * @see {@link encode} For async version
436
+ */
437
+ encodeSync(frame: Frame): void;
438
+ /**
439
+ * Encode a frame to packets.
252
440
  *
253
- * Sends a frame to the encoder and attempts to receive an encoded packet.
441
+ * Sends a frame to the encoder and receives all available encoded packets.
442
+ * Returns array of packets - may be empty if encoder needs more data.
254
443
  * On first frame, automatically initializes encoder with frame properties.
255
- * Handles internal buffering - may return null if more frames needed.
444
+ * One frame can produce zero, one, or multiple packets depending on codec.
256
445
  *
257
446
  * Direct mapping to avcodec_send_frame() and avcodec_receive_packet().
258
447
  *
259
448
  * @param frame - Raw frame to encode (or null to flush)
260
449
  *
261
- * @returns Encoded packet, null if more data needed, or null if encoder is closed
450
+ * @returns Array of encoded packets (empty if more data needed or encoder is closed)
262
451
  *
263
452
  * @throws {FFmpegError} If encoding fails
264
453
  *
265
454
  * @example
266
455
  * ```typescript
267
- * const packet = await encoder.encode(frame);
268
- * if (packet) {
456
+ * const packets = await encoder.encodeAll(frame);
457
+ * for (const packet of packets) {
269
458
  * console.log(`Encoded packet with PTS: ${packet.pts}`);
270
459
  * await output.writePacket(packet);
271
460
  * packet.free();
@@ -276,8 +465,8 @@ export declare class Encoder implements Disposable {
276
465
  * ```typescript
277
466
  * // Encode loop
278
467
  * for await (const frame of decoder.frames(input.packets())) {
279
- * const packet = await encoder.encode(frame);
280
- * if (packet) {
468
+ * const packets = await encoder.encodeAll(frame);
469
+ * for (const packet of packets) {
281
470
  * await output.writePacket(packet);
282
471
  * packet.free();
283
472
  * }
@@ -285,30 +474,33 @@ export declare class Encoder implements Disposable {
285
474
  * }
286
475
  * ```
287
476
  *
477
+ * @see {@link encode} For single packet encoding
288
478
  * @see {@link packets} For automatic frame iteration
289
479
  * @see {@link flush} For end-of-stream handling
480
+ * @see {@link encodeAllSync} For synchronous version
290
481
  */
291
- encode(frame: Frame | null): Promise<Packet | null>;
482
+ encodeAll(frame: Frame | null): Promise<Packet[]>;
292
483
  /**
293
- * Encode a frame to a packet synchronously.
294
- * Synchronous version of encode.
484
+ * Encode a frame to packets synchronously.
485
+ * Synchronous version of encodeAll.
295
486
  *
296
- * Sends a frame to the encoder and attempts to receive an encoded packet.
487
+ * Sends a frame to the encoder and receives all available encoded packets.
488
+ * Returns array of packets - may be empty if encoder needs more data.
297
489
  * On first frame, automatically initializes encoder with frame properties.
298
- * Handles internal buffering - may return null if more frames needed.
490
+ * One frame can produce zero, one, or multiple packets depending on codec.
299
491
  *
300
492
  * Direct mapping to avcodec_send_frame() and avcodec_receive_packet().
301
493
  *
302
494
  * @param frame - Raw frame to encode (or null to flush)
303
495
  *
304
- * @returns Encoded packet, null if more data needed, or null if encoder is closed
496
+ * @returns Array of encoded packets (empty if more data needed or encoder is closed)
305
497
  *
306
498
  * @throws {FFmpegError} If encoding fails
307
499
  *
308
500
  * @example
309
501
  * ```typescript
310
- * const packet = encoder.encodeSync(frame);
311
- * if (packet) {
502
+ * const packets = encoder.encodeAllSync(frame);
503
+ * for (const packet of packets) {
312
504
  * console.log(`Encoded packet with PTS: ${packet.pts}`);
313
505
  * output.writePacketSync(packet);
314
506
  * packet.free();
@@ -319,8 +511,8 @@ export declare class Encoder implements Disposable {
319
511
  * ```typescript
320
512
  * // Encode loop
321
513
  * for (const frame of decoder.framesSync(packets)) {
322
- * const packet = encoder.encodeSync(frame);
323
- * if (packet) {
514
+ * const packets = encoder.encodeAllSync(frame);
515
+ * for (const packet of packets) {
324
516
  * output.writePacketSync(packet);
325
517
  * packet.free();
326
518
  * }
@@ -328,27 +520,38 @@ export declare class Encoder implements Disposable {
328
520
  * }
329
521
  * ```
330
522
  *
331
- * @see {@link encode} For async version
523
+ * @see {@link encodeSync} For single packet encoding
524
+ * @see {@link packetsSync} For automatic frame iteration
525
+ * @see {@link flushSync} For end-of-stream handling
526
+ * @see {@link encodeAll} For async version
332
527
  */
333
- encodeSync(frame: Frame | null): Packet | null;
528
+ encodeAllSync(frame: Frame | null): Packet[];
334
529
  /**
335
530
  * Encode frame stream to packet stream.
336
531
  *
337
532
  * High-level async generator for complete encoding pipeline.
338
- * Automatically manages frame memory, encoder state,
339
- * and flushes buffered packets at end.
533
+ * Encoder is only flushed when EOF (null) signal is explicitly received.
340
534
  * Primary interface for stream-based encoding.
341
535
  *
342
- * @param frames - Async iterable of frames (freed automatically)
536
+ * **EOF Handling:**
537
+ * - Send null to flush encoder and get remaining buffered packets
538
+ * - Generator yields null after flushing when null is received
539
+ * - No automatic flushing - encoder stays open until EOF or close()
540
+ *
541
+ * @param frames - Async iterable of frames, single frame, or null to flush
343
542
  *
344
- * @yields {Packet} Encoded packets (caller must free)
543
+ * @yields {Packet | null} Encoded packets, followed by null when explicitly flushed
345
544
  *
346
545
  * @throws {FFmpegError} If encoding fails
347
546
  *
348
547
  * @example
349
548
  * ```typescript
350
- * // Basic encoding pipeline
549
+ * // Stream of frames with automatic EOF propagation
351
550
  * for await (const packet of encoder.packets(decoder.frames(input.packets()))) {
551
+ * if (packet === null) {
552
+ * console.log('Encoder flushed');
553
+ * break;
554
+ * }
352
555
  * await output.writePacket(packet);
353
556
  * packet.free(); // Must free output packets
354
557
  * }
@@ -356,60 +559,60 @@ export declare class Encoder implements Disposable {
356
559
  *
357
560
  * @example
358
561
  * ```typescript
359
- * // With frame filtering
360
- * async function* filteredFrames() {
361
- * for await (const frame of decoder.frames(input.packets())) {
362
- * const filtered = await filter.process(frame);
363
- * if (filtered) {
364
- * yield filtered;
365
- * }
366
- * frame.free();
367
- * }
368
- * }
369
- *
370
- * for await (const packet of encoder.packets(filteredFrames())) {
562
+ * // Single frame - no automatic flush
563
+ * for await (const packet of encoder.packets(singleFrame)) {
371
564
  * await output.writePacket(packet);
372
565
  * packet.free();
373
566
  * }
567
+ * // Encoder remains open, buffered packets not flushed
374
568
  * ```
375
569
  *
376
570
  * @example
377
571
  * ```typescript
378
- * // Pipeline integration
379
- * import { pipeline } from 'node-av/api';
380
- *
381
- * const control = pipeline(
382
- * input,
383
- * decoder,
384
- * encoder,
385
- * output
386
- * );
387
- * await control.completion;
572
+ * // Explicit flush with EOF
573
+ * for await (const packet of encoder.packets(null)) {
574
+ * if (packet === null) {
575
+ * console.log('All buffered packets flushed');
576
+ * break;
577
+ * }
578
+ * console.log('Buffered packet:', packet.pts);
579
+ * await output.writePacket(packet);
580
+ * packet.free();
581
+ * }
388
582
  * ```
389
583
  *
390
584
  * @see {@link encode} For single frame encoding
391
585
  * @see {@link Decoder.frames} For frame source
586
+ * @see {@link packetsSync} For sync version
392
587
  */
393
- packets(frames: AsyncIterable<Frame>): AsyncGenerator<Packet>;
588
+ packets(frames: AsyncIterable<Frame | null> | Frame | null): AsyncGenerator<Packet | null>;
394
589
  /**
395
590
  * Encode frame stream to packet stream synchronously.
396
591
  * Synchronous version of packets.
397
592
  *
398
593
  * High-level sync generator for complete encoding pipeline.
399
- * Automatically manages frame memory, encoder state,
400
- * and flushes buffered packets at end.
594
+ * Encoder is only flushed when EOF (null) signal is explicitly received.
401
595
  * Primary interface for stream-based encoding.
402
596
  *
403
- * @param frames - Iterable of frames (freed automatically)
597
+ * **EOF Handling:**
598
+ * - Send null to flush encoder and get remaining buffered packets
599
+ * - Generator yields null after flushing when null is received
600
+ * - No automatic flushing - encoder stays open until EOF or close()
601
+ *
602
+ * @param frames - Iterable of frames, single frame, or null to flush
404
603
  *
405
- * @yields {Packet} Encoded packets (caller must free)
604
+ * @yields {Packet | null} Encoded packets, followed by null when explicitly flushed
406
605
  *
407
606
  * @throws {FFmpegError} If encoding fails
408
607
  *
409
608
  * @example
410
609
  * ```typescript
411
- * // Basic encoding pipeline
610
+ * // Stream of frames with automatic EOF propagation
412
611
  * for (const packet of encoder.packetsSync(decoder.framesSync(packets))) {
612
+ * if (packet === null) {
613
+ * console.log('Encoder flushed');
614
+ * break;
615
+ * }
413
616
  * output.writePacketSync(packet);
414
617
  * packet.free(); // Must free output packets
415
618
  * }
@@ -417,26 +620,33 @@ export declare class Encoder implements Disposable {
417
620
  *
418
621
  * @example
419
622
  * ```typescript
420
- * // With frame filtering
421
- * function* filteredFrames() {
422
- * for (const frame of decoder.framesSync(packets)) {
423
- * const filtered = filter.processSync(frame);
424
- * if (filtered) {
425
- * yield filtered;
426
- * }
427
- * frame.free();
428
- * }
623
+ * // Single frame - no automatic flush
624
+ * for (const packet of encoder.packetsSync(singleFrame)) {
625
+ * output.writePacketSync(packet);
626
+ * packet.free();
429
627
  * }
628
+ * // Encoder remains open, buffered packets not flushed
629
+ * ```
430
630
  *
431
- * for (const packet of encoder.packetsSync(filteredFrames())) {
631
+ * @example
632
+ * ```typescript
633
+ * // Explicit flush with EOF
634
+ * for (const packet of encoder.packetsSync(null)) {
635
+ * if (packet === null) {
636
+ * console.log('All buffered packets flushed');
637
+ * break;
638
+ * }
639
+ * console.log('Buffered packet:', packet.pts);
432
640
  * output.writePacketSync(packet);
433
641
  * packet.free();
434
642
  * }
435
643
  * ```
436
644
  *
645
+ * @see {@link encodeSync} For single frame encoding
646
+ * @see {@link Decoder.framesSync} For frame source
437
647
  * @see {@link packets} For async version
438
648
  */
439
- packetsSync(frames: Iterable<Frame>): Generator<Packet>;
649
+ packetsSync(frames: Iterable<Frame | null> | Frame | null): Generator<Packet | null>;
440
650
  /**
441
651
  * Flush encoder and signal end-of-stream.
442
652
  *
@@ -462,6 +672,7 @@ export declare class Encoder implements Disposable {
462
672
  *
463
673
  * @see {@link flushPackets} For async iteration
464
674
  * @see {@link receive} For getting buffered packets
675
+ * @see {@link flushSync} For synchronous version
465
676
  */
466
677
  flush(): Promise<void>;
467
678
  /**
@@ -488,6 +699,8 @@ export declare class Encoder implements Disposable {
488
699
  * }
489
700
  * ```
490
701
  *
702
+ * @see {@link flushPacketsSync} For sync iteration
703
+ * @see {@link receiveSync} For getting buffered packets
491
704
  * @see {@link flush} For async version
492
705
  */
493
706
  flushSync(): void;
@@ -510,8 +723,9 @@ export declare class Encoder implements Disposable {
510
723
  * }
511
724
  * ```
512
725
  *
726
+ * @see {@link encode} For sending frames and receiving packets
513
727
  * @see {@link flush} For signaling end-of-stream
514
- * @see {@link packets} For complete pipeline
728
+ * @see {@link flushPacketsSync} For synchronous version
515
729
  */
516
730
  flushPackets(): AsyncGenerator<Packet>;
517
731
  /**
@@ -534,6 +748,8 @@ export declare class Encoder implements Disposable {
534
748
  * }
535
749
  * ```
536
750
  *
751
+ * @see {@link encodeSync} For sending frames and receiving packets
752
+ * @see {@link flushSync} For signaling end-of-stream
537
753
  * @see {@link flushPackets} For async version
538
754
  */
539
755
  flushPacketsSync(): Generator<Packet>;
@@ -542,19 +758,25 @@ export declare class Encoder implements Disposable {
542
758
  *
543
759
  * Gets encoded packets from the codec's internal buffer.
544
760
  * Handles packet cloning and error checking.
545
- * Returns null if encoder is closed, not initialized, or no packets available.
546
- * Call repeatedly until null to drain all buffered packets.
761
+ * Implements FFmpeg's send/receive pattern.
762
+ *
763
+ * **Return Values:**
764
+ * - `Packet` - Successfully encoded packet (AVERROR >= 0)
765
+ * - `null` - Need more input frames (AVERROR_EAGAIN), or encoder not initialized
766
+ * - `undefined` - End of stream reached (AVERROR_EOF), or encoder is closed
547
767
  *
548
768
  * Direct mapping to avcodec_receive_packet().
549
769
  *
550
- * @returns Cloned packet or null if no packets available
770
+ * @returns Cloned packet, null if need more data, or undefined if stream ended
551
771
  *
552
772
  * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
553
773
  *
554
774
  * @example
555
775
  * ```typescript
556
- * const packet = await encoder.receive();
557
- * if (packet) {
776
+ * // Process all buffered packets
777
+ * while (true) {
778
+ * const packet = await encoder.receive();
779
+ * if (!packet) break; // Stop on EAGAIN or EOF
558
780
  * console.log(`Got packet with PTS: ${packet.pts}`);
559
781
  * await output.writePacket(packet);
560
782
  * packet.free();
@@ -563,10 +785,14 @@ export declare class Encoder implements Disposable {
563
785
  *
564
786
  * @example
565
787
  * ```typescript
566
- * // Drain all buffered packets
567
- * let packet;
568
- * while ((packet = await encoder.receive()) !== null) {
569
- * console.log(`Packet size: ${packet.size}`);
788
+ * // Handle each return value explicitly
789
+ * const packet = await encoder.receive();
790
+ * if (packet === EOF) {
791
+ * console.log('Encoder stream ended');
792
+ * } else if (packet === null) {
793
+ * console.log('Need more input frames');
794
+ * } else {
795
+ * console.log(`Got packet: pts=${packet.pts}`);
570
796
  * await output.writePacket(packet);
571
797
  * packet.free();
572
798
  * }
@@ -574,27 +800,35 @@ export declare class Encoder implements Disposable {
574
800
  *
575
801
  * @see {@link encode} For sending frames and receiving packets
576
802
  * @see {@link flush} For signaling end-of-stream
803
+ * @see {@link receiveSync} For synchronous version
804
+ * @see {@link EOF} For end-of-stream signal
577
805
  */
578
- receive(): Promise<Packet | null>;
806
+ receive(): Promise<Packet | EOFSignal | null>;
579
807
  /**
580
808
  * Receive packet from encoder synchronously.
581
809
  * Synchronous version of receive.
582
810
  *
583
811
  * Gets encoded packets from the codec's internal buffer.
584
812
  * Handles packet cloning and error checking.
585
- * Returns null if encoder is closed, not initialized, or no packets available.
586
- * Call repeatedly until null to drain all buffered packets.
813
+ * Implements FFmpeg's send/receive pattern.
814
+ *
815
+ * **Return Values:**
816
+ * - `Packet` - Successfully encoded packet (AVERROR >= 0)
817
+ * - `null` - Need more input frames (AVERROR_EAGAIN), or encoder not initialized
818
+ * - `undefined` - End of stream reached (AVERROR_EOF), or encoder is closed
587
819
  *
588
820
  * Direct mapping to avcodec_receive_packet().
589
821
  *
590
- * @returns Cloned packet or null if no packets available
822
+ * @returns Cloned packet, null if need more data, or undefined if stream ended
591
823
  *
592
824
  * @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
593
825
  *
594
826
  * @example
595
827
  * ```typescript
596
- * const packet = encoder.receiveSync();
597
- * if (packet) {
828
+ * // Process all buffered packets
829
+ * while (true) {
830
+ * const packet = encoder.receiveSync();
831
+ * if (!packet) break; // Stop on EAGAIN or EOF
598
832
  * console.log(`Got packet with PTS: ${packet.pts}`);
599
833
  * output.writePacketSync(packet);
600
834
  * packet.free();
@@ -603,18 +837,40 @@ export declare class Encoder implements Disposable {
603
837
  *
604
838
  * @example
605
839
  * ```typescript
606
- * // Drain all buffered packets
607
- * let packet;
608
- * while ((packet = encoder.receiveSync()) !== null) {
609
- * console.log(`Packet size: ${packet.size}`);
840
+ * // Handle each return value explicitly
841
+ * const packet = encoder.receiveSync();
842
+ * if (packet === EOF) {
843
+ * console.log('Encoder stream ended');
844
+ * } else if (packet === null) {
845
+ * console.log('Need more input frames');
846
+ * } else {
847
+ * console.log(`Got packet: pts=${packet.pts}`);
610
848
  * output.writePacketSync(packet);
611
849
  * packet.free();
612
850
  * }
613
851
  * ```
614
852
  *
853
+ * @see {@link encodeSync} For sending frames and receiving packets
854
+ * @see {@link flushSync} For signaling end-of-stream
615
855
  * @see {@link receive} For async version
856
+ * @see {@link EOF} For end-of-stream signal
857
+ */
858
+ receiveSync(): Packet | EOFSignal | null;
859
+ /**
860
+ * Pipe encoded packets to muxer.
861
+ *
862
+ * @param target - Media output component to write packets to
863
+ *
864
+ * @param streamIndex - Stream index to write packets to
865
+ *
866
+ * @returns Scheduler for continued chaining
867
+ *
868
+ * @example
869
+ * ```typescript
870
+ * decoder.pipeTo(filter).pipeTo(encoder)
871
+ * ```
616
872
  */
617
- receiveSync(): Packet | null;
873
+ pipeTo(target: Muxer, streamIndex: number): SchedulerControl<Frame>;
618
874
  /**
619
875
  * Close encoder and free resources.
620
876
  *
@@ -635,6 +891,65 @@ export declare class Encoder implements Disposable {
635
891
  * @see {@link Symbol.dispose} For automatic cleanup
636
892
  */
637
893
  close(): void;
894
+ /**
895
+ * Get encoder codec.
896
+ *
897
+ * Returns the codec used by this encoder.
898
+ * Useful for checking codec capabilities and properties.
899
+ *
900
+ * @returns Codec instance
901
+ *
902
+ * @internal
903
+ *
904
+ * @see {@link Codec} For codec details
905
+ */
906
+ getCodec(): Codec;
907
+ /**
908
+ * Get underlying codec context.
909
+ *
910
+ * Returns the codec context for advanced operations.
911
+ * Useful for accessing low-level codec properties and settings.
912
+ * Returns null if encoder is closed or not initialized.
913
+ *
914
+ * @returns Codec context or null if closed/not initialized
915
+ *
916
+ * @internal
917
+ *
918
+ * @see {@link CodecContext} For context details
919
+ */
920
+ getCodecContext(): CodecContext | null;
921
+ /**
922
+ * Worker loop for push-based processing.
923
+ *
924
+ * @internal
925
+ */
926
+ private runWorker;
927
+ /**
928
+ * Send frame to input queue or flush the pipeline.
929
+ *
930
+ * When frame is provided, queues it for encoding.
931
+ * When null is provided, triggers flush sequence:
932
+ * - Closes input queue
933
+ * - Waits for worker completion
934
+ * - Flushes encoder and sends remaining packets to output queue
935
+ * - Closes output queue
936
+ * - Waits for pipeTo task completion (writes to muxer)
937
+ *
938
+ * Used by scheduler system for pipeline control.
939
+ *
940
+ * @param frame - Frame to send, or null to flush
941
+ *
942
+ * @internal
943
+ */
944
+ private sendToQueue;
945
+ /**
946
+ * Receive packet from output queue.
947
+ *
948
+ * @returns Packet from output queue
949
+ *
950
+ * @internal
951
+ */
952
+ private receiveFromQueue;
638
953
  /**
639
954
  * Initialize encoder from first frame.
640
955
  *
@@ -667,57 +982,33 @@ export declare class Encoder implements Disposable {
667
982
  */
668
983
  private initializeSync;
669
984
  /**
670
- * Get encoder codec.
985
+ * Setup hardware acceleration for encoder.
671
986
  *
672
- * Returns the codec used by this encoder.
673
- * Useful for checking codec capabilities and properties.
987
+ * Implements FFmpeg's hw_device_setup_for_encode logic.
988
+ * Validates hardware frames context format and codec support.
989
+ * Falls back to device context if frames context is incompatible.
674
990
  *
675
- * @returns Codec instance
991
+ * @param frame - Frame to get hardware context from
676
992
  *
677
993
  * @internal
678
- *
679
- * @see {@link Codec} For codec details
680
- */
681
- getCodec(): Codec;
682
- /**
683
- * Get underlying codec context.
684
- *
685
- * Returns the codec context for advanced operations.
686
- * Useful for accessing low-level codec properties and settings.
687
- * Returns null if encoder is closed or not initialized.
688
- *
689
- * @returns Codec context or null if closed/not initialized
690
- *
691
- * @internal
692
- *
693
- * @see {@link CodecContext} For context details
694
994
  */
695
- getCodecContext(): CodecContext | null;
995
+ private setupHardwareAcceleration;
696
996
  /**
697
- * Get codec flags even before encoder initialization.
997
+ * Prepare frame for encoding.
698
998
  *
699
- * Unlike getCodecContext(), this works before initialization.
999
+ * Implements FFmpeg's frame_encode() pre-encoding logic:
1000
+ * 1. Video: Sets frame.quality from encoder's globalQuality (like -qscale)
1001
+ * 2. Audio: Validates channel count consistency for encoders without PARAM_CHANGE capability
700
1002
  *
701
- * @returns Current codec flags
1003
+ * This matches FFmpeg CLI behavior where these properties are automatically managed.
702
1004
  *
703
- * @throws {Error} If encoder is closed
1005
+ * @param frame - Frame to prepare for encoding
704
1006
  *
705
- * @internal
706
- */
707
- getCodecFlags(): AVCodecFlag;
708
- /**
709
- * Set codec flags before encoder initialization.
710
- *
711
- * This allows setting flags on the codec context before the encoder is opened,
712
- * which is necessary for flags that affect initialization behavior (like GLOBAL_HEADER).
713
- *
714
- * @param flags - The flags to set
715
- *
716
- * @throws {Error} If encoder is already initialized or closed
1007
+ * @throws {Error} If audio channel count changed and encoder doesn't support parameter changes
717
1008
  *
718
1009
  * @internal
719
1010
  */
720
- setCodecFlags(flags: AVCodecFlag): void;
1011
+ private prepareFrameForEncoding;
721
1012
  /**
722
1013
  * Dispose of encoder.
723
1014
  *