node-av 1.1.0 → 1.2.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 (134) hide show
  1. package/README.md +51 -38
  2. package/dist/api/bitstream-filter.d.ts +180 -123
  3. package/dist/api/bitstream-filter.js +180 -125
  4. package/dist/api/bitstream-filter.js.map +1 -1
  5. package/dist/api/decoder.d.ts +279 -132
  6. package/dist/api/decoder.js +285 -142
  7. package/dist/api/decoder.js.map +1 -1
  8. package/dist/api/encoder.d.ts +246 -162
  9. package/dist/api/encoder.js +272 -208
  10. package/dist/api/encoder.js.map +1 -1
  11. package/dist/api/filter-presets.d.ts +690 -94
  12. package/dist/api/filter-presets.js +686 -102
  13. package/dist/api/filter-presets.js.map +1 -1
  14. package/dist/api/filter.d.ts +249 -213
  15. package/dist/api/filter.js +252 -242
  16. package/dist/api/filter.js.map +1 -1
  17. package/dist/api/hardware.d.ts +224 -117
  18. package/dist/api/hardware.js +380 -214
  19. package/dist/api/hardware.js.map +1 -1
  20. package/dist/api/index.d.ts +3 -3
  21. package/dist/api/index.js +1 -1
  22. package/dist/api/index.js.map +1 -1
  23. package/dist/api/io-stream.d.ts +65 -61
  24. package/dist/api/io-stream.js +43 -46
  25. package/dist/api/io-stream.js.map +1 -1
  26. package/dist/api/media-input.d.ts +242 -140
  27. package/dist/api/media-input.js +205 -103
  28. package/dist/api/media-input.js.map +1 -1
  29. package/dist/api/media-output.d.ts +206 -128
  30. package/dist/api/media-output.js +210 -128
  31. package/dist/api/media-output.js.map +1 -1
  32. package/dist/api/pipeline.d.ts +168 -38
  33. package/dist/api/pipeline.js +238 -14
  34. package/dist/api/pipeline.js.map +1 -1
  35. package/dist/api/types.d.ts +21 -187
  36. package/dist/api/utils.d.ts +1 -2
  37. package/dist/api/utils.js +9 -0
  38. package/dist/api/utils.js.map +1 -1
  39. package/dist/lib/audio-fifo.d.ts +127 -170
  40. package/dist/lib/audio-fifo.js +130 -173
  41. package/dist/lib/audio-fifo.js.map +1 -1
  42. package/dist/lib/binding.js +5 -0
  43. package/dist/lib/binding.js.map +1 -1
  44. package/dist/lib/bitstream-filter-context.d.ts +139 -184
  45. package/dist/lib/bitstream-filter-context.js +139 -188
  46. package/dist/lib/bitstream-filter-context.js.map +1 -1
  47. package/dist/lib/bitstream-filter.d.ts +68 -54
  48. package/dist/lib/bitstream-filter.js +68 -54
  49. package/dist/lib/bitstream-filter.js.map +1 -1
  50. package/dist/lib/codec-context.d.ts +316 -380
  51. package/dist/lib/codec-context.js +316 -381
  52. package/dist/lib/codec-context.js.map +1 -1
  53. package/dist/lib/codec-parameters.d.ts +160 -170
  54. package/dist/lib/codec-parameters.js +162 -172
  55. package/dist/lib/codec-parameters.js.map +1 -1
  56. package/dist/lib/codec-parser.d.ts +91 -104
  57. package/dist/lib/codec-parser.js +92 -103
  58. package/dist/lib/codec-parser.js.map +1 -1
  59. package/dist/lib/codec.d.ts +264 -281
  60. package/dist/lib/codec.js +268 -285
  61. package/dist/lib/codec.js.map +1 -1
  62. package/dist/lib/dictionary.d.ts +149 -203
  63. package/dist/lib/dictionary.js +158 -212
  64. package/dist/lib/dictionary.js.map +1 -1
  65. package/dist/lib/error.d.ts +96 -130
  66. package/dist/lib/error.js +98 -128
  67. package/dist/lib/error.js.map +1 -1
  68. package/dist/lib/filter-context.d.ts +284 -218
  69. package/dist/lib/filter-context.js +290 -227
  70. package/dist/lib/filter-context.js.map +1 -1
  71. package/dist/lib/filter-graph.d.ts +251 -292
  72. package/dist/lib/filter-graph.js +253 -294
  73. package/dist/lib/filter-graph.js.map +1 -1
  74. package/dist/lib/filter-inout.d.ts +87 -95
  75. package/dist/lib/filter-inout.js +87 -95
  76. package/dist/lib/filter-inout.js.map +1 -1
  77. package/dist/lib/filter.d.ts +93 -111
  78. package/dist/lib/filter.js +93 -111
  79. package/dist/lib/filter.js.map +1 -1
  80. package/dist/lib/format-context.d.ts +320 -428
  81. package/dist/lib/format-context.js +313 -385
  82. package/dist/lib/format-context.js.map +1 -1
  83. package/dist/lib/frame.d.ts +262 -405
  84. package/dist/lib/frame.js +263 -408
  85. package/dist/lib/frame.js.map +1 -1
  86. package/dist/lib/hardware-device-context.d.ts +149 -203
  87. package/dist/lib/hardware-device-context.js +149 -203
  88. package/dist/lib/hardware-device-context.js.map +1 -1
  89. package/dist/lib/hardware-frames-context.d.ts +170 -180
  90. package/dist/lib/hardware-frames-context.js +171 -181
  91. package/dist/lib/hardware-frames-context.js.map +1 -1
  92. package/dist/lib/index.d.ts +2 -1
  93. package/dist/lib/index.js +2 -2
  94. package/dist/lib/index.js.map +1 -1
  95. package/dist/lib/input-format.d.ts +89 -117
  96. package/dist/lib/input-format.js +89 -117
  97. package/dist/lib/input-format.js.map +1 -1
  98. package/dist/lib/io-context.d.ts +209 -241
  99. package/dist/lib/io-context.js +220 -252
  100. package/dist/lib/io-context.js.map +1 -1
  101. package/dist/lib/log.d.ts +85 -119
  102. package/dist/lib/log.js +85 -122
  103. package/dist/lib/log.js.map +1 -1
  104. package/dist/lib/native-types.d.ts +117 -106
  105. package/dist/lib/native-types.js +0 -7
  106. package/dist/lib/native-types.js.map +1 -1
  107. package/dist/lib/option.d.ts +284 -241
  108. package/dist/lib/option.js +309 -249
  109. package/dist/lib/option.js.map +1 -1
  110. package/dist/lib/output-format.d.ts +77 -101
  111. package/dist/lib/output-format.js +77 -101
  112. package/dist/lib/output-format.js.map +1 -1
  113. package/dist/lib/packet.d.ts +172 -240
  114. package/dist/lib/packet.js +172 -241
  115. package/dist/lib/packet.js.map +1 -1
  116. package/dist/lib/rational.d.ts +0 -2
  117. package/dist/lib/rational.js +0 -2
  118. package/dist/lib/rational.js.map +1 -1
  119. package/dist/lib/software-resample-context.d.ts +241 -325
  120. package/dist/lib/software-resample-context.js +242 -326
  121. package/dist/lib/software-resample-context.js.map +1 -1
  122. package/dist/lib/software-scale-context.d.ts +129 -173
  123. package/dist/lib/software-scale-context.js +131 -175
  124. package/dist/lib/software-scale-context.js.map +1 -1
  125. package/dist/lib/stream.d.ts +87 -197
  126. package/dist/lib/stream.js +87 -197
  127. package/dist/lib/stream.js.map +1 -1
  128. package/dist/lib/utilities.d.ts +372 -181
  129. package/dist/lib/utilities.js +373 -182
  130. package/dist/lib/utilities.js.map +1 -1
  131. package/install/check.js +0 -1
  132. package/package.json +21 -12
  133. package/release_notes.md +43 -59
  134. package/CHANGELOG.md +0 -8
@@ -7,104 +7,65 @@ import { OptionMember } from './option.js';
7
7
  import { OutputFormat } from './output-format.js';
8
8
  import { Stream } from './stream.js';
9
9
  /**
10
- * FFmpeg format context for demuxing and muxing.
10
+ * Container format context for reading/writing multimedia files.
11
11
  *
12
- * Central structure for media file handling, managing both input (demuxing) and output (muxing).
13
- * Provides full control over allocation, configuration and lifecycle with no hidden operations.
14
- * Handles container formats, streams, metadata, and packet I/O operations.
12
+ * Central structure for demuxing (reading) and muxing (writing) media files.
13
+ * Manages streams, packets, metadata, and format-specific operations.
14
+ * Supports both file-based and custom I/O through IOContext.
15
+ * Essential for all file-based media operations.
15
16
  *
16
17
  * Direct mapping to FFmpeg's AVFormatContext.
17
18
  *
18
19
  * @example
19
20
  * ```typescript
20
- * import { FormatContext, Packet, FFmpegError } from 'node-av';
21
+ * import { FormatContext, FFmpegError } from 'node-av';
22
+ * import { AVMEDIA_TYPE_VIDEO } from 'node-av/constants';
21
23
  *
22
- * // Demuxing - full control over every step
24
+ * // Open input file
23
25
  * const ctx = new FormatContext();
24
- * ctx.allocContext();
25
- *
26
- * const ret = await ctx.openInput('video.mp4', null, null);
26
+ * let ret = await ctx.openInput('input.mp4');
27
27
  * FFmpegError.throwIfError(ret, 'openInput');
28
28
  *
29
- * const infoRet = await ctx.findStreamInfo(null);
30
- * FFmpegError.throwIfError(infoRet, 'findStreamInfo');
29
+ * ret = await ctx.findStreamInfo();
30
+ * FFmpegError.throwIfError(ret, 'findStreamInfo');
31
+ *
32
+ * // Find video stream
33
+ * const videoIndex = ctx.findBestStream(AVMEDIA_TYPE_VIDEO);
34
+ * if (videoIndex < 0) {
35
+ * throw new Error('No video stream found');
36
+ * }
31
37
  *
38
+ * // Read packets
32
39
  * const packet = new Packet();
33
40
  * packet.alloc();
34
- *
35
- * while (true) {
36
- * const readRet = await ctx.readFrame(packet);
37
- * if (readRet < 0) break; // EOF or error
38
- * // Process packet
41
+ * while ((ret = await ctx.readFrame(packet)) >= 0) {
42
+ * if (packet.streamIndex === videoIndex) {
43
+ * // Process video packet
44
+ * }
39
45
  * packet.unref();
40
46
  * }
41
47
  *
48
+ * // Cleanup
42
49
  * await ctx.closeInput();
43
- * ctx.freeContext();
44
50
  * ```
45
51
  *
46
- * @example
47
- * ```typescript
48
- * import { FormatContext, FFmpegError } from 'node-av';
49
- *
50
- * // Muxing - explicit control
51
- * const ctx = new FormatContext();
52
- * const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4');
53
- * FFmpegError.throwIfError(ret, 'allocOutputContext2');
54
- *
55
- * // Add streams
56
- * const stream = ctx.newStream(null);
57
- *
58
- * // Write header
59
- * const headerRet = await ctx.writeHeader(null);
60
- * FFmpegError.throwIfError(headerRet, 'writeHeader');
61
- *
62
- * // Write packets
63
- * const writeRet = await ctx.interleavedWriteFrame(packet);
64
- * FFmpegError.throwIfError(writeRet, 'interleavedWriteFrame');
65
- *
66
- * // Finalize
67
- * const trailerRet = await ctx.writeTrailer();
68
- * FFmpegError.throwIfError(trailerRet, 'writeTrailer');
69
- * ctx.freeContext();
70
- * ```
71
- *
72
- * @see {@link InputFormat} For input format handling
73
- * @see {@link OutputFormat} For output format handling
52
+ * @see [AVFormatContext](https://ffmpeg.org/doxygen/trunk/structAVFormatContext.html) - FFmpeg Doxygen
53
+ * @see {@link InputFormat} For supported input formats
54
+ * @see {@link OutputFormat} For supported output formats
74
55
  * @see {@link Stream} For stream management
75
- * @see {@link Packet} For packet handling
76
56
  */
77
57
  export class FormatContext extends OptionMember {
78
58
  _ioContext = null;
79
- /**
80
- * Create a new format context.
81
- *
82
- * The context is uninitialized - you must call allocContext() or allocOutputContext2() before use.
83
- * No FFmpeg resources are allocated until initialization.
84
- *
85
- * Direct wrapper around AVFormatContext.
86
- *
87
- * @example
88
- * ```typescript
89
- * import { FormatContext, FFmpegError } from 'node-av';
90
- *
91
- * const ctx = new FormatContext();
92
- * ctx.allocContext(); // For demuxing
93
- * // OR
94
- * const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4'); // For muxing
95
- * FFmpegError.throwIfError(ret, 'allocOutputContext2');
96
- * ```
97
- */
98
59
  constructor() {
99
60
  super(new bindings.FormatContext());
100
61
  }
101
62
  /**
102
- * Input or output URL/filename.
63
+ * URL or filename of the media.
103
64
  *
104
- * Direct mapping to AVFormatContext->url
65
+ * For input: the opened file path.
66
+ * For output: the target file path.
105
67
  *
106
- * - muxing: Set by user
107
- * - demuxing: Set by avformat_open_input
68
+ * Direct mapping to AVFormatContext->url.
108
69
  */
109
70
  get url() {
110
71
  return this.native.url;
@@ -113,46 +74,45 @@ export class FormatContext extends OptionMember {
113
74
  this.native.url = value;
114
75
  }
115
76
  /**
116
- * Position of the first frame of the component, in AV_TIME_BASE units.
77
+ * Start time of the stream.
117
78
  *
118
- * Direct mapping to AVFormatContext->start_time
79
+ * Position of the first frame in microseconds.
80
+ * AV_NOPTS_VALUE if unknown.
119
81
  *
120
- * NEVER set this value directly: it is deduced from the AVStream values.
121
- * - demuxing: Set by libavformat
82
+ * Direct mapping to AVFormatContext->start_time.
122
83
  */
123
84
  get startTime() {
124
85
  return this.native.startTime;
125
86
  }
126
87
  /**
127
- * Duration of the stream, in AV_TIME_BASE units.
88
+ * Duration of the stream.
128
89
  *
129
- * Direct mapping to AVFormatContext->duration
90
+ * Total stream duration in microseconds.
91
+ * AV_NOPTS_VALUE if unknown.
130
92
  *
131
- * Only set this value if you know none of the individual stream durations.
132
- * - demuxing: Set by libavformat
133
- * - muxing: May be set by user
93
+ * Direct mapping to AVFormatContext->duration.
134
94
  */
135
95
  get duration() {
136
96
  return this.native.duration;
137
97
  }
138
98
  /**
139
- * Total stream bitrate in bit/s, 0 if not available.
99
+ * Total stream bitrate.
140
100
  *
141
- * Direct mapping to AVFormatContext->bit_rate
101
+ * Bitrate in bits per second.
102
+ * 0 if unknown.
142
103
  *
143
- * Never set directly if the file_size and duration are known.
104
+ * Direct mapping to AVFormatContext->bit_rate.
144
105
  */
145
106
  get bitRate() {
146
107
  return this.native.bitRate;
147
108
  }
148
109
  /**
149
- * Flags modifying demuxer/muxer behavior.
110
+ * Format-specific flags.
150
111
  *
151
- * Direct mapping to AVFormatContext->flags
112
+ * Combination of AVFMT_FLAG_* values controlling
113
+ * format behavior (e.g., AVFMT_FLAG_GENPTS).
152
114
  *
153
- * AVFMT_FLAG_GENPTS, AVFMT_FLAG_IGNIDX, etc.
154
- * - encoding: Set by user
155
- * - decoding: Set by user
115
+ * Direct mapping to AVFormatContext->flags.
156
116
  */
157
117
  get flags() {
158
118
  return this.native.flags;
@@ -161,12 +121,12 @@ export class FormatContext extends OptionMember {
161
121
  this.native.flags = value;
162
122
  }
163
123
  /**
164
- * Maximum size of the data read from input for determining format.
124
+ * Maximum bytes to probe for format detection.
165
125
  *
166
- * Direct mapping to AVFormatContext->probesize
126
+ * Larger values improve format detection accuracy
127
+ * but increase startup time.
167
128
  *
168
- * - encoding: unused
169
- * - decoding: Set by user
129
+ * Direct mapping to AVFormatContext->probesize.
170
130
  */
171
131
  get probesize() {
172
132
  return this.native.probesize;
@@ -175,12 +135,12 @@ export class FormatContext extends OptionMember {
175
135
  this.native.probesize = value;
176
136
  }
177
137
  /**
178
- * Maximum duration (in AV_TIME_BASE units) of the data read from input.
138
+ * Maximum duration to analyze streams.
179
139
  *
180
- * Direct mapping to AVFormatContext->max_analyze_duration
140
+ * Time in microseconds to spend analyzing streams.
141
+ * Larger values improve stream detection accuracy.
181
142
  *
182
- * - encoding: unused
183
- * - decoding: Set by user
143
+ * Direct mapping to AVFormatContext->max_analyze_duration.
184
144
  */
185
145
  get maxAnalyzeDuration() {
186
146
  return this.native.maxAnalyzeDuration;
@@ -189,12 +149,11 @@ export class FormatContext extends OptionMember {
189
149
  this.native.maxAnalyzeDuration = value;
190
150
  }
191
151
  /**
192
- * Metadata that applies to the whole file.
152
+ * Container metadata.
193
153
  *
194
- * Direct mapping to AVFormatContext->metadata
154
+ * Key-value pairs of metadata (title, author, etc.).
195
155
  *
196
- * - demuxing: Set by libavformat
197
- * - muxing: May be set by user
156
+ * Direct mapping to AVFormatContext->metadata.
198
157
  */
199
158
  get metadata() {
200
159
  const nativeDict = this.native.metadata;
@@ -207,11 +166,11 @@ export class FormatContext extends OptionMember {
207
166
  this.native.metadata = value?.getNative() ?? null;
208
167
  }
209
168
  /**
210
- * Input format (demuxing only).
169
+ * Input format descriptor.
211
170
  *
212
- * Direct mapping to AVFormatContext->iformat
171
+ * Format used for demuxing. Null for output contexts.
213
172
  *
214
- * The detected or specified input format.
173
+ * Direct mapping to AVFormatContext->iformat.
215
174
  */
216
175
  get iformat() {
217
176
  const nativeFormat = this.native.iformat;
@@ -221,11 +180,11 @@ export class FormatContext extends OptionMember {
221
180
  return new InputFormat(nativeFormat);
222
181
  }
223
182
  /**
224
- * Output format (muxing only).
183
+ * Output format descriptor.
225
184
  *
226
- * Direct mapping to AVFormatContext->oformat
185
+ * Format used for muxing. Null for input contexts.
227
186
  *
228
- * The specified output format.
187
+ * Direct mapping to AVFormatContext->oformat.
229
188
  */
230
189
  get oformat() {
231
190
  const nativeFormat = this.native.oformat;
@@ -238,15 +197,11 @@ export class FormatContext extends OptionMember {
238
197
  this.native.oformat = value?.getNative() ?? null;
239
198
  }
240
199
  /**
241
- * I/O context.
200
+ * Custom I/O context.
242
201
  *
243
- * Direct mapping to AVFormatContext->pb
202
+ * For custom I/O operations instead of file I/O.
244
203
  *
245
- * - demuxing: Either set by user or internal (for protocols like file:)
246
- * - muxing: Set by user for custom I/O. Otherwise internal
247
- *
248
- * The FormatContext keeps track of the IOContext set by the user.
249
- * This prevents ownership confusion.
204
+ * Direct mapping to AVFormatContext->pb.
250
205
  */
251
206
  get pb() {
252
207
  return this._ioContext;
@@ -256,17 +211,19 @@ export class FormatContext extends OptionMember {
256
211
  this.native.pb = value?.getNative() ?? null;
257
212
  }
258
213
  /**
259
- * Number of streams in the file.
214
+ * Number of streams in the container.
260
215
  *
261
- * Direct mapping to AVFormatContext->nb_streams
216
+ * Direct mapping to AVFormatContext->nb_streams.
262
217
  */
263
218
  get nbStreams() {
264
219
  return this.native.nbStreams;
265
220
  }
266
221
  /**
267
- * Array of streams in the file.
222
+ * Array of streams in the container.
223
+ *
224
+ * All audio, video, subtitle, and data streams.
268
225
  *
269
- * Direct mapping to AVFormatContext->streams
226
+ * Direct mapping to AVFormatContext->streams.
270
227
  */
271
228
  get streams() {
272
229
  const nativeStreams = this.native.streams;
@@ -276,11 +233,12 @@ export class FormatContext extends OptionMember {
276
233
  return nativeStreams.map((nativeStream) => new Stream(nativeStream));
277
234
  }
278
235
  /**
279
- * Allow non-standard and experimental extension.
236
+ * Strictness level for standards compliance.
280
237
  *
281
- * Direct mapping to AVFormatContext->strict_std_compliance
238
+ * FF_COMPLIANCE_* value controlling how strictly
239
+ * to follow specifications.
282
240
  *
283
- * @see AVCodecContext.strict_std_compliance
241
+ * Direct mapping to AVFormatContext->strict_std_compliance.
284
242
  */
285
243
  get strictStdCompliance() {
286
244
  return this.native.strictStdCompliance;
@@ -291,10 +249,9 @@ export class FormatContext extends OptionMember {
291
249
  /**
292
250
  * Maximum number of streams.
293
251
  *
294
- * Direct mapping to AVFormatContext->max_streams
252
+ * Limit on stream count for security/resource reasons.
295
253
  *
296
- * - encoding: unused
297
- * - decoding: Set by user
254
+ * Direct mapping to AVFormatContext->max_streams.
298
255
  */
299
256
  get maxStreams() {
300
257
  return this.native.maxStreams;
@@ -303,77 +260,78 @@ export class FormatContext extends OptionMember {
303
260
  this.native.maxStreams = value;
304
261
  }
305
262
  /**
306
- * Number of programs in the stream.
263
+ * Number of programs.
307
264
  *
308
- * Direct mapping to AVFormatContext->nb_programs
265
+ * For containers with multiple programs (e.g., MPEG-TS).
309
266
  *
310
- * - demuxing: Set by libavformat
267
+ * Direct mapping to AVFormatContext->nb_programs.
311
268
  */
312
269
  get nbPrograms() {
313
270
  return this.native.nbPrograms;
314
271
  }
315
272
  /**
316
- * Current position in bytes (avio_tell).
317
- *
318
- * Direct mapping to avio_tell(AVFormatContext->pb)
273
+ * Number of bytes read/written through I/O context.
319
274
  *
320
- * Returns the current byte position in the I/O context.
321
- * - demuxing: Current read position
322
- * - muxing: Current write position
275
+ * Direct mapping to avio_tell(AVFormatContext->pb).
323
276
  */
324
277
  get pbBytes() {
325
278
  return this.native.pbBytes;
326
279
  }
327
280
  /**
328
- * Format probing score (0-100).
281
+ * Format probe score.
329
282
  *
330
- * Direct mapping to AVFormatContext->probe_score
283
+ * Confidence score from format detection (0-100).
284
+ * Higher values indicate more confident detection.
331
285
  *
332
- * Indicates confidence in format detection (higher is better).
333
- * - demuxing: Set by format probing
286
+ * Direct mapping to AVFormatContext->probe_score.
334
287
  */
335
288
  get probeScore() {
336
289
  return this.native.probeScore;
337
290
  }
338
291
  /**
339
- * Allocate an AVFormatContext for input.
292
+ * Allocate a format context.
340
293
  *
341
- * Direct mapping to avformat_alloc_context()
294
+ * Allocates the context structure. Usually not needed
295
+ * as openInput/allocOutputContext2 handle this.
296
+ *
297
+ * Direct mapping to avformat_alloc_context().
342
298
  *
343
299
  * @example
344
300
  * ```typescript
345
301
  * const ctx = new FormatContext();
346
302
  * ctx.allocContext();
347
- * // Context is now allocated for demuxing
303
+ * // Context is now allocated
348
304
  * ```
349
- *
350
- * @throws {Error} If allocation fails (ENOMEM)
351
305
  */
352
306
  allocContext() {
353
- return this.native.allocContext();
307
+ this.native.allocContext();
354
308
  }
355
309
  /**
356
- * Allocate an AVFormatContext for output.
310
+ * Allocate an output format context.
357
311
  *
358
- * Direct mapping to avformat_alloc_output_context2()
312
+ * Allocates and configures context for writing.
313
+ * Format is determined by parameters in priority order.
359
314
  *
360
- * @param oformat - Output format. May be null to auto-detect from filename
361
- * @param formatName - Format name. May be null to auto-detect
362
- * @param filename - Filename for output. Used to guess format if not specified
315
+ * Direct mapping to avformat_alloc_output_context2().
363
316
  *
317
+ * @param oformat - Specific output format to use
318
+ * @param formatName - Format name (e.g., 'mp4', 'mkv')
319
+ * @param filename - Filename to guess format from extension
364
320
  * @returns 0 on success, negative AVERROR on error:
365
- * - 0: Success
366
- * - AVERROR(EINVAL): Invalid arguments
367
- * - AVERROR(ENOMEM): Memory allocation failure
321
+ * - AVERROR_ENOMEM: Memory allocation failure
322
+ * - AVERROR_EINVAL: Invalid parameters
368
323
  *
369
324
  * @example
370
325
  * ```typescript
326
+ * import { FFmpegError } from 'node-av';
327
+ *
371
328
  * const ctx = new FormatContext();
372
329
  * const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4');
373
- * if (ret < 0) {
374
- * throw new FFmpegError(ret);
375
- * }
330
+ * FFmpegError.throwIfError(ret, 'allocOutputContext2');
376
331
  * ```
332
+ *
333
+ * @see {@link openOutput} To open output file
334
+ * @see {@link writeHeader} To write file header
377
335
  */
378
336
  allocOutputContext2(oformat, formatName, filename) {
379
337
  if (!oformat && !formatName && !filename) {
@@ -382,415 +340,392 @@ export class FormatContext extends OptionMember {
382
340
  return this.native.allocOutputContext2(oformat?.getNative() ?? null, formatName, filename);
383
341
  }
384
342
  /**
385
- * Free an AVFormatContext and all its streams.
343
+ * Free the format context.
344
+ *
345
+ * Releases all resources. The context becomes invalid.
386
346
  *
387
- * Direct mapping to avformat_free_context()
347
+ * Direct mapping to avformat_free_context().
388
348
  *
389
349
  * @example
390
350
  * ```typescript
391
351
  * ctx.freeContext();
392
- * // ctx is now invalid and should not be used
352
+ * // Context is now invalid
393
353
  * ```
354
+ *
355
+ * @see {@link Symbol.asyncDispose} For automatic cleanup
394
356
  */
395
357
  freeContext() {
396
- return this.native.freeContext();
358
+ this.native.freeContext();
397
359
  }
398
360
  /**
399
- * Close an opened input AVFormatContext.
361
+ * Close an input format context.
362
+ *
363
+ * Closes input file and releases resources.
364
+ *
365
+ * Direct mapping to avformat_close_input().
400
366
  *
401
- * Direct mapping to avformat_close_input()
367
+ * @returns Promise that resolves when closed
402
368
  *
403
369
  * @example
404
370
  * ```typescript
405
371
  * await ctx.closeInput();
406
- * // Input is closed and context is freed
372
+ * // Input closed and context freed
407
373
  * ```
374
+ *
375
+ * @see {@link openInput} To open input
408
376
  */
409
377
  async closeInput() {
410
- return this.native.closeInput();
378
+ return await this.native.closeInput();
411
379
  }
412
380
  /**
413
- * Open the output file for writing.
381
+ * Open output file for writing.
414
382
  *
415
- * Must be called after allocOutputContext2() and before writeHeader()
416
- * for file-based formats (not NOFILE formats).
383
+ * Opens the output file specified in url.
384
+ * Must call allocOutputContext2 first.
417
385
  *
418
- * Direct mapping to avio_open()
386
+ * Direct mapping to avio_open2().
419
387
  *
420
- * @returns Promise resolving to 0 on success, negative AVERROR on failure:
421
- * - 0: Success
422
- * - AVERROR(ENOENT): File cannot be created
423
- * - AVERROR(EACCES): Permission denied
424
- * - AVERROR(EIO): I/O error
388
+ * @returns 0 on success, negative AVERROR on error:
389
+ * - AVERROR_ENOENT: File not found
390
+ * - AVERROR_EACCES: Permission denied
391
+ * - AVERROR_EIO: I/O error
425
392
  *
426
393
  * @example
427
394
  * ```typescript
428
- * import { FormatContext, FFmpegError } from 'node-av';
395
+ * import { FFmpegError } from 'node-av';
429
396
  *
430
- * ctx.allocOutputContext2(null, null, 'output.mp4');
431
- * const ret = await ctx.openOutput(); // Opens the file for writing
397
+ * const ret = await ctx.openOutput();
432
398
  * FFmpegError.throwIfError(ret, 'openOutput');
433
- * await ctx.writeHeader(null);
434
399
  * ```
400
+ *
401
+ * @see {@link allocOutputContext2} Must be called first
402
+ * @see {@link closeOutput} To close output
435
403
  */
436
404
  async openOutput() {
437
- return this.native.openOutput();
405
+ return await this.native.openOutput();
438
406
  }
439
407
  /**
440
- * Close the output file.
408
+ * Close output file.
409
+ *
410
+ * Closes the output file and releases I/O resources.
441
411
  *
442
- * Direct mapping to avio_closep()
412
+ * Direct mapping to avio_closep().
443
413
  *
444
- * Should be called after writeTrailer() for file-based formats.
445
- * The file is automatically closed by freeContext() as well.
414
+ * @returns Promise that resolves when closed
446
415
  *
447
416
  * @example
448
417
  * ```typescript
449
- * await ctx.writeTrailer();
450
418
  * await ctx.closeOutput();
451
- * ctx.freeContext();
419
+ * // Output file closed
452
420
  * ```
421
+ *
422
+ * @see {@link openOutput} To open output
453
423
  */
454
424
  async closeOutput() {
455
- return this.native.closeOutput();
425
+ return await this.native.closeOutput();
456
426
  }
457
427
  /**
458
- * Open an input stream and read the header.
459
- *
460
- * Opens the specified URL, reads the format header, and initializes the stream information.
461
- * Automatically detects the format if not specified.
428
+ * Open input file for reading.
462
429
  *
463
- * Direct mapping to avformat_open_input()
430
+ * Opens and probes the input file, detecting format automatically
431
+ * unless specified.
464
432
  *
465
- * @param url - URL of the stream to open
466
- * @param fmt - Input format. May be null to auto-detect
467
- * @param options - Dictionary of options. May be null
433
+ * Direct mapping to avformat_open_input().
468
434
  *
435
+ * @param url - URL or file path to open
436
+ * @param fmt - Force specific input format (null for auto-detect)
437
+ * @param options - Format-specific options
469
438
  * @returns 0 on success, negative AVERROR on error:
470
- * - 0: Success
471
- * - AVERROR(ENOENT): File not found
472
- * - AVERROR(EIO): I/O error
473
- * - AVERROR(EINVAL): Invalid data found
474
- * - AVERROR(ENOMEM): Memory allocation failure
475
- * - <0: Other format-specific errors
439
+ * - AVERROR_ENOENT: File not found
440
+ * - AVERROR_INVALIDDATA: Invalid file format
441
+ * - AVERROR_EIO: I/O error
476
442
  *
477
443
  * @example
478
444
  * ```typescript
479
- * import { FormatContext, FFmpegError } from 'node-av';
445
+ * import { FFmpegError } from 'node-av';
480
446
  *
481
- * const ret = await ctx.openInput('video.mp4', null, null);
447
+ * const ret = await ctx.openInput('input.mp4');
482
448
  * FFmpegError.throwIfError(ret, 'openInput');
483
- * // Context is now open and header is read
484
449
  * ```
450
+ *
451
+ * @see {@link findStreamInfo} To analyze streams after opening
452
+ * @see {@link closeInput} To close input
485
453
  */
486
454
  async openInput(url, fmt = null, options = null) {
487
- return this.native.openInput(url, fmt?.getNative() ?? null, options?.getNative() ?? null);
455
+ return await this.native.openInput(url, fmt?.getNative() ?? null, options?.getNative() ?? null);
488
456
  }
489
457
  /**
490
- * Read packets of a media file to get stream information.
458
+ * Analyze streams to get stream info.
491
459
  *
492
- * Analyzes the media file by reading packets to determine stream parameters
493
- * like codec, dimensions, sample rate, etc. Required after openInput().
460
+ * Reads packet headers to fill in stream information.
461
+ * Should be called after openInput for accurate stream data.
494
462
  *
495
- * Direct mapping to avformat_find_stream_info()
496
- *
497
- * @param options - Dictionary of options per stream. May be null
463
+ * Direct mapping to avformat_find_stream_info().
498
464
  *
465
+ * @param options - Per-stream options array
499
466
  * @returns >=0 on success, negative AVERROR on error:
500
- * - >=0: Success (number of stream info found)
501
- * - AVERROR(EIO): I/O error
502
- * - AVERROR(ENOMEM): Memory allocation failure
503
- * - <0: Other errors
467
+ * - AVERROR_EOF: End of file reached
468
+ * - AVERROR_ENOMEM: Memory allocation failure
504
469
  *
505
470
  * @example
506
471
  * ```typescript
507
- * import { FormatContext, FFmpegError } from 'node-av';
472
+ * import { FFmpegError } from 'node-av';
508
473
  *
509
- * const ret = await ctx.findStreamInfo(null);
474
+ * const ret = await ctx.findStreamInfo();
510
475
  * FFmpegError.throwIfError(ret, 'findStreamInfo');
511
476
  * console.log(`Found ${ctx.nbStreams} streams`);
512
477
  * ```
478
+ *
479
+ * @see {@link openInput} Must be called first
513
480
  */
514
481
  async findStreamInfo(options = null) {
515
- return this.native.findStreamInfo(options?.map((d) => d.getNative()) ?? null);
482
+ return await this.native.findStreamInfo(options?.map((d) => d.getNative()) ?? null);
516
483
  }
517
484
  /**
518
- * Read the next packet in the file.
485
+ * Read next packet from the input.
519
486
  *
520
- * Reads and returns the next packet from the input file.
521
- * Packets must be unreferenced after use to free memory.
487
+ * Reads and returns the next packet in the stream.
488
+ * Packet must be unreferenced after use.
522
489
  *
523
- * Direct mapping to av_read_frame()
524
- *
525
- * @param pkt - Packet to fill with data
490
+ * Direct mapping to av_read_frame().
526
491
  *
492
+ * @param pkt - Packet to read into
527
493
  * @returns 0 on success, negative AVERROR on error:
528
- * - 0: Success
529
- * - AVERROR_EOF: End of file reached
530
- * - AVERROR(EAGAIN): Temporarily unavailable
531
- * - AVERROR(EIO): I/O error
532
- * - <0: Other errors
494
+ * - AVERROR_EOF: End of file
495
+ * - AVERROR_EAGAIN: Temporarily unavailable
533
496
  *
534
497
  * @example
535
498
  * ```typescript
536
- * import { Packet, FormatContext, FFmpegError, AVERROR_EOF } from 'node-av';
499
+ * import { FFmpegError } from 'node-av';
500
+ * import { AVERROR_EOF } from 'node-av';
537
501
  *
538
502
  * const packet = new Packet();
539
503
  * packet.alloc();
540
504
  *
541
- * while (true) {
542
- * const ret = await ctx.readFrame(packet);
543
- * if (ret === AVERROR_EOF) break;
544
- * FFmpegError.throwIfError(ret, 'readFrame');
545
- *
505
+ * let ret;
506
+ * while ((ret = await ctx.readFrame(packet)) >= 0) {
546
507
  * // Process packet
547
508
  * console.log(`Stream ${packet.streamIndex}, PTS: ${packet.pts}`);
548
509
  * packet.unref();
549
510
  * }
511
+ *
512
+ * if (ret !== AVERROR_EOF) {
513
+ * FFmpegError.throwIfError(ret, 'readFrame');
514
+ * }
550
515
  * ```
516
+ *
517
+ * @see {@link seekFrame} To seek before reading
551
518
  */
552
519
  async readFrame(pkt) {
553
- return this.native.readFrame(pkt.getNative());
520
+ return await this.native.readFrame(pkt.getNative());
554
521
  }
555
522
  /**
556
- * Seek to the keyframe at timestamp.
557
- *
558
- * Seeks to the keyframe at or before the specified timestamp.
559
- * The next packet read will be from the new position.
523
+ * Seek to timestamp in stream.
560
524
  *
561
- * Direct mapping to av_seek_frame()
525
+ * Seeks to the keyframe at or before the given timestamp.
562
526
  *
563
- * @param streamIndex - Stream index or -1 for default
564
- * @param timestamp - Timestamp in stream time_base units or AV_TIME_BASE if stream_index is -1
565
- * @param flags - AVSEEK_FLAG_* flags
527
+ * Direct mapping to av_seek_frame().
566
528
  *
529
+ * @param streamIndex - Stream to seek in (-1 for default)
530
+ * @param timestamp - Target timestamp in stream time base
531
+ * @param flags - Seek flags (AVSEEK_FLAG_*)
567
532
  * @returns >=0 on success, negative AVERROR on error:
568
- * - >=0: Success
569
- * - AVERROR(EINVAL): Invalid arguments
570
- * - AVERROR(EIO): I/O error
571
- * - <0: Other errors
533
+ * - AVERROR_EINVAL: Invalid parameters
534
+ * - AVERROR_EOF: Seek beyond file
572
535
  *
573
536
  * @example
574
537
  * ```typescript
575
- * import { FormatContext, FFmpegError, AV_TIME_BASE, AVSEEK_FLAG_BACKWARD } from 'node-av';
538
+ * import { FFmpegError } from 'node-av';
539
+ * import { AVSEEK_FLAG_BACKWARD } from 'node-av/constants';
576
540
  *
577
- * // Seek to 10 seconds
578
- * const timestamp = 10n * BigInt(AV_TIME_BASE);
579
- * const ret = await ctx.seekFrame(-1, timestamp, AVSEEK_FLAG_BACKWARD);
541
+ * // Seek to 10 seconds (assuming 1/1000 time base)
542
+ * const ret = await ctx.seekFrame(videoStreamIndex, 10000n, AVSEEK_FLAG_BACKWARD);
580
543
  * FFmpegError.throwIfError(ret, 'seekFrame');
581
- * // Next readFrame will return packet from new position
582
544
  * ```
545
+ *
546
+ * @see {@link seekFile} For more precise seeking
583
547
  */
584
548
  async seekFrame(streamIndex, timestamp, flags = AVFLAG_NONE) {
585
- return this.native.seekFrame(streamIndex, timestamp, flags);
549
+ return await this.native.seekFrame(streamIndex, timestamp, flags);
586
550
  }
587
551
  /**
588
- * Seek to timestamp ts with more control.
552
+ * Seek to timestamp with bounds.
589
553
  *
590
- * Seeks to a timestamp within the specified min/max range.
591
- * More precise than seekFrame() with tolerance control.
554
+ * More precise seeking with min/max timestamp bounds.
592
555
  *
593
- * Direct mapping to avformat_seek_file()
556
+ * Direct mapping to avformat_seek_file().
594
557
  *
595
- * @param streamIndex - Stream index or -1 for default
596
- * @param minTs - Smallest acceptable timestamp
558
+ * @param streamIndex - Stream to seek in (-1 for default)
559
+ * @param minTs - Minimum acceptable timestamp
597
560
  * @param ts - Target timestamp
598
- * @param maxTs - Largest acceptable timestamp
599
- * @param flags - AVSEEK_FLAG_* flags
600
- *
601
- * @returns >=0 on success, negative AVERROR on error:
602
- * - >=0: Success
603
- * - AVERROR(EINVAL): Invalid arguments
604
- * - AVERROR(EIO): I/O error
605
- * - <0: Other errors
561
+ * @param maxTs - Maximum acceptable timestamp
562
+ * @param flags - Seek flags
563
+ * @returns >=0 on success, negative AVERROR on error
606
564
  *
607
565
  * @example
608
566
  * ```typescript
609
- * import { FormatContext, FFmpegError, AV_TIME_BASE } from 'node-av';
567
+ * import { FFmpegError } from 'node-av';
610
568
  *
611
- * // Seek to timestamp with tolerance
612
- * const target = 10n * BigInt(AV_TIME_BASE);
613
- * const tolerance = BigInt(AV_TIME_BASE);
569
+ * // Seek to 10s with 0.5s tolerance
570
+ * const target = 10000n;
614
571
  * const ret = await ctx.seekFile(
615
572
  * -1,
616
- * target - tolerance, // min: 9 seconds
617
- * target, // target: 10 seconds
618
- * target + tolerance, // max: 11 seconds
619
- * 0
573
+ * target - 500n,
574
+ * target,
575
+ * target + 500n
620
576
  * );
621
577
  * FFmpegError.throwIfError(ret, 'seekFile');
622
578
  * ```
579
+ *
580
+ * @see {@link seekFrame} For simpler seeking
623
581
  */
624
582
  async seekFile(streamIndex, minTs, ts, maxTs, flags = AVFLAG_NONE) {
625
- return this.native.seekFile(streamIndex, minTs, ts, maxTs, flags);
583
+ return await this.native.seekFile(streamIndex, minTs, ts, maxTs, flags);
626
584
  }
627
585
  /**
628
- * Allocate the stream private data and write the stream header.
629
- *
630
- * Initializes the output file and writes the file header.
631
- * Must be called before writing any packets.
586
+ * Write file header.
632
587
  *
633
- * Direct mapping to avformat_write_header()
588
+ * Writes the file header and initializes output.
589
+ * Must be called before writing packets.
634
590
  *
635
- * @param options - Dictionary of options. May be null
591
+ * Direct mapping to avformat_write_header().
636
592
  *
593
+ * @param options - Muxer-specific options
637
594
  * @returns 0 on success, negative AVERROR on error:
638
- * - 0: Success
639
- * - AVERROR(EINVAL): Invalid parameters
640
- * - AVERROR(EIO): I/O error
641
- * - AVERROR(ENOMEM): Memory allocation failure
642
- * - <0: Other muxer-specific errors
595
+ * - AVERROR_EINVAL: Invalid parameters
596
+ * - AVERROR_EIO: I/O error
643
597
  *
644
598
  * @example
645
599
  * ```typescript
646
- * import { Dictionary, FormatContext, FFmpegError } from 'node-av';
647
- *
648
- * const options = new Dictionary();
649
- * options.set('movflags', 'faststart', 0);
600
+ * import { FFmpegError } from 'node-av';
650
601
  *
651
- * const ret = await ctx.writeHeader(options);
602
+ * const ret = await ctx.writeHeader();
652
603
  * FFmpegError.throwIfError(ret, 'writeHeader');
653
- * options.free();
654
- * // Header written, ready to write packets
604
+ * // Now ready to write packets
655
605
  * ```
606
+ *
607
+ * @see {@link writeTrailer} To finalize file
608
+ * @see {@link writeFrame} To write packets
656
609
  */
657
610
  async writeHeader(options = null) {
658
- return this.native.writeHeader(options?.getNative() ?? null);
611
+ return await this.native.writeHeader(options?.getNative() ?? null);
659
612
  }
660
613
  /**
661
- * Write a packet to an output media file.
662
- *
663
- * Writes a packet directly without reordering.
664
- * Use interleavedWriteFrame() for automatic interleaving.
614
+ * Write packet to output.
665
615
  *
666
- * Direct mapping to av_write_frame()
616
+ * Writes a packet directly without interleaving.
617
+ * Caller must handle correct interleaving.
667
618
  *
668
- * @param pkt - Packet to write. May be null to flush
619
+ * Direct mapping to av_write_frame().
669
620
  *
621
+ * @param pkt - Packet to write (null to flush)
670
622
  * @returns 0 on success, negative AVERROR on error:
671
- * - 0: Success
672
- * - AVERROR(EINVAL): Invalid packet
673
- * - AVERROR(EIO): I/O error
674
- * - <0: Other muxer-specific errors
623
+ * - AVERROR_EINVAL: Invalid packet
624
+ * - AVERROR_EIO: I/O error
675
625
  *
676
626
  * @example
677
627
  * ```typescript
678
- * import { FormatContext, FFmpegError } from 'node-av';
628
+ * import { FFmpegError } from 'node-av';
679
629
  *
680
630
  * const ret = await ctx.writeFrame(packet);
681
631
  * FFmpegError.throwIfError(ret, 'writeFrame');
682
- *
683
- * // Flush at the end
684
- * const flushRet = await ctx.writeFrame(null);
685
- * FFmpegError.throwIfError(flushRet, 'writeFrame flush');
686
632
  * ```
687
633
  *
688
- * @note This function does NOT take ownership of the packet.
689
- *
690
634
  * @see {@link interleavedWriteFrame} For automatic interleaving
691
635
  */
692
636
  async writeFrame(pkt) {
693
- return this.native.writeFrame(pkt ? pkt.getNative() : null);
637
+ return await this.native.writeFrame(pkt ? pkt.getNative() : null);
694
638
  }
695
639
  /**
696
- * Write a packet to an output media file ensuring correct interleaving.
697
- *
698
- * Automatically interleaves packets from different streams based on DTS.
699
- * Preferred method for writing packets in most cases.
640
+ * Write packet with automatic interleaving.
700
641
  *
701
- * Direct mapping to av_interleaved_write_frame()
642
+ * Writes packet with proper interleaving for muxing.
643
+ * Preferred method for writing packets.
702
644
  *
703
- * @param pkt - Packet to write. May be null to flush
645
+ * Direct mapping to av_interleaved_write_frame().
704
646
  *
647
+ * @param pkt - Packet to write (null to flush)
705
648
  * @returns 0 on success, negative AVERROR on error:
706
- * - 0: Success
707
- * - AVERROR(EINVAL): Invalid packet
708
- * - AVERROR(EIO): I/O error
709
- * - <0: Other muxer-specific errors
649
+ * - AVERROR_EINVAL: Invalid packet
650
+ * - AVERROR_EIO: I/O error
710
651
  *
711
652
  * @example
712
653
  * ```typescript
713
- * import { FormatContext, FFmpegError } from 'node-av';
654
+ * import { FFmpegError } from 'node-av';
714
655
  *
715
- * // Write packets with automatic interleaving
656
+ * // Write with proper interleaving
716
657
  * const ret = await ctx.interleavedWriteFrame(packet);
717
658
  * FFmpegError.throwIfError(ret, 'interleavedWriteFrame');
718
- * // Packet is automatically freed after writing
719
- * ```
720
659
  *
721
- * @note This function TAKES OWNERSHIP of the packet and will free it.
660
+ * // Flush buffered packets
661
+ * await ctx.interleavedWriteFrame(null);
662
+ * ```
722
663
  *
723
- * @see {@link writeFrame} For manual interleaving control
664
+ * @see {@link writeFrame} For direct writing
724
665
  */
725
666
  async interleavedWriteFrame(pkt) {
726
- return this.native.interleavedWriteFrame(pkt ? pkt.getNative() : null);
667
+ return await this.native.interleavedWriteFrame(pkt ? pkt.getNative() : null);
727
668
  }
728
669
  /**
729
- * Write the stream trailer to an output media file.
670
+ * Write file trailer.
730
671
  *
731
- * Finalizes the output file by writing the trailer.
732
- * Must be called after all packets have been written.
672
+ * Finalizes the output file, writing index and metadata.
673
+ * Must be called to properly close output files.
733
674
  *
734
- * Direct mapping to av_write_trailer()
675
+ * Direct mapping to av_write_trailer().
735
676
  *
736
677
  * @returns 0 on success, negative AVERROR on error:
737
- * - 0: Success
738
- * - AVERROR(EIO): I/O error
739
- * - <0: Other muxer-specific errors
678
+ * - AVERROR_EIO: I/O error
740
679
  *
741
680
  * @example
742
681
  * ```typescript
743
- * import { FormatContext, FFmpegError } from 'node-av';
682
+ * import { FFmpegError } from 'node-av';
744
683
  *
745
- * // Finalize the output file
746
684
  * const ret = await ctx.writeTrailer();
747
685
  * FFmpegError.throwIfError(ret, 'writeTrailer');
748
- * // File is now complete and finalized
686
+ * // File is now finalized
749
687
  * ```
750
688
  *
751
- * @note Must be called after all packets have been written.
689
+ * @see {@link writeHeader} Must be called first
752
690
  */
753
691
  async writeTrailer() {
754
- return this.native.writeTrailer();
692
+ return await this.native.writeTrailer();
755
693
  }
756
694
  /**
757
- * Flush any buffered data to the output.
695
+ * Flush buffered data.
758
696
  *
759
- * Direct mapping to avio_flush()
697
+ * Flushes any buffered packets in muxers.
698
+ *
699
+ * Direct mapping to avio_flush().
760
700
  *
761
701
  * @example
762
702
  * ```typescript
763
- * import { FormatContext } from 'node-av';
764
- *
765
- * // Flush buffered data
766
703
  * ctx.flush();
767
- * // All buffered data written to output
704
+ * // Buffered data written to output
768
705
  * ```
769
706
  */
770
707
  flush() {
771
- return this.native.flush();
708
+ this.native.flush();
772
709
  }
773
710
  /**
774
- * Dump format information to stderr.
711
+ * Print format information.
775
712
  *
776
- * Prints detailed information about the format and streams to stderr.
777
- * Useful for debugging and understanding file structure.
713
+ * Dumps human-readable format info to stderr.
714
+ * Useful for debugging.
778
715
  *
779
- * Direct mapping to av_dump_format()
716
+ * Direct mapping to av_dump_format().
780
717
  *
781
- * @param index - Stream index or program index to dump
782
- * @param url - URL or filename to display
783
- * @param isOutput - true for output format, false for input format
718
+ * @param index - Stream index to highlight (-1 for none)
719
+ * @param url - URL to display
720
+ * @param isOutput - True for output format, false for input
784
721
  *
785
722
  * @example
786
723
  * ```typescript
787
- * import { FormatContext } from 'node-av';
788
- *
789
724
  * // Dump input format info
790
- * formatCtx.dumpFormat(0, 'input.mp4', false);
725
+ * ctx.dumpFormat(0, 'input.mp4', false);
791
726
  *
792
727
  * // Dump output format info
793
- * formatCtx.dumpFormat(0, 'output.mp4', true);
728
+ * ctx.dumpFormat(0, 'output.mp4', true);
794
729
  * ```
795
730
  */
796
731
  dumpFormat(index, url, isOutput) {
@@ -812,63 +747,56 @@ export class FormatContext extends OptionMember {
812
747
  return this.native.findBestStream(type, wantedStreamNb, relatedStream, false, flags ?? 0);
813
748
  }
814
749
  /**
815
- * Add a new stream to the media file.
816
- *
817
- * Creates a new stream in the output format context.
818
- * The stream must be configured before calling writeHeader().
819
- *
820
- * Direct mapping to avformat_new_stream()
750
+ * Add a new stream to output context.
821
751
  *
822
- * @param c - Codec to use for the stream. May be null
752
+ * Creates a new stream for writing.
823
753
  *
824
- * @returns The newly created stream
754
+ * Direct mapping to avformat_new_stream().
825
755
  *
826
- * @throws {Error} If stream creation fails (ENOMEM)
756
+ * @param c - Codec for the stream (optional)
757
+ * @returns New stream instance
827
758
  *
828
759
  * @example
829
760
  * ```typescript
830
- * import { FormatContext, Codec, FFmpegError } from 'node-av';
831
- * import { AV_CODEC_ID_H264, AVMEDIA_TYPE_VIDEO } from 'node-av/constants';
832
- *
833
- * // Add a video stream
834
- * const videoCodec = Codec.findEncoder(AV_CODEC_ID_H264);
835
- * const videoStream = ctx.newStream(videoCodec);
836
- *
837
- * // Configure stream parameters
838
- * videoStream.codecpar.codecType = AVMEDIA_TYPE_VIDEO;
839
- * videoStream.codecpar.codecId = AV_CODEC_ID_H264;
840
- * videoStream.codecpar.width = 1920;
841
- * videoStream.codecpar.height = 1080;
761
+ * import { Codec } from 'node-av';
762
+ * import { AV_CODEC_ID_H264 } from 'node-av/constants';
763
+ *
764
+ * const codec = Codec.findEncoder(AV_CODEC_ID_H264);
765
+ * const stream = ctx.newStream(codec);
766
+ * stream.id = ctx.nbStreams - 1;
842
767
  * ```
768
+ *
769
+ * @see {@link Stream} For stream configuration
843
770
  */
844
771
  newStream(c = null) {
845
772
  const nativeStream = this.native.newStream(c?.getNative() ?? null);
846
773
  return new Stream(nativeStream);
847
774
  }
848
775
  /**
849
- * Get the native FFmpeg AVFormatContext pointer.
776
+ * Get the underlying native FormatContext object.
777
+ *
778
+ * @returns The native FormatContext binding object
850
779
  *
851
- * @internal For use by other wrapper classes
852
- * @returns The underlying native format context object
780
+ * @internal
853
781
  */
854
782
  getNative() {
855
783
  return this.native;
856
784
  }
857
785
  /**
858
- * Dispose of the format context asynchronously.
786
+ * Dispose of the format context.
859
787
  *
860
788
  * Implements the AsyncDisposable interface for automatic cleanup.
861
- * Properly handles network connections and I/O operations.
789
+ * Closes input/output and frees resources.
790
+ *
791
+ * @returns Promise that resolves when disposed
862
792
  *
863
793
  * @example
864
794
  * ```typescript
865
- * import { FormatContext } from 'node-av';
866
- *
867
795
  * {
868
796
  * await using ctx = new FormatContext();
869
- * await ctx.openInput('rtsp://camera/stream');
870
- * // ... use context
871
- * } // Automatically closed when leaving scope
797
+ * await ctx.openInput('input.mp4');
798
+ * // Use context...
799
+ * } // Automatically closed and freed
872
800
  * ```
873
801
  */
874
802
  async [Symbol.asyncDispose]() {