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
@@ -4,92 +4,83 @@ import { OptionMember } from './option.js';
4
4
  /**
5
5
  * I/O context for custom input/output operations.
6
6
  *
7
- * Provides buffered I/O and protocol handling for reading/writing data
8
- * from/to files, network streams, memory buffers, or custom sources.
9
- * Can be used with FormatContext for custom I/O or standalone for direct I/O operations.
7
+ * Provides an abstraction layer for all I/O operations in FFmpeg.
8
+ * Enables reading from and writing to various sources including files,
9
+ * network streams, memory buffers, and custom callbacks. Essential for
10
+ * implementing custom protocols or handling non-standard I/O scenarios.
10
11
  *
11
12
  * Direct mapping to FFmpeg's AVIOContext.
12
13
  *
13
14
  * @example
14
15
  * ```typescript
15
16
  * import { IOContext, FFmpegError } from 'node-av';
16
- * import { AVIO_FLAG_READ, AVSEEK_SET } from 'node-av/constants';
17
+ * import { AVIO_FLAG_READ, AVIO_FLAG_WRITE, AVSEEK_SET } from 'node-av/constants';
17
18
  *
18
- * // Open a file for reading
19
+ * // Open file for reading
19
20
  * const io = new IOContext();
20
21
  * const ret = await io.open2('input.mp4', AVIO_FLAG_READ);
21
22
  * FFmpegError.throwIfError(ret, 'open2');
22
23
  *
23
24
  * // Read data
24
- * const buffer = await io.read(4096);
25
+ * const data = await io.read(4096);
26
+ * if (data instanceof Buffer) {
27
+ * console.log(`Read ${data.length} bytes`);
28
+ * }
25
29
  *
26
30
  * // Seek to position
27
- * const seekRet = await io.seek(1024n, AVSEEK_SET);
28
- * FFmpegError.throwIfError(seekRet < 0 ? -1 : 0, 'seek');
31
+ * const pos = await io.seek(1024n, AVSEEK_SET);
32
+ * console.log(`Seeked to position ${pos}`);
29
33
  *
30
34
  * // Get file size
31
- * const size = await io.size();
35
+ * const fileSize = await io.size();
36
+ * console.log(`File size: ${fileSize}`);
32
37
  *
33
- * // Clean up
38
+ * // Close when done
34
39
  * await io.closep();
35
- * ```
36
40
  *
37
- * @example
38
- * ```typescript
39
41
  * // Custom I/O with callbacks
40
- * const io = new IOContext();
41
- * io.allocContextWithCallbacks(
42
- * 4096, // buffer size
43
- * 0, // read mode
44
- * (size) => { // custom read function
45
- * return myBuffer.slice(pos, pos + size);
42
+ * const customIO = new IOContext();
43
+ * let position = 0n;
44
+ * const buffer = Buffer.from('Hello World');
45
+ *
46
+ * customIO.allocContextWithCallbacks(
47
+ * 4096, // Buffer size
48
+ * 0, // Read mode
49
+ * (size) => {
50
+ * // Read callback
51
+ * const end = Number(position) + size;
52
+ * const chunk = buffer.subarray(Number(position), end);
53
+ * position = BigInt(end);
54
+ * return chunk;
46
55
  * },
47
- * null, // no write
48
- * (offset, whence) => { // custom seek function
49
- * return BigInt(calculateNewPosition(offset, whence));
56
+ * null, // No write callback for read mode
57
+ * (offset, whence) => {
58
+ * // Seek callback
59
+ * if (whence === AVSEEK_SET) position = offset;
60
+ * else if (whence === AVSEEK_CUR) position += offset;
61
+ * else if (whence === AVSEEK_END) position = BigInt(buffer.length) + offset;
62
+ * return position;
50
63
  * }
51
64
  * );
52
- *
53
- * // Use with FormatContext
54
- * const ctx = new FormatContext();
55
- * ctx.allocOutputContext2(null, 'mp4', null);
56
- * ctx.pb = io;
57
- * const openRet = await ctx.openInput(null, null, null);
58
- * FFmpegError.throwIfError(openRet, 'openInput');
59
65
  * ```
60
66
  *
61
- * @see {@link FormatContext} For using custom I/O with containers
67
+ * @see [AVIOContext](https://ffmpeg.org/doxygen/trunk/structAVIOContext.html) - FFmpeg Doxygen
68
+ * @see {@link FormatContext} For using with demuxing/muxing
62
69
  */
63
70
  export class IOContext extends OptionMember {
64
- /**
65
- * Create a new I/O context instance.
66
- *
67
- * The context is uninitialized - you must call allocContext() or open2() before use.
68
- * No FFmpeg resources are allocated until initialization.
69
- *
70
- * Direct wrapper around AVIOContext allocation.
71
- *
72
- * @example
73
- * ```typescript
74
- * import { IOContext, FFmpegError, AVIO_FLAG_READ } from 'node-av';
75
- *
76
- * const io = new IOContext();
77
- * const ret = await io.open2('file.mp4', AVIO_FLAG_READ);
78
- * FFmpegError.throwIfError(ret, 'open2');
79
- * // I/O context is now ready for use
80
- * ```
81
- */
82
71
  constructor() {
83
72
  super(new bindings.IOContext());
84
73
  }
85
74
  /**
86
- * Create an IOContext wrapper from a native IOContext.
75
+ * Find input format by short name.
87
76
  *
88
- * Used internally when getting IOContext from other objects.
89
- * @internal
77
+ * Creates an IOContext instance from a native binding object.
78
+ * Used internally for wrapping native I/O contexts.
90
79
  *
91
- * @param native - Native IOContext to wrap
80
+ * @param native - Native IOContext binding object
92
81
  * @returns Wrapped IOContext instance
82
+ *
83
+ * @internal
93
84
  */
94
85
  static fromNative(native) {
95
86
  const io = Object.create(IOContext.prototype);
@@ -97,32 +88,32 @@ export class IOContext extends OptionMember {
97
88
  return io;
98
89
  }
99
90
  /**
100
- * Check if end of file reached.
91
+ * End of file indicator.
101
92
  *
102
- * Direct mapping to avio_feof()
93
+ * True if end of file has been reached during reading.
103
94
  *
104
- * @readonly
95
+ * Direct mapping to AVIOContext->eof_reached.
105
96
  */
106
97
  get eof() {
107
98
  return this.native.eof;
108
99
  }
109
100
  /**
110
- * Error code if any.
101
+ * Error code.
111
102
  *
112
- * Direct mapping to AVIOContext->error
103
+ * Contains the last error that occurred, or 0 if no error.
113
104
  *
114
- * @readonly
105
+ * Direct mapping to AVIOContext->error.
115
106
  */
116
107
  get error() {
117
108
  return this.native.error;
118
109
  }
119
110
  /**
120
- * Whether seeking is possible.
111
+ * Seekability indicator.
121
112
  *
122
- * Direct mapping to AVIOContext->seekable
113
+ * Non-zero if the underlying resource supports seeking.
114
+ * Some protocols like pipes or network streams may not be seekable.
123
115
  *
124
- * Bitmask of AVIO_SEEKABLE_* flags.
125
- * @readonly
116
+ * Direct mapping to AVIOContext->seekable.
126
117
  */
127
118
  get seekable() {
128
119
  return this.native.seekable;
@@ -130,9 +121,10 @@ export class IOContext extends OptionMember {
130
121
  /**
131
122
  * Maximum packet size.
132
123
  *
133
- * Direct mapping to AVIOContext->max_packet_size
124
+ * Used to limit packet sizes in network protocols.
125
+ * 0 means no limit.
134
126
  *
135
- * If non-zero, indicates the maximum packet size.
127
+ * Direct mapping to AVIOContext->max_packet_size.
136
128
  */
137
129
  get maxPacketSize() {
138
130
  return this.native.maxPacketSize;
@@ -141,13 +133,11 @@ export class IOContext extends OptionMember {
141
133
  this.native.maxPacketSize = value;
142
134
  }
143
135
  /**
144
- * Whether direct mode is enabled.
136
+ * Direct mode flag.
145
137
  *
146
- * Direct mapping to AVIOContext->direct
138
+ * If set, the I/O context will attempt to avoid buffering.
147
139
  *
148
- * avio_read and avio_write should if possible be satisfied directly
149
- * instead of going through a buffer, and avio_seek will always call
150
- * the underlying seek function directly.
140
+ * Direct mapping to AVIOContext->direct.
151
141
  */
152
142
  get direct() {
153
143
  return this.native.direct;
@@ -156,390 +146,368 @@ export class IOContext extends OptionMember {
156
146
  this.native.direct = value;
157
147
  }
158
148
  /**
159
- * Get current position in the file.
149
+ * Current position.
160
150
  *
161
- * Direct mapping to AVIOContext->pos
151
+ * Current byte position in the stream.
162
152
  *
163
- * @readonly
153
+ * Direct mapping to AVIOContext->pos.
164
154
  */
165
155
  get pos() {
166
156
  return this.native.pos;
167
157
  }
168
158
  /**
169
- * Get buffer size.
159
+ * Internal buffer size.
170
160
  *
171
- * Direct mapping to AVIOContext->buffer_size
161
+ * Size of the internal buffer used for I/O operations.
172
162
  *
173
- * @readonly
163
+ * Direct mapping to AVIOContext->buffer_size.
174
164
  */
175
165
  get bufferSize() {
176
166
  return this.native.bufferSize;
177
167
  }
178
168
  /**
179
- * Check if opened for writing.
169
+ * Write flag.
180
170
  *
181
- * Direct mapping to AVIOContext->write_flag
171
+ * True if opened for writing, false for reading.
182
172
  *
183
- * @readonly
173
+ * Direct mapping to AVIOContext->write_flag.
184
174
  */
185
175
  get writeFlag() {
186
176
  return this.native.writeFlag;
187
177
  }
188
178
  /**
189
- * Create and initialize a buffered I/O context.
179
+ * Allocate I/O context with buffer.
190
180
  *
191
- * Allocates an I/O context with an internal buffer for efficient I/O operations.
192
- * For file I/O, use open2() instead which handles allocation automatically.
181
+ * Allocates a basic I/O context with an internal buffer.
182
+ * For custom I/O, use allocContextWithCallbacks instead.
193
183
  *
194
- * Direct mapping to avio_alloc_context()
184
+ * Direct mapping to avio_alloc_context() without callbacks.
195
185
  *
196
- * @param bufferSize - Size of the internal buffer in bytes
197
- * @param writeFlag - 1 for writing, 0 for reading
186
+ * @param bufferSize - Size of internal buffer
187
+ * @param writeFlag - 1 for write, 0 for read
198
188
  *
199
189
  * @example
200
190
  * ```typescript
201
- * import { IOContext } from 'node-av';
202
- *
203
191
  * const io = new IOContext();
204
192
  * io.allocContext(4096, 0); // 4KB buffer for reading
205
- *
206
- * // For writing
207
- * const writeIO = new IOContext();
208
- * writeIO.allocContext(8192, 1); // 8KB buffer for writing
209
193
  * ```
210
194
  *
211
- * @see {@link allocContextWithCallbacks} For custom I/O callbacks
212
- * @see {@link open2} For file I/O
195
+ * @see {@link allocContextWithCallbacks} For custom I/O
213
196
  */
214
197
  allocContext(bufferSize, writeFlag) {
215
- return this.native.allocContext(bufferSize, writeFlag);
198
+ this.native.allocContext(bufferSize, writeFlag);
216
199
  }
217
200
  /**
218
- * Allocate an AVIOContext with custom callbacks.
201
+ * Allocate I/O context with custom callbacks.
219
202
  *
220
- * Creates a custom I/O context with JavaScript callbacks for read, write, and seek operations.
203
+ * Creates an I/O context with custom read, write, and seek callbacks.
204
+ * Enables implementing custom protocols or data sources.
221
205
  *
222
- * IMPORTANT: Callbacks must be synchronous! They are called from FFmpeg's thread and must
223
- * return immediately. If you need async operations, buffer the data in JavaScript first.
206
+ * Direct mapping to avio_alloc_context() with callbacks.
224
207
  *
225
- * Direct mapping to avio_alloc_context() with custom callbacks
226
- *
227
- * @param bufferSize - Size of the buffer in bytes
228
- * @param writeFlag - 0 for read, 1 for write
229
- * @param readCallback - Synchronous callback for reading data. Returns Buffer, null for EOF, or negative error code
230
- * @param writeCallback - Synchronous callback for writing data. Returns bytes written or negative error code
231
- * @param seekCallback - Synchronous callback for seeking. Returns new position or negative error code
208
+ * @param bufferSize - Size of internal buffer
209
+ * @param writeFlag - 1 for write mode, 0 for read mode
210
+ * @param readCallback - Function to read data (null for write-only)
211
+ * @param writeCallback - Function to write data (null for read-only)
212
+ * @param seekCallback - Function to seek in stream (optional)
232
213
  *
233
214
  * @example
234
215
  * ```typescript
235
- * import { IOContext, AVSEEK_SET, AVSEEK_CUR, AVSEEK_END } from 'node-av';
216
+ * import { AVSEEK_SET, AVSEEK_CUR, AVSEEK_END, AVSEEK_SIZE } from 'node-av/constants';
236
217
  *
237
- * const io = new IOContext();
218
+ * const data = Buffer.from('Custom data source');
238
219
  * let position = 0;
239
- * const buffer = Buffer.from('example data');
240
220
  *
241
221
  * io.allocContextWithCallbacks(
242
222
  * 4096,
243
- * 0,
223
+ * 0, // Read mode
244
224
  * (size) => {
245
- * // Read up to 'size' bytes - MUST BE SYNCHRONOUS
246
- * return buffer.slice(position, position + size);
225
+ * // Read callback
226
+ * if (position >= data.length) return -541; // EOF
227
+ * const chunk = data.subarray(position, position + size);
228
+ * position += chunk.length;
229
+ * return chunk;
247
230
  * },
248
231
  * null,
249
232
  * (offset, whence) => {
250
- * // Seek to position - MUST BE SYNCHRONOUS
233
+ * // Seek callback
234
+ * if (whence === AVSEEK_SIZE) return BigInt(data.length);
251
235
  * if (whence === AVSEEK_SET) position = Number(offset);
252
236
  * else if (whence === AVSEEK_CUR) position += Number(offset);
253
- * else if (whence === AVSEEK_END) position = buffer.length + Number(offset);
237
+ * else if (whence === AVSEEK_END) position = data.length + Number(offset);
254
238
  * return BigInt(position);
255
239
  * }
256
240
  * );
257
241
  * ```
258
242
  *
259
- * @see {@link allocContext} For simple buffer allocation
243
+ * @see {@link allocContext} For simple allocation
260
244
  */
261
245
  allocContextWithCallbacks(bufferSize, writeFlag, readCallback, writeCallback, seekCallback) {
262
- return this.native.allocContextWithCallbacks(bufferSize, writeFlag, readCallback ?? undefined, writeCallback ?? undefined, seekCallback ?? undefined);
246
+ this.native.allocContextWithCallbacks(bufferSize, writeFlag, readCallback ?? undefined, writeCallback ?? undefined, seekCallback ?? undefined);
263
247
  }
264
248
  /**
265
- * Free the AVIOContext.
249
+ * Free I/O context.
266
250
  *
267
- * Direct mapping to avio_context_free()
251
+ * Releases the I/O context and its resources.
252
+ * The context becomes invalid after calling this.
253
+ *
254
+ * Direct mapping to avio_context_free().
268
255
  *
269
256
  * @example
270
257
  * ```typescript
271
- * import { IOContext } from 'node-av';
272
- *
273
258
  * io.freeContext();
274
- * // io is now invalid and should not be used
259
+ * // Context is now invalid
275
260
  * ```
276
261
  */
277
262
  freeContext() {
278
- return this.native.freeContext();
263
+ this.native.freeContext();
279
264
  }
280
265
  /**
281
- * Open a resource for reading or writing.
266
+ * Open resource for I/O.
282
267
  *
283
- * Opens a URL using the appropriate protocol handler (file, http, etc.).
284
- * Automatically allocates and initializes the I/O context.
268
+ * Opens a URL or file for reading or writing.
269
+ * Automatically selects the appropriate protocol handler.
285
270
  *
286
- * Direct mapping to avio_open2()
287
- *
288
- * @param url - URL to open (file://, http://, https://, etc.)
289
- * @param flags - I/O flags (AVIO_FLAG_READ, AVIO_FLAG_WRITE, etc.)
271
+ * Direct mapping to avio_open2().
290
272
  *
273
+ * @param url - URL or file path to open
274
+ * @param flags - Open flags (AVIO_FLAG_READ, AVIO_FLAG_WRITE, etc.)
291
275
  * @returns 0 on success, negative AVERROR on error:
292
- * - 0: Success
293
- * - AVERROR(ENOENT): File not found
294
- * - AVERROR(EACCES): Permission denied
295
- * - AVERROR(EIO): I/O error
296
- * - AVERROR(ENOMEM): Memory allocation failure
297
- * - <0: Other protocol-specific errors
276
+ * - AVERROR_ENOENT: File not found
277
+ * - AVERROR_EACCES: Permission denied
278
+ * - AVERROR_ENOMEM: Memory allocation failure
298
279
  *
299
280
  * @example
300
281
  * ```typescript
301
- * import { IOContext, FFmpegError } from 'node-av';
282
+ * import { FFmpegError } from 'node-av';
302
283
  * import { AVIO_FLAG_READ, AVIO_FLAG_WRITE } from 'node-av/constants';
303
284
  *
304
- * // Open file for reading
305
- * const io = new IOContext();
285
+ * // Open for reading
306
286
  * const ret = await io.open2('input.mp4', AVIO_FLAG_READ);
307
287
  * FFmpegError.throwIfError(ret, 'open2');
308
288
  *
309
- * // Open file for writing
310
- * const writeIO = new IOContext();
311
- * const writeRet = await writeIO.open2('output.mp4', AVIO_FLAG_WRITE);
312
- * FFmpegError.throwIfError(writeRet, 'open2');
313
- *
314
- * // Open network stream
315
- * const streamIO = new IOContext();
316
- * const streamRet = await streamIO.open2('http://example.com/stream.m3u8', AVIO_FLAG_READ);
317
- * FFmpegError.throwIfError(streamRet, 'open2');
289
+ * // Open for writing
290
+ * const ret2 = await io.open2('output.mp4', AVIO_FLAG_WRITE);
291
+ * FFmpegError.throwIfError(ret2, 'open2');
318
292
  * ```
319
293
  *
320
- * @see {@link closep} To close and free resources
294
+ * @see {@link closep} To close after use
321
295
  */
322
296
  async open2(url, flags = AVIO_FLAG_READ) {
323
- return this.native.open2(url, flags);
297
+ return await this.native.open2(url, flags);
324
298
  }
325
299
  /**
326
- * Close the resource and free the AVIOContext.
300
+ * Close I/O context.
327
301
  *
328
- * Direct mapping to avio_closep()
302
+ * Closes the I/O context and releases associated resources.
303
+ * Flushes any buffered data before closing.
329
304
  *
330
- * @returns 0 on success, negative AVERROR on error:
331
- * - 0: Success
332
- * - AVERROR(EIO): I/O error during close
333
- * - <0: Other errors
305
+ * Direct mapping to avio_closep().
306
+ *
307
+ * @returns 0 on success, negative AVERROR on error
334
308
  *
335
309
  * @example
336
310
  * ```typescript
337
- * import { FFmpegError } from 'node-av';
338
- *
339
311
  * const ret = await io.closep();
340
- * FFmpegError.throwIfError(ret, 'closep');
341
- * // I/O context is now closed and freed
312
+ * if (ret < 0) {
313
+ * console.error('Error closing I/O context');
314
+ * }
342
315
  * ```
316
+ *
317
+ * @see {@link open2} To open resources
343
318
  */
344
319
  async closep() {
345
- return this.native.closep();
320
+ return await this.native.closep();
346
321
  }
347
322
  /**
348
- * Read size bytes from AVIOContext.
323
+ * Read data from I/O context.
349
324
  *
350
- * Direct mapping to avio_read()
325
+ * Reads up to the specified number of bytes from the stream.
351
326
  *
352
- * @param size - Number of bytes to read
327
+ * Direct mapping to avio_read().
353
328
  *
354
- * @returns Buffer with data or error code if negative:
355
- * - Buffer: Successfully read data
329
+ * @param size - Maximum number of bytes to read
330
+ * @returns Buffer with data, or error code if negative:
356
331
  * - AVERROR_EOF: End of file reached
357
- * - AVERROR(EIO): I/O error
358
- * - <0: Other errors
332
+ * - AVERROR_EIO: I/O error
359
333
  *
360
334
  * @example
361
335
  * ```typescript
362
- * import { FFmpegError, AVERROR_EOF } from 'node-av';
363
- *
364
- * const data = await io.read(1024);
365
- * if (typeof data === 'number' && data < 0) {
366
- * if (data === AVERROR_EOF) {
367
- * console.log('End of file');
368
- * } else {
369
- * FFmpegError.throwIfError(data, 'read');
370
- * }
371
- * } else {
372
- * // Process buffer
336
+ * const data = await io.read(4096);
337
+ * if (data instanceof Buffer) {
373
338
  * console.log(`Read ${data.length} bytes`);
339
+ * } else {
340
+ * console.error(`Read error: ${data}`);
374
341
  * }
375
342
  * ```
343
+ *
344
+ * @see {@link write} For writing data
376
345
  */
377
346
  async read(size) {
378
- return this.native.read(size);
347
+ return await this.native.read(size);
379
348
  }
380
349
  /**
381
- * Write buffer to AVIOContext.
350
+ * Write data to I/O context.
351
+ *
352
+ * Writes buffer data to the stream.
382
353
  *
383
- * Direct mapping to avio_write()
354
+ * Direct mapping to avio_write().
384
355
  *
385
- * @param buffer - Buffer to write
356
+ * @param buffer - Data to write
386
357
  *
387
358
  * @example
388
359
  * ```typescript
389
- * import { IOContext } from 'node-av';
390
- *
391
- * const data = Buffer.from('Hello, World!');
360
+ * const data = Buffer.from('Hello World');
392
361
  * await io.write(data);
393
- * // Data written successfully
394
362
  * ```
395
363
  *
396
- * @throws {Error} If write fails
364
+ * @see {@link read} For reading data
365
+ * @see {@link flush} To flush buffers
397
366
  */
398
367
  async write(buffer) {
399
- return this.native.write(buffer);
368
+ await this.native.write(buffer);
400
369
  }
401
370
  /**
402
- * Seek to a given offset.
371
+ * Seek to position in stream.
403
372
  *
404
- * Direct mapping to avio_seek()
373
+ * Changes the current position in the stream.
374
+ * Not all streams support seeking.
405
375
  *
406
- * @param offset - Offset to seek to
407
- * @param whence - AVSEEK_SET (0), AVSEEK_CUR (1), AVSEEK_END (2), or AVSEEK_SIZE (0x10000)
376
+ * Direct mapping to avio_seek().
408
377
  *
409
- * @returns New position or negative AVERROR:
410
- * - >=0: New position in bytes
411
- * - AVERROR(EINVAL): Invalid whence value
412
- * - AVERROR(ESPIPE): Seek not supported
413
- * - <0: Other errors
378
+ * @param offset - Byte offset to seek to
379
+ * @param whence - Seek origin (AVSEEK_SET, AVSEEK_CUR, AVSEEK_END)
380
+ * @returns New position, or negative AVERROR on error:
381
+ * - AVERROR_EINVAL: Invalid arguments
382
+ * - AVERROR_ENOSYS: Seeking not supported
414
383
  *
415
384
  * @example
416
385
  * ```typescript
417
- * import { FFmpegError, AVSEEK_SET, AVSEEK_END, AVSEEK_SIZE } from 'node-av';
386
+ * import { AVSEEK_SET, AVSEEK_CUR, AVSEEK_END } from 'node-av/constants';
418
387
  *
419
- * // Seek to beginning
420
- * const pos = await io.seek(0n, AVSEEK_SET);
421
- * FFmpegError.throwIfError(pos < 0n ? Number(pos) : 0, 'seek');
388
+ * // Seek to absolute position
389
+ * const pos1 = await io.seek(1024n, AVSEEK_SET);
422
390
  *
423
- * // Seek to end
424
- * const endPos = await io.seek(0n, AVSEEK_END);
425
- * FFmpegError.throwIfError(endPos < 0n ? Number(endPos) : 0, 'seek');
391
+ * // Seek relative to current position
392
+ * const pos2 = await io.seek(512n, AVSEEK_CUR);
426
393
  *
427
- * // Get file size without changing position
428
- * const size = await io.seek(0n, AVSEEK_SIZE);
429
- * console.log(`File size: ${size} bytes`);
394
+ * // Seek relative to end
395
+ * const pos3 = await io.seek(-1024n, AVSEEK_END);
430
396
  * ```
397
+ *
398
+ * @see {@link tell} To get current position
399
+ * @see {@link skip} For relative seeking
431
400
  */
432
401
  async seek(offset, whence) {
433
- return this.native.seek(offset, whence);
402
+ return await this.native.seek(offset, whence);
434
403
  }
435
404
  /**
436
- * Get the file size.
405
+ * Get stream size.
437
406
  *
438
- * Direct mapping to avio_size()
407
+ * Returns the total size of the stream in bytes.
408
+ * Not all streams have a known size.
439
409
  *
440
- * @returns File size or negative AVERROR:
441
- * - >=0: File size in bytes
442
- * - AVERROR(ENOSYS): Operation not supported
443
- * - <0: Other errors
410
+ * Direct mapping to avio_size().
411
+ *
412
+ * @returns Size in bytes, or negative AVERROR if unknown:
413
+ * - AVERROR_ENOSYS: Size not available
444
414
  *
445
415
  * @example
446
416
  * ```typescript
447
- * import { FFmpegError } from 'node-av';
448
- *
449
417
  * const size = await io.size();
450
- * if (size < 0n) {
451
- * // Handle unsupported or error
452
- * console.error('Cannot determine file size');
418
+ * if (size >= 0n) {
419
+ * console.log(`Stream size: ${size} bytes`);
453
420
  * } else {
454
- * console.log(`File size: ${size} bytes`);
421
+ * console.log('Stream size unknown');
455
422
  * }
456
423
  * ```
457
424
  */
458
425
  async size() {
459
- return this.native.size();
426
+ return await this.native.size();
460
427
  }
461
428
  /**
462
- * Force flushing of buffered data.
429
+ * Flush buffered data.
430
+ *
431
+ * Forces any buffered data to be written to the underlying resource.
463
432
  *
464
- * Direct mapping to avio_flush()
433
+ * Direct mapping to avio_flush().
465
434
  *
466
435
  * @example
467
436
  * ```typescript
468
- * import { IOContext } from 'node-av';
469
- *
470
- * await io.flush();
471
- * // All buffered data has been written
437
+ * await io.write(data);
438
+ * await io.flush(); // Ensure data is written
472
439
  * ```
440
+ *
441
+ * @see {@link write} For writing data
473
442
  */
474
443
  async flush() {
475
- return this.native.flush();
444
+ await this.native.flush();
476
445
  }
477
446
  /**
478
- * Skip given number of bytes forward.
447
+ * Skip bytes in stream.
479
448
  *
480
- * Direct mapping to avio_skip()
449
+ * Advances the position by the specified offset.
450
+ * More efficient than reading and discarding data.
481
451
  *
482
- * @param offset - Number of bytes to skip
452
+ * Direct mapping to avio_skip().
483
453
  *
484
- * @returns New position or negative AVERROR:
485
- * - >=0: New position in bytes
486
- * - AVERROR_EOF: End of file reached
487
- * - <0: Other errors
454
+ * @param offset - Number of bytes to skip
455
+ * @returns New position after skipping
488
456
  *
489
457
  * @example
490
458
  * ```typescript
491
- * import { FFmpegError } from 'node-av';
492
- *
493
- * // Skip 1024 bytes
459
+ * // Skip 1024 bytes forward
494
460
  * const newPos = await io.skip(1024n);
495
- * FFmpegError.throwIfError(newPos < 0n ? Number(newPos) : 0, 'skip');
496
461
  * console.log(`New position: ${newPos}`);
497
462
  * ```
463
+ *
464
+ * @see {@link seek} For absolute positioning
498
465
  */
499
466
  async skip(offset) {
500
- return this.native.skip(offset);
467
+ return await this.native.skip(offset);
501
468
  }
502
469
  /**
503
- * Get the current position.
470
+ * Get current position.
471
+ *
472
+ * Returns the current byte position in the stream.
504
473
  *
505
- * Direct mapping to avio_tell()
474
+ * Direct mapping to avio_tell().
506
475
  *
507
476
  * @returns Current position in bytes
508
477
  *
509
478
  * @example
510
479
  * ```typescript
511
- * import { IOContext } from 'node-av';
512
- *
513
480
  * const position = io.tell();
514
- * console.log(`Current position: ${position} bytes`);
481
+ * console.log(`Current position: ${position}`);
515
482
  * ```
483
+ *
484
+ * @see {@link seek} To change position
516
485
  */
517
486
  tell() {
518
487
  return this.native.tell();
519
488
  }
520
489
  /**
521
- * Get the native FFmpeg AVIOContext pointer.
490
+ * Get the underlying native IOContext object.
522
491
  *
523
- * @internal For use by other wrapper classes
524
- * @returns The underlying native I/O context object
492
+ * @returns The native IOContext binding object
493
+ *
494
+ * @internal
525
495
  */
526
496
  getNative() {
527
497
  return this.native;
528
498
  }
529
499
  /**
530
- * Dispose of the I/O context.
500
+ * Dispose of the I/O context asynchronously.
531
501
  *
532
502
  * Implements the AsyncDisposable interface for automatic cleanup.
533
- * Equivalent to calling closep().
503
+ * Closes the context and releases resources.
534
504
  *
535
505
  * @example
536
506
  * ```typescript
537
- * import { IOContext, AVIO_FLAG_READ } from 'node-av';
538
- *
539
507
  * {
540
508
  * await using io = new IOContext();
541
- * await io.open2('file.mp4', AVIO_FLAG_READ);
542
- * // ... use I/O context
509
+ * await io.open2('input.mp4');
510
+ * // Use io...
543
511
  * } // Automatically closed when leaving scope
544
512
  * ```
545
513
  */