node-av 1.3.0 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/README.md +47 -40
  2. package/binding.gyp +12 -0
  3. package/dist/api/bitstream-filter.d.ts +134 -2
  4. package/dist/api/bitstream-filter.js +200 -2
  5. package/dist/api/bitstream-filter.js.map +1 -1
  6. package/dist/api/decoder.d.ts +261 -105
  7. package/dist/api/decoder.js +384 -171
  8. package/dist/api/decoder.js.map +1 -1
  9. package/dist/api/encoder.d.ts +338 -74
  10. package/dist/api/encoder.js +546 -188
  11. package/dist/api/encoder.js.map +1 -1
  12. package/dist/api/filter-presets.d.ts +479 -1513
  13. package/dist/api/filter-presets.js +1044 -2005
  14. package/dist/api/filter-presets.js.map +1 -1
  15. package/dist/api/filter.d.ts +370 -150
  16. package/dist/api/filter.js +647 -364
  17. package/dist/api/filter.js.map +1 -1
  18. package/dist/api/hardware.d.ts +25 -31
  19. package/dist/api/hardware.js +36 -70
  20. package/dist/api/hardware.js.map +1 -1
  21. package/dist/api/index.d.ts +1 -1
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/index.js.map +1 -1
  24. package/dist/api/io-stream.d.ts +6 -0
  25. package/dist/api/io-stream.js +2 -0
  26. package/dist/api/io-stream.js.map +1 -1
  27. package/dist/api/media-input.d.ts +208 -2
  28. package/dist/api/media-input.js +356 -8
  29. package/dist/api/media-input.js.map +1 -1
  30. package/dist/api/media-output.d.ts +142 -104
  31. package/dist/api/media-output.js +446 -179
  32. package/dist/api/media-output.js.map +1 -1
  33. package/dist/api/pipeline.d.ts +82 -17
  34. package/dist/api/pipeline.js +80 -42
  35. package/dist/api/pipeline.js.map +1 -1
  36. package/dist/api/types.d.ts +24 -57
  37. package/dist/api/utils.js +2 -0
  38. package/dist/api/utils.js.map +1 -1
  39. package/dist/lib/audio-fifo.d.ts +103 -0
  40. package/dist/lib/audio-fifo.js +109 -0
  41. package/dist/lib/audio-fifo.js.map +1 -1
  42. package/dist/lib/binding.d.ts +1 -0
  43. package/dist/lib/binding.js.map +1 -1
  44. package/dist/lib/bitstream-filter-context.d.ts +79 -0
  45. package/dist/lib/bitstream-filter-context.js +83 -0
  46. package/dist/lib/bitstream-filter-context.js.map +1 -1
  47. package/dist/lib/bitstream-filter.d.ts +2 -0
  48. package/dist/lib/bitstream-filter.js +2 -0
  49. package/dist/lib/bitstream-filter.js.map +1 -1
  50. package/dist/lib/codec-context.d.ts +168 -0
  51. package/dist/lib/codec-context.js +178 -0
  52. package/dist/lib/codec-context.js.map +1 -1
  53. package/dist/lib/codec-parameters.d.ts +3 -0
  54. package/dist/lib/codec-parameters.js +3 -0
  55. package/dist/lib/codec-parameters.js.map +1 -1
  56. package/dist/lib/codec-parser.d.ts +6 -0
  57. package/dist/lib/codec-parser.js +6 -0
  58. package/dist/lib/codec-parser.js.map +1 -1
  59. package/dist/lib/codec.d.ts +12 -0
  60. package/dist/lib/codec.js +12 -0
  61. package/dist/lib/codec.js.map +1 -1
  62. package/dist/lib/dictionary.d.ts +18 -2
  63. package/dist/lib/dictionary.js +18 -2
  64. package/dist/lib/dictionary.js.map +1 -1
  65. package/dist/lib/error.d.ts +8 -0
  66. package/dist/lib/error.js +9 -0
  67. package/dist/lib/error.js.map +1 -1
  68. package/dist/lib/filter-context.d.ts +119 -2
  69. package/dist/lib/filter-context.js +119 -0
  70. package/dist/lib/filter-context.js.map +1 -1
  71. package/dist/lib/filter-graph.d.ts +80 -0
  72. package/dist/lib/filter-graph.js +84 -0
  73. package/dist/lib/filter-graph.js.map +1 -1
  74. package/dist/lib/filter-inout.d.ts +1 -0
  75. package/dist/lib/filter-inout.js +1 -0
  76. package/dist/lib/filter-inout.js.map +1 -1
  77. package/dist/lib/filter.d.ts +2 -0
  78. package/dist/lib/filter.js +2 -0
  79. package/dist/lib/filter.js.map +1 -1
  80. package/dist/lib/format-context.d.ts +356 -20
  81. package/dist/lib/format-context.js +375 -23
  82. package/dist/lib/format-context.js.map +1 -1
  83. package/dist/lib/frame.d.ts +84 -1
  84. package/dist/lib/frame.js +96 -0
  85. package/dist/lib/frame.js.map +1 -1
  86. package/dist/lib/hardware-device-context.d.ts +8 -0
  87. package/dist/lib/hardware-device-context.js +8 -0
  88. package/dist/lib/hardware-device-context.js.map +1 -1
  89. package/dist/lib/hardware-frames-context.d.ts +55 -0
  90. package/dist/lib/hardware-frames-context.js +57 -0
  91. package/dist/lib/hardware-frames-context.js.map +1 -1
  92. package/dist/lib/input-format.d.ts +43 -3
  93. package/dist/lib/input-format.js +48 -0
  94. package/dist/lib/input-format.js.map +1 -1
  95. package/dist/lib/io-context.d.ts +212 -0
  96. package/dist/lib/io-context.js +228 -0
  97. package/dist/lib/io-context.js.map +1 -1
  98. package/dist/lib/log.d.ts +2 -0
  99. package/dist/lib/log.js +2 -0
  100. package/dist/lib/log.js.map +1 -1
  101. package/dist/lib/native-types.d.ts +39 -1
  102. package/dist/lib/option.d.ts +90 -0
  103. package/dist/lib/option.js +97 -0
  104. package/dist/lib/option.js.map +1 -1
  105. package/dist/lib/output-format.d.ts +4 -0
  106. package/dist/lib/output-format.js +4 -0
  107. package/dist/lib/output-format.js.map +1 -1
  108. package/dist/lib/packet.d.ts +7 -0
  109. package/dist/lib/packet.js +7 -0
  110. package/dist/lib/packet.js.map +1 -1
  111. package/dist/lib/rational.d.ts +1 -0
  112. package/dist/lib/rational.js +1 -0
  113. package/dist/lib/rational.js.map +1 -1
  114. package/dist/lib/software-resample-context.d.ts +64 -0
  115. package/dist/lib/software-resample-context.js +66 -0
  116. package/dist/lib/software-resample-context.js.map +1 -1
  117. package/dist/lib/software-scale-context.d.ts +98 -0
  118. package/dist/lib/software-scale-context.js +102 -0
  119. package/dist/lib/software-scale-context.js.map +1 -1
  120. package/dist/lib/stream.d.ts +1 -0
  121. package/dist/lib/stream.js +1 -0
  122. package/dist/lib/stream.js.map +1 -1
  123. package/dist/lib/utilities.d.ts +60 -0
  124. package/dist/lib/utilities.js +60 -0
  125. package/dist/lib/utilities.js.map +1 -1
  126. package/package.json +18 -18
  127. package/release_notes.md +0 -29
@@ -3,15 +3,20 @@ import { Encoder } from './encoder.js';
3
3
  import type { IRational, Packet, Stream } from '../lib/index.js';
4
4
  import type { IOOutputCallbacks, MediaOutputOptions } from './types.js';
5
5
  export interface StreamDescription {
6
+ initialized: boolean;
6
7
  stream: Stream;
7
- timeBase: IRational;
8
- isStreamCopy: boolean;
8
+ source: Encoder | Stream;
9
+ timeBase?: IRational;
9
10
  sourceTimeBase?: IRational;
11
+ isStreamCopy: boolean;
12
+ bufferedPackets: Packet[];
10
13
  }
11
14
  /**
12
15
  * High-level media output for writing and muxing media files.
13
16
  *
14
17
  * Provides simplified access to media muxing and file writing operations.
18
+ * Automatically manages header and trailer writing - header is written on first packet,
19
+ * trailer is written on close. Supports lazy initialization for both encoders and streams.
15
20
  * Handles stream configuration, packet writing, and format management.
16
21
  * Supports files, URLs, and custom I/O with automatic cleanup.
17
22
  * Essential component for media encoding pipelines and transcoding.
@@ -27,14 +32,11 @@ export interface StreamDescription {
27
32
  * const videoIdx = output.addStream(videoEncoder);
28
33
  * const audioIdx = output.addStream(audioEncoder);
29
34
  *
30
- * // Write header
31
- * await output.writeHeader();
32
- *
33
- * // Write packets
35
+ * // Write packets - header written automatically on first packet
34
36
  * await output.writePacket(packet, videoIdx);
35
37
  *
36
- * // Write trailer and close
37
- * await output.writeTrailer();
38
+ * // Close - trailer written automatically
39
+ * // (automatic with await using)
38
40
  * ```
39
41
  *
40
42
  * @example
@@ -45,8 +47,8 @@ export interface StreamDescription {
45
47
  *
46
48
  * // Copy stream configuration
47
49
  * const videoIdx = output.addStream(input.video());
48
- * await output.writeHeader();
49
50
  *
51
+ * // Process packets - header/trailer handled automatically
50
52
  * for await (const packet of input.packets()) {
51
53
  * await output.writePacket(packet, videoIdx);
52
54
  * packet.free();
@@ -57,13 +59,14 @@ export interface StreamDescription {
57
59
  * @see {@link Encoder} For encoding frames to packets
58
60
  * @see {@link FormatContext} For low-level API
59
61
  */
60
- export declare class MediaOutput implements AsyncDisposable {
62
+ export declare class MediaOutput implements AsyncDisposable, Disposable {
61
63
  private formatContext;
62
64
  private streams;
63
65
  private ioContext?;
64
66
  private headerWritten;
65
67
  private trailerWritten;
66
- private closed;
68
+ private isClosed;
69
+ private headerWritePromise?;
67
70
  /**
68
71
  * @internal
69
72
  */
@@ -78,7 +81,9 @@ export declare class MediaOutput implements AsyncDisposable {
78
81
  * Direct mapping to avformat_alloc_output_context2() and avio_open2().
79
82
  *
80
83
  * @param target - File path, URL, or I/O callbacks
84
+ *
81
85
  * @param options - Output configuration options
86
+ *
82
87
  * @returns Opened media output instance
83
88
  *
84
89
  * @throws {Error} If format required for custom I/O
@@ -123,25 +128,69 @@ export declare class MediaOutput implements AsyncDisposable {
123
128
  * @see {@link IOOutputCallbacks} For custom I/O interface
124
129
  */
125
130
  static open(target: string | IOOutputCallbacks, options?: MediaOutputOptions): Promise<MediaOutput>;
131
+ /**
132
+ * Open media output for writing synchronously.
133
+ * Synchronous version of open.
134
+ *
135
+ * Creates and configures output context for muxing.
136
+ * Automatically creates directories for file output.
137
+ * Supports files, URLs, and custom I/O callbacks.
138
+ *
139
+ * Direct mapping to avformat_alloc_output_context2() and avio_open2().
140
+ *
141
+ * @param target - File path, URL, or I/O callbacks
142
+ *
143
+ * @param options - Output configuration options
144
+ *
145
+ * @returns Opened media output instance
146
+ *
147
+ * @throws {Error} If format required for custom I/O
148
+ *
149
+ * @throws {FFmpegError} If allocation or opening fails
150
+ *
151
+ * @example
152
+ * ```typescript
153
+ * // Create file output
154
+ * using output = MediaOutput.openSync('output.mp4');
155
+ * ```
156
+ *
157
+ * @example
158
+ * ```typescript
159
+ * // Create output with specific format
160
+ * using output = MediaOutput.openSync('output.ts', {
161
+ * format: 'mpegts'
162
+ * });
163
+ * ```
164
+ *
165
+ * @see {@link open} For async version
166
+ */
167
+ static openSync(target: string | IOOutputCallbacks, options?: MediaOutputOptions): MediaOutput;
126
168
  /**
127
169
  * Add a stream to the output.
128
170
  *
129
171
  * Configures output stream from encoder or input stream.
130
- * Must be called before writeHeader().
172
+ * Must be called before writing any packets.
131
173
  * Returns stream index for packet writing.
132
174
  *
133
- * Direct mapping to avformat_new_stream() and avcodec_parameters_copy().
175
+ * Streams are initialized lazily - codec parameters are configured
176
+ * automatically when the first packet is written. This allows encoders
177
+ * to be initialized from frame properties.
178
+ *
179
+ * Direct mapping to avformat_new_stream().
134
180
  *
135
181
  * @param source - Encoder or stream to add
182
+ *
136
183
  * @param options - Stream configuration options
184
+ *
137
185
  * @param options.timeBase - Optional custom timebase for the stream
186
+ *
138
187
  * @returns Stream index for packet writing
139
188
  *
140
- * @throws {Error} If called after header written or output closed
189
+ * @throws {Error} If called after packets have been written or output closed
141
190
  *
142
191
  * @example
143
192
  * ```typescript
144
- * // Add stream from encoder
193
+ * // Add stream from encoder (lazy initialization)
145
194
  * const videoIdx = output.addStream(videoEncoder);
146
195
  * const audioIdx = output.addStream(audioEncoder);
147
196
  * ```
@@ -164,20 +213,28 @@ export declare class MediaOutput implements AsyncDisposable {
164
213
  * Write a packet to the output.
165
214
  *
166
215
  * Writes muxed packet to the specified stream.
167
- * Automatically handles timestamp rescaling.
168
- * Must be called after writeHeader() and before writeTrailer().
216
+ * Automatically handles:
217
+ * - Stream initialization on first packet (lazy initialization)
218
+ * - Codec parameter configuration from encoder or input stream
219
+ * - Header writing on first packet
220
+ * - Timestamp rescaling between source and output timebases
221
+ *
222
+ * For encoder sources, the encoder must have processed at least one frame
223
+ * before packets can be written (encoder must be initialized).
169
224
  *
170
- * Direct mapping to av_interleaved_write_frame().
225
+ * Direct mapping to avformat_write_header() (on first packet) and av_interleaved_write_frame().
171
226
  *
172
227
  * @param packet - Packet to write
228
+ *
173
229
  * @param streamIndex - Target stream index
174
- * @throws {Error} If stream invalid or called at wrong time
230
+ *
231
+ * @throws {Error} If stream invalid or encoder not initialized
175
232
  *
176
233
  * @throws {FFmpegError} If write fails
177
234
  *
178
235
  * @example
179
236
  * ```typescript
180
- * // Write encoded packet
237
+ * // Write encoded packet - header written automatically on first packet
181
238
  * const packet = await encoder.encode(frame);
182
239
  * if (packet) {
183
240
  * await output.writePacket(packet, videoIdx);
@@ -197,64 +254,61 @@ export declare class MediaOutput implements AsyncDisposable {
197
254
  * ```
198
255
  *
199
256
  * @see {@link addStream} For adding streams
200
- * @see {@link writeHeader} Must be called first
201
257
  */
202
258
  writePacket(packet: Packet, streamIndex: number): Promise<void>;
203
259
  /**
204
- * Write file header.
260
+ * Write a packet to the output synchronously.
261
+ * Synchronous version of writePacket.
205
262
  *
206
- * Writes format header with stream configuration.
207
- * Must be called after adding all streams and before writing packets.
208
- * Finalizes stream parameters and initializes muxer.
263
+ * Writes muxed packet to the specified stream.
264
+ * Automatically handles:
265
+ * - Stream initialization on first packet (lazy initialization)
266
+ * - Codec parameter configuration from encoder or input stream
267
+ * - Header writing on first packet
268
+ * - Timestamp rescaling between source and output timebases
269
+ *
270
+ * For encoder sources, the encoder must have processed at least one frame
271
+ * before packets can be written (encoder must be initialized).
209
272
  *
210
- * Direct mapping to avformat_write_header().
273
+ * Direct mapping to avformat_write_header() (on first packet) and av_interleaved_write_frame().
211
274
  *
212
- * @throws {Error} If already written or output closed
275
+ * @param packet - Packet to write
276
+ *
277
+ * @param streamIndex - Target stream index
278
+ *
279
+ * @throws {Error} If stream invalid or encoder not initialized
213
280
  *
214
281
  * @throws {FFmpegError} If write fails
215
282
  *
216
283
  * @example
217
284
  * ```typescript
218
- * // Standard workflow
219
- * const output = await MediaOutput.open('output.mp4');
220
- * output.addStream(encoder);
221
- * await output.writeHeader();
222
- * // Now ready to write packets
285
+ * // Write encoded packet - header written automatically on first packet
286
+ * const packet = encoder.encodeSync(frame);
287
+ * if (packet) {
288
+ * output.writePacketSync(packet, videoIdx);
289
+ * packet.free();
290
+ * }
223
291
  * ```
224
292
  *
225
- * @see {@link addStream} Must add streams first
226
- * @see {@link writePacket} Can write packets after
227
- * @see {@link writeTrailer} Must call at end
228
- */
229
- writeHeader(): Promise<void>;
230
- /**
231
- * Write file trailer.
232
- *
233
- * Writes format trailer and finalizes the file.
234
- * Must be called after all packets are written.
235
- * Flushes any buffered data and updates file headers.
236
- *
237
- * Direct mapping to av_write_trailer().
238
- *
239
- * @throws {Error} If header not written or already written
240
- *
241
- * @throws {FFmpegError} If write fails
242
- *
243
293
  * @example
244
294
  * ```typescript
245
- * // Finalize output
246
- * await output.writeTrailer();
247
- * await output.close();
295
+ * // Stream copy with packet processing
296
+ * for (const packet of input.packetsSync()) {
297
+ * if (packet.streamIndex === inputVideoIdx) {
298
+ * output.writePacketSync(packet, outputVideoIdx);
299
+ * }
300
+ * packet.free();
301
+ * }
248
302
  * ```
249
303
  *
250
- * @see {@link writeHeader} Must be called first
251
- * @see {@link close} For cleanup after trailer
304
+ * @see {@link writePacket} For async version
252
305
  */
253
- writeTrailer(): Promise<void>;
306
+ writePacketSync(packet: Packet, streamIndex: number): void;
254
307
  /**
255
308
  * Close media output and free resources.
256
309
  *
257
- * Writes trailer if needed and releases all resources.
310
+ * Automatically writes trailer if header was written.
311
+ * Closes the output file and releases all resources.
258
312
  * Safe to call multiple times.
259
313
  * Automatically called by Symbol.asyncDispose.
260
314
  *
@@ -262,7 +316,7 @@ export declare class MediaOutput implements AsyncDisposable {
262
316
  * ```typescript
263
317
  * const output = await MediaOutput.open('output.mp4');
264
318
  * try {
265
- * // Use output
319
+ * // Use output - trailer written automatically on close
266
320
  * } finally {
267
321
  * await output.close();
268
322
  * }
@@ -272,60 +326,27 @@ export declare class MediaOutput implements AsyncDisposable {
272
326
  */
273
327
  close(): Promise<void>;
274
328
  /**
275
- * Get stream information.
276
- *
277
- * Returns internal stream info for the specified index.
329
+ * Close media output and free resources synchronously.
330
+ * Synchronous version of close.
278
331
  *
279
- * @param streamIndex - Stream index
280
- * @returns Stream info or undefined
281
- *
282
- * @example
283
- * ```typescript
284
- * const info = output.getStreamInfo(0);
285
- * console.log(`Stream 0 timebase: ${info?.timeBase.num}/${info?.timeBase.den}`);
286
- * ```
287
- */
288
- getStreamInfo(streamIndex: number): StreamDescription | undefined;
289
- /**
290
- * Get all stream indices.
291
- *
292
- * Returns array of all added stream indices.
293
- *
294
- * @returns Array of stream indices
295
- *
296
- * @example
297
- * ```typescript
298
- * const indices = output.getStreamIndices();
299
- * console.log(`Output has ${indices.length} streams`);
300
- * ```
301
- */
302
- getStreamIndices(): number[];
303
- /**
304
- * Check if header has been written.
305
- *
306
- * @returns true if header written
332
+ * Automatically writes trailer if header was written.
333
+ * Closes the output file and releases all resources.
334
+ * Safe to call multiple times.
335
+ * Automatically called by Symbol.dispose.
307
336
  *
308
337
  * @example
309
338
  * ```typescript
310
- * if (!output.isHeaderWritten()) {
311
- * await output.writeHeader();
339
+ * const output = MediaOutput.openSync('output.mp4');
340
+ * try {
341
+ * // Use output - trailer written automatically on close
342
+ * } finally {
343
+ * output.closeSync();
312
344
  * }
313
345
  * ```
314
- */
315
- isHeaderWritten(): boolean;
316
- /**
317
- * Check if trailer has been written.
318
- *
319
- * @returns true if trailer written
320
346
  *
321
- * @example
322
- * ```typescript
323
- * if (!output.isTrailerWritten()) {
324
- * await output.writeTrailer();
325
- * }
326
- * ```
347
+ * @see {@link close} For async version
327
348
  */
328
- isTrailerWritten(): boolean;
349
+ closeSync(): void;
329
350
  /**
330
351
  * Get underlying format context.
331
352
  *
@@ -353,4 +374,21 @@ export declare class MediaOutput implements AsyncDisposable {
353
374
  * @see {@link close} For manual cleanup
354
375
  */
355
376
  [Symbol.asyncDispose](): Promise<void>;
377
+ /**
378
+ * Dispose of media output synchronously.
379
+ *
380
+ * Implements Disposable interface for automatic cleanup.
381
+ * Equivalent to calling closeSync().
382
+ *
383
+ * @example
384
+ * ```typescript
385
+ * {
386
+ * using output = MediaOutput.openSync('output.mp4');
387
+ * // Use output...
388
+ * } // Automatically closed
389
+ * ```
390
+ *
391
+ * @see {@link closeSync} For manual cleanup
392
+ */
393
+ [Symbol.dispose](): void;
356
394
  }