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
@@ -1,607 +1,523 @@
1
1
  import { bindings } from './binding.js';
2
2
  import { OptionMember } from './option.js';
3
3
  /**
4
- * Software audio resampling context.
4
+ * Audio resampling and format conversion context.
5
5
  *
6
- * Provides high-quality audio resampling, format conversion, and channel mixing.
7
- * Supports sample rate conversion, channel layout remapping, and sample format conversion.
8
- * Uses the libswresample library for efficient audio processing.
6
+ * Provides comprehensive audio format conversion including sample rate conversion,
7
+ * channel layout remapping, and sample format conversion. Essential for audio
8
+ * processing pipelines where format compatibility is required between components.
9
+ * Supports high-quality resampling algorithms with configurable parameters.
9
10
  *
10
11
  * Direct mapping to FFmpeg's SwrContext.
11
12
  *
12
13
  * @example
13
14
  * ```typescript
14
- * import { SoftwareResampleContext, FFmpegError } from 'node-av';
15
- * import { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP } from 'node-av/constants';
15
+ * import { SoftwareResampleContext, Frame, FFmpegError } from 'node-av';
16
+ * import { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16 } from 'node-av/constants';
16
17
  *
17
- * // Create and configure resample context
18
- * const swr = new SoftwareResampleContext();
19
- * const ret = swr.allocSetOpts2(
20
- * { order: 0, nbChannels: 2, mask: 0x3 }, // stereo out
21
- * AV_SAMPLE_FMT_S16,
22
- * 44100,
23
- * { order: 0, nbChannels: 6, mask: 0x3f }, // 5.1 in
24
- * AV_SAMPLE_FMT_FLTP,
25
- * 48000
18
+ * // Create resampler
19
+ * const resampler = new SoftwareResampleContext();
20
+ *
21
+ * // Configure format conversion
22
+ * const outLayout = { nbChannels: 2, order: 1, u: { mask: 3n } }; // Stereo
23
+ * const inLayout = { nbChannels: 1, order: 1, u: { mask: 1n } }; // Mono
24
+ *
25
+ * const ret = resampler.allocSetOpts2(
26
+ * outLayout, AV_SAMPLE_FMT_S16, 48000, // Output: Stereo, 16-bit, 48kHz
27
+ * inLayout, AV_SAMPLE_FMT_FLTP, 44100 // Input: Mono, float, 44.1kHz
26
28
  * );
27
29
  * FFmpegError.throwIfError(ret, 'allocSetOpts2');
28
30
  *
29
- * // Initialize
30
- * const initRet = swr.init();
31
- * FFmpegError.throwIfError(initRet, 'init');
31
+ * const ret2 = resampler.init();
32
+ * FFmpegError.throwIfError(ret2, 'init');
33
+ *
34
+ * // Convert audio frame
35
+ * const outFrame = new Frame();
36
+ * outFrame.nbSamples = 1024;
37
+ * outFrame.format = AV_SAMPLE_FMT_S16;
38
+ * outFrame.channelLayout = outLayout;
39
+ * outFrame.sampleRate = 48000;
40
+ * outFrame.allocBuffer();
32
41
  *
33
- * // Convert audio
34
- * const samplesOut = await swr.convert(outBuffers, outSamples, inBuffers, inSamples);
35
- * FFmpegError.throwIfError(samplesOut, 'convert');
42
+ * const ret3 = resampler.convertFrame(outFrame, inFrame);
43
+ * FFmpegError.throwIfError(ret3, 'convertFrame');
36
44
  *
37
- * // Cleanup
38
- * swr.free();
45
+ * // Get conversion delay
46
+ * const delay = resampler.getDelay(48000n);
47
+ * console.log(`Resampler delay: ${delay} samples`);
48
+ *
49
+ * // Clean up
50
+ * resampler.free();
39
51
  * ```
52
+ *
53
+ * @see [SwrContext](https://ffmpeg.org/doxygen/trunk/structSwrContext.html) - FFmpeg Doxygen
54
+ * @see {@link Frame} For audio frame operations
40
55
  */
41
56
  export class SoftwareResampleContext extends OptionMember {
42
- /**
43
- * Create a new software resample context.
44
- *
45
- * The context is uninitialized - you must call alloc() or allocSetOpts2() before use.
46
- * No FFmpeg resources are allocated until initialization.
47
- *
48
- * Direct wrapper around SwrContext.
49
- *
50
- * @example
51
- * ```typescript
52
- * import { SoftwareResampleContext, FFmpegError } from 'node-av';
53
- * import { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP } from 'node-av/constants';
54
- *
55
- * const swr = new SoftwareResampleContext();
56
- * const ret = swr.allocSetOpts2(
57
- * { order: 0, nbChannels: 2, mask: 0x3 },
58
- * AV_SAMPLE_FMT_S16,
59
- * 44100,
60
- * { order: 0, nbChannels: 6, mask: 0x3f },
61
- * AV_SAMPLE_FMT_FLTP,
62
- * 48000
63
- * );
64
- * FFmpegError.throwIfError(ret, 'allocSetOpts2');
65
- * const initRet = swr.init();
66
- * FFmpegError.throwIfError(initRet, 'init');
67
- * ```
68
- */
69
57
  constructor() {
70
58
  super(new bindings.SoftwareResampleContext());
71
59
  }
72
60
  /**
73
- * Allocate SwrContext.
61
+ * Allocate resample context.
74
62
  *
75
- * Allocates an uninitialized resample context.
76
- * Options must be set through the AVOptions API before calling init().
63
+ * Allocates memory for the resampler.
64
+ * Must be called before configuration.
77
65
  *
78
- * Direct mapping to swr_alloc()
79
- *
80
- * @throws {Error} Memory allocation failure (ENOMEM)
66
+ * Direct mapping to swr_alloc().
81
67
  *
82
68
  * @example
83
69
  * ```typescript
84
- * import { SoftwareResampleContext, FFmpegError } from 'node-av';
85
- *
86
- * const swr = new SoftwareResampleContext();
87
- * swr.alloc();
88
- * // Set options via AVOptions API
89
- * const ret = swr.init();
90
- * FFmpegError.throwIfError(ret, 'init');
70
+ * const resampler = new SoftwareResampleContext();
71
+ * resampler.alloc();
72
+ * // Now configure with setOption() or allocSetOpts2()
91
73
  * ```
92
74
  *
93
- * @see {@link allocSetOpts2} For one-step configuration
94
- * @see {@link init} To initialize after configuration
75
+ * @see {@link allocSetOpts2} For combined allocation and configuration
95
76
  */
96
77
  alloc() {
97
78
  this.native.alloc();
98
79
  }
99
80
  /**
100
- * Allocate SwrContext if needed and set/reset common parameters.
81
+ * Allocate and configure resampler.
101
82
  *
102
- * One-step allocation and configuration of the resample context.
103
- * Automatically allocates the context if not already allocated.
83
+ * Combined allocation and configuration of the resampler with
84
+ * input and output format specifications.
104
85
  *
105
- * Direct mapping to swr_alloc_set_opts2()
86
+ * Direct mapping to swr_alloc_set_opts2().
106
87
  *
107
88
  * @param outChLayout - Output channel layout
108
89
  * @param outSampleFmt - Output sample format
109
- * @param outSampleRate - Output sample rate (frequency in Hz)
90
+ * @param outSampleRate - Output sample rate in Hz
110
91
  * @param inChLayout - Input channel layout
111
92
  * @param inSampleFmt - Input sample format
112
- * @param inSampleRate - Input sample rate (frequency in Hz)
113
- *
93
+ * @param inSampleRate - Input sample rate in Hz
114
94
  * @returns 0 on success, negative AVERROR on error:
115
- * - 0: Success
116
- * - AVERROR(EINVAL): Invalid parameters
117
- * - AVERROR(ENOMEM): Memory allocation failure
95
+ * - AVERROR_EINVAL: Invalid parameters
96
+ * - AVERROR_ENOMEM: Memory allocation failure
118
97
  *
119
98
  * @example
120
99
  * ```typescript
121
- * import { SoftwareResampleContext, FFmpegError } from 'node-av';
122
- * import { AV_SAMPLE_FMT_S16, AV_SAMPLE_FMT_FLTP } from 'node-av/constants';
123
- *
124
- * const ret = swr.allocSetOpts2(
125
- * { order: 0, nbChannels: 2, mask: 0x3 }, // stereo
126
- * AV_SAMPLE_FMT_S16,
127
- * 44100,
128
- * { order: 0, nbChannels: 6, mask: 0x3f }, // 5.1
129
- * AV_SAMPLE_FMT_FLTP,
130
- * 48000
100
+ * import { FFmpegError } from 'node-av';
101
+ * import { AV_SAMPLE_FMT_FLTP, AV_SAMPLE_FMT_S16 } from 'node-av/constants';
102
+ *
103
+ * // Stereo layout
104
+ * const stereo = { nbChannels: 2, order: 1, u: { mask: 3n } };
105
+ * // 5.1 layout
106
+ * const surround = { nbChannels: 6, order: 1, u: { mask: 63n } };
107
+ *
108
+ * // Convert 5.1 float to stereo 16-bit
109
+ * const ret = resampler.allocSetOpts2(
110
+ * stereo, AV_SAMPLE_FMT_S16, 48000,
111
+ * surround, AV_SAMPLE_FMT_FLTP, 48000
131
112
  * );
132
113
  * FFmpegError.throwIfError(ret, 'allocSetOpts2');
133
114
  * ```
134
115
  *
135
- * @see {@link init} To initialize after configuration
116
+ * @see {@link init} Must be called after configuration
136
117
  */
137
118
  allocSetOpts2(outChLayout, outSampleFmt, outSampleRate, inChLayout, inSampleFmt, inSampleRate) {
138
119
  return this.native.allocSetOpts2(outChLayout, outSampleFmt, outSampleRate, inChLayout, inSampleFmt, inSampleRate);
139
120
  }
140
121
  /**
141
- * Initialize context after user parameters have been set.
122
+ * Initialize resampler.
142
123
  *
143
- * Completes initialization of the resample context.
144
- * Must be called after configuration and before conversion.
124
+ * Initializes the resampler after configuration.
125
+ * Must be called before any conversion operations.
145
126
  *
146
- * Direct mapping to swr_init()
127
+ * Direct mapping to swr_init().
147
128
  *
148
129
  * @returns 0 on success, negative AVERROR on error:
149
- * - 0: Success
150
- * - AVERROR(EINVAL): Invalid parameters
151
- * - <0: Other errors
130
+ * - AVERROR_EINVAL: Invalid configuration
131
+ * - AVERROR_ENOMEM: Memory allocation failure
152
132
  *
153
133
  * @example
154
134
  * ```typescript
155
135
  * import { FFmpegError } from 'node-av';
156
136
  *
157
- * const ret = swr.init();
137
+ * const ret = resampler.init();
158
138
  * FFmpegError.throwIfError(ret, 'init');
159
139
  * ```
160
140
  *
161
141
  * @see {@link allocSetOpts2} For configuration
162
- * @see {@link convert} For audio conversion
142
+ * @see {@link isInitialized} To check initialization status
163
143
  */
164
144
  init() {
165
145
  return this.native.init();
166
146
  }
167
147
  /**
168
- * Free the given SwrContext and set the pointer to NULL.
148
+ * Free resampler context.
169
149
  *
170
- * Direct mapping to swr_free()
150
+ * Releases all resources associated with the resampler.
151
+ * The context becomes invalid after calling this.
152
+ *
153
+ * Direct mapping to swr_free().
171
154
  *
172
155
  * @example
173
156
  * ```typescript
174
- * swr.free();
175
- * // swr is now invalid and should not be used
157
+ * resampler.free();
158
+ * // Resampler is now invalid
176
159
  * ```
160
+ *
161
+ * @see {@link close} For closing without freeing
162
+ * @see {@link Symbol.dispose} For automatic cleanup
177
163
  */
178
164
  free() {
179
165
  this.native.free();
180
166
  }
181
167
  /**
182
- * Closes the context so that swr_is_initialized() returns 0.
168
+ * Close resampler context.
183
169
  *
184
- * Direct mapping to swr_close()
170
+ * Closes the resampler but keeps the context allocated.
171
+ * Can be reconfigured and reinitialized after closing.
185
172
  *
186
- * The context can be brought back to life by running swr_init(),
187
- * swr_init() can also be used without swr_close().
188
- * This function is mainly provided for simplifying the usecase
189
- * where one tries to support libavresample and libswresample.
173
+ * Direct mapping to swr_close().
190
174
  *
191
175
  * @example
192
176
  * ```typescript
193
- * swr.close();
194
- * // Context is now closed but not freed
195
- * // Can be reinitialized with swr.init()
177
+ * resampler.close();
178
+ * // Can now reconfigure and reinit
196
179
  * ```
180
+ *
181
+ * @see {@link free} For complete deallocation
197
182
  */
198
183
  close() {
199
184
  this.native.close();
200
185
  }
201
186
  /**
202
- * Convert audio.
203
- *
204
- * Converts audio between different formats, sample rates, and channel layouts.
205
- * Handles buffering internally when output space is insufficient.
187
+ * Convert audio samples.
206
188
  *
207
- * Direct mapping to swr_convert()
189
+ * Converts audio samples from input format to output format.
190
+ * Handles resampling, channel remapping, and format conversion.
208
191
  *
209
- * @param outBuffer - Output buffers, only the first one need be set in case of packed audio
210
- * @param outCount - Amount of space available for output in samples per channel
211
- * @param inBuffer - Input buffers, only the first one need be set in case of packed audio
212
- * @param inCount - Number of input samples available in one channel
192
+ * Direct mapping to swr_convert().
213
193
  *
214
- * @returns Number of samples output per channel, negative AVERROR on error:
215
- * - >=0: Number of samples output per channel
216
- * - AVERROR(EINVAL): Invalid parameters
217
- * - <0: Other errors
194
+ * @param outBuffer - Output sample buffers (one per channel for planar)
195
+ * @param outCount - Maximum output samples per channel
196
+ * @param inBuffer - Input sample buffers (one per channel for planar)
197
+ * @param inCount - Input samples per channel
198
+ * @returns Number of output samples per channel, negative AVERROR on error:
199
+ * - AVERROR_EINVAL: Invalid parameters
200
+ * - AVERROR_INPUT_CHANGED: Input format changed
218
201
  *
219
202
  * @example
220
203
  * ```typescript
221
204
  * import { FFmpegError } from 'node-av';
222
205
  *
223
- * const samplesOut = await swr.convert(
224
- * outBuffers,
225
- * outSamples,
226
- * inBuffers,
227
- * inSamples
206
+ * // Convert audio buffers
207
+ * const outBuffers = [Buffer.alloc(4096), Buffer.alloc(4096)]; // Stereo
208
+ * const inBuffers = [inputBuffer]; // Mono
209
+ *
210
+ * const samples = await resampler.convert(
211
+ * outBuffers, 1024,
212
+ * inBuffers, inputSamples
228
213
  * );
229
- * FFmpegError.throwIfError(samplesOut, 'convert');
230
- * console.log(`Converted ${samplesOut} samples per channel`);
214
+ *
215
+ * if (samples < 0) {
216
+ * FFmpegError.throwIfError(samples, 'convert');
217
+ * }
218
+ * console.log(`Converted ${samples} samples`);
231
219
  * ```
232
220
  *
233
- * @see {@link getOutSamples} To calculate required output space
234
221
  * @see {@link convertFrame} For frame-based conversion
235
- *
236
- * @note If more input is provided than output space, then the input will be buffered.
237
- * You can avoid this buffering by using swr_get_out_samples() to retrieve an
238
- * upper bound on the required number of output samples for the given number of
239
- * input samples. Conversion will run directly without copying whenever possible.
240
222
  */
241
223
  async convert(outBuffer, outCount, inBuffer, inCount) {
242
- return this.native.convert(outBuffer, outCount, inBuffer, inCount);
224
+ return await this.native.convert(outBuffer, outCount, inBuffer, inCount);
243
225
  }
244
226
  /**
245
- * Convert the samples in the input AVFrame and write them to the output AVFrame.
246
- *
247
- * Frame-based audio conversion with automatic buffer management.
248
- * Handles format, sample rate, and channel layout conversion.
227
+ * Convert audio frame.
249
228
  *
250
- * Direct mapping to swr_convert_frame()
229
+ * Converts an entire audio frame to the output format.
230
+ * Simpler interface than convert() for frame-based processing.
251
231
  *
252
- * @param outFrame - Output AVFrame (can be null for flushing)
253
- * @param inFrame - Input AVFrame (can be null for draining)
232
+ * Direct mapping to swr_convert_frame().
254
233
  *
234
+ * @param outFrame - Output frame (null to drain)
235
+ * @param inFrame - Input frame (null to flush)
255
236
  * @returns 0 on success, negative AVERROR on error:
256
- * - 0: Success
257
- * - AVERROR(EINVAL): Invalid frame parameters
258
- * - AVERROR(EAGAIN): Need more input or output
259
- * - <0: Other errors
237
+ * - AVERROR_EINVAL: Invalid parameters
238
+ * - AVERROR_ENOMEM: Memory allocation failure
239
+ * - AVERROR_INPUT_CHANGED: Input format changed
260
240
  *
261
241
  * @example
262
242
  * ```typescript
263
243
  * import { Frame, FFmpegError } from 'node-av';
264
244
  *
265
- * const ret = swr.convertFrame(outFrame, inFrame);
245
+ * // Convert frame
246
+ * const outFrame = new Frame();
247
+ * const ret = resampler.convertFrame(outFrame, inFrame);
266
248
  * FFmpegError.throwIfError(ret, 'convertFrame');
267
249
  *
268
- * // Flush remaining samples
269
- * const flushRet = swr.convertFrame(outFrame, null);
270
- * FFmpegError.throwIfError(flushRet, 'flush');
250
+ * // Drain remaining samples
251
+ * const drainFrame = new Frame();
252
+ * const ret2 = resampler.convertFrame(drainFrame, null);
253
+ * if (ret2 === 0) {
254
+ * // Got drained samples
255
+ * }
271
256
  * ```
272
257
  *
273
258
  * @see {@link convert} For buffer-based conversion
274
- * @see {@link getDelay} To check buffered samples
275
- *
276
- * @note Input and output AVFrames must have channel_layout, sample_rate and format set.
277
- * If the output AVFrame does not have the data pointers allocated the nb_samples
278
- * field will be set and av_frame_get_buffer() is called to allocate the frame.
259
+ * @see {@link configFrame} To configure from frame
279
260
  */
280
261
  convertFrame(outFrame, inFrame) {
281
262
  return this.native.convertFrame(outFrame?.getNative() ?? null, inFrame?.getNative() ?? null);
282
263
  }
283
264
  /**
284
- * Configure or reconfigure the SwrContext using the information provided by the AVFrames.
285
- *
286
- * Automatically configures the resample context from frame parameters.
287
- * Resets the context even on failure and calls close() internally if open.
265
+ * Configure resampler from frames.
288
266
  *
289
- * Direct mapping to swr_config_frame()
267
+ * Configures the resampler using format information from frames.
268
+ * Alternative to allocSetOpts2() for frame-based setup.
290
269
  *
291
- * @param outFrame - Output AVFrame (provides output parameters)
292
- * @param inFrame - Input AVFrame (provides input parameters)
270
+ * Direct mapping to swr_config_frame().
293
271
  *
272
+ * @param outFrame - Frame with output format
273
+ * @param inFrame - Frame with input format
294
274
  * @returns 0 on success, negative AVERROR on error:
295
- * - 0: Success
296
- * - AVERROR(EINVAL): Invalid frame parameters
297
- * - AVERROR(ENOMEM): Memory allocation failure
298
- * - <0: Other errors
275
+ * - AVERROR_EINVAL: Invalid parameters
299
276
  *
300
277
  * @example
301
278
  * ```typescript
302
279
  * import { FFmpegError } from 'node-av';
303
280
  *
304
- * const ret = swr.configFrame(outFrame, inFrame);
281
+ * // Configure from frames
282
+ * const ret = resampler.configFrame(outFrame, inFrame);
305
283
  * FFmpegError.throwIfError(ret, 'configFrame');
306
- * const initRet = swr.init();
307
- * FFmpegError.throwIfError(initRet, 'init');
284
+ *
285
+ * const ret2 = resampler.init();
286
+ * FFmpegError.throwIfError(ret2, 'init');
308
287
  * ```
309
288
  *
310
- * @see {@link init} Must be called after configuration
289
+ * @see {@link allocSetOpts2} For manual configuration
311
290
  */
312
291
  configFrame(outFrame, inFrame) {
313
292
  return this.native.configFrame(outFrame?.getNative() ?? null, inFrame?.getNative() ?? null);
314
293
  }
315
294
  /**
316
- * Check whether an swr context has been initialized or not.
295
+ * Check if initialized.
317
296
  *
318
- * Checks if the context is ready for audio conversion.
297
+ * Returns whether the resampler has been initialized.
319
298
  *
320
- * Direct mapping to swr_is_initialized()
299
+ * Direct mapping to swr_is_initialized().
321
300
  *
322
301
  * @returns True if initialized, false otherwise
323
302
  *
324
303
  * @example
325
304
  * ```typescript
326
- * import { FFmpegError } from 'node-av';
327
- *
328
- * if (swr.isInitialized()) {
329
- * // Context is ready for conversion
330
- * const ret = await swr.convert(outBuf, outCount, inBuf, inCount);
331
- * FFmpegError.throwIfError(ret, 'convert');
305
+ * if (!resampler.isInitialized()) {
306
+ * resampler.init();
332
307
  * }
333
308
  * ```
309
+ *
310
+ * @see {@link init} To initialize
334
311
  */
335
312
  isInitialized() {
336
313
  return this.native.isInitialized();
337
314
  }
338
315
  /**
339
- * Gets the delay the next input sample will experience relative to the next output sample.
340
- *
341
- * Returns the total buffering delay in the resample context.
342
- * Accounts for both buffered data and sample rate conversion delays.
316
+ * Get resampler delay.
343
317
  *
344
- * Direct mapping to swr_get_delay()
318
+ * Returns the number of samples currently buffered in the resampler.
319
+ * These samples will be output when flushing or with new input.
345
320
  *
346
- * @param base - Timebase in which the returned delay will be:
347
- * - 1: delay in seconds
348
- * - 1000: delay in milliseconds
349
- * - input sample rate: delay in input samples
350
- * - output sample rate: delay in output samples
351
- * - LCM of rates: exact rounding-free delay
321
+ * Direct mapping to swr_get_delay().
352
322
  *
353
- * @returns The delay in 1 / base units
323
+ * @param base - Time base for the returned delay
324
+ * @returns Delay in samples at the given base rate
354
325
  *
355
326
  * @example
356
327
  * ```typescript
357
- * // Get delay in milliseconds
358
- * const delayMs = swr.getDelay(1000n);
359
- * console.log(`Buffered: ${delayMs}ms`);
328
+ * // Get delay in output sample rate
329
+ * const delay = resampler.getDelay(48000n);
330
+ * console.log(`${delay} samples buffered`);
360
331
  *
361
- * // Get delay in output samples
362
- * const delaySamples = swr.getDelay(BigInt(outputSampleRate));
363
- * console.log(`Buffered: ${delaySamples} samples`);
332
+ * // Get delay in microseconds
333
+ * const delayUs = resampler.getDelay(1000000n);
334
+ * console.log(`${delayUs} microseconds delay`);
364
335
  * ```
365
- *
366
- * @see {@link getOutSamples} To calculate output buffer size
367
336
  */
368
337
  getDelay(base) {
369
338
  return this.native.getDelay(base);
370
339
  }
371
340
  /**
372
- * Find an upper bound on the number of samples that the next swr_convert will output.
341
+ * Calculate output sample count.
373
342
  *
374
- * Calculates maximum output samples for given input samples.
375
- * Accounts for buffered data and sample rate conversion.
343
+ * Calculates how many output samples will be produced
344
+ * for a given number of input samples.
376
345
  *
377
- * Direct mapping to swr_get_out_samples()
346
+ * Direct mapping to swr_get_out_samples().
378
347
  *
379
348
  * @param inSamples - Number of input samples
380
- *
381
- * @returns Upper bound on output samples or negative AVERROR:
382
- * - >=0: Upper bound on the number of samples that the next swr_convert will output
383
- * - AVERROR(EINVAL): Invalid parameters
384
- * - <0: Other errors
349
+ * @returns Number of output samples
385
350
  *
386
351
  * @example
387
352
  * ```typescript
388
- * import { FFmpegError } from 'node-av';
389
- *
390
- * const outSamples = swr.getOutSamples(inSamples);
391
- * FFmpegError.throwIfError(outSamples, 'getOutSamples');
392
- * // Allocate output buffer for outSamples samples
393
- * const bufferSize = outSamples * bytesPerSample * channels;
353
+ * const outSamples = resampler.getOutSamples(1024);
354
+ * console.log(`1024 input samples -> ${outSamples} output samples`);
394
355
  * ```
395
- *
396
- * @see {@link convert} For actual conversion
397
- *
398
- * @note This depends on the internal state, and anything changing the internal state
399
- * (like further swr_convert() calls) may change the number of samples returned.
400
356
  */
401
357
  getOutSamples(inSamples) {
402
358
  return this.native.getOutSamples(inSamples);
403
359
  }
404
360
  /**
405
- * Convert the next timestamp from input to output.
361
+ * Calculate next PTS.
406
362
  *
407
- * Converts timestamps accounting for sample rate conversion.
408
- * Timestamps are in 1/(in_sample_rate * out_sample_rate) units.
363
+ * Calculates the presentation timestamp for the next output sample.
409
364
  *
410
- * Direct mapping to swr_next_pts()
365
+ * Direct mapping to swr_next_pts().
411
366
  *
412
- * @param pts - Timestamp for the next input sample, INT64_MIN if unknown
413
- *
414
- * @returns The output timestamp for the next output sample
367
+ * @param pts - Current presentation timestamp
368
+ * @returns Next presentation timestamp
415
369
  *
416
370
  * @example
417
371
  * ```typescript
418
- * const outPts = swr.nextPts(inPts);
419
- * outFrame.pts = outPts;
372
+ * let pts = 0n;
373
+ * pts = resampler.nextPts(pts);
374
+ * console.log(`Next PTS: ${pts}`);
420
375
  * ```
421
- *
422
- * @see {@link setCompensation} For timestamp compensation
423
376
  */
424
377
  nextPts(pts) {
425
378
  return this.native.nextPts(pts);
426
379
  }
427
380
  /**
428
- * Activate resampling compensation ("soft" compensation).
381
+ * Set compensation.
429
382
  *
430
- * Adjusts resampling to compensate for timestamp drift.
431
- * Automatically called by nextPts() when needed.
383
+ * Adjusts the resampling rate to compensate for clock drift.
384
+ * Used for audio/video synchronization.
432
385
  *
433
- * Direct mapping to swr_set_compensation()
434
- *
435
- * @param sampleDelta - Delta in PTS per sample
436
- * @param compensationDistance - Number of samples to compensate for
386
+ * Direct mapping to swr_set_compensation().
437
387
  *
388
+ * @param sampleDelta - Sample difference to compensate
389
+ * @param compensationDistance - Distance over which to compensate
438
390
  * @returns 0 on success, negative AVERROR on error:
439
- * - 0: Success
440
- * - AVERROR(EINVAL): Invalid parameters (NULL context, negative distance, etc.)
441
- * - AVERROR(ENOSYS): Compensation unsupported by resampler
442
- * - <0: Other errors
391
+ * - AVERROR_EINVAL: Invalid parameters
443
392
  *
444
393
  * @example
445
394
  * ```typescript
446
395
  * import { FFmpegError } from 'node-av';
447
396
  *
448
- * const ret = swr.setCompensation(delta, distance);
397
+ * // Compensate 10 samples over 1000 samples
398
+ * const ret = resampler.setCompensation(10, 1000);
449
399
  * FFmpegError.throwIfError(ret, 'setCompensation');
450
400
  * ```
451
- *
452
- * @see {@link nextPts} For automatic compensation
453
401
  */
454
402
  setCompensation(sampleDelta, compensationDistance) {
455
403
  return this.native.setCompensation(sampleDelta, compensationDistance);
456
404
  }
457
405
  /**
458
- * Set a customized input channel mapping.
406
+ * Set channel mapping.
459
407
  *
460
- * Remaps input channels to output channels.
461
- * Use -1 to mute a channel.
408
+ * Sets custom channel mapping for remixing.
462
409
  *
463
- * Direct mapping to swr_set_channel_mapping()
410
+ * Direct mapping to swr_set_channel_mapping().
464
411
  *
465
- * @param channelMap - Customized input channel mapping (array of channel indexes, -1 for a muted channel)
466
- *
467
- * @returns 0 on success, negative AVERROR on error:
468
- * - 0: Success
469
- * - AVERROR(EINVAL): Invalid parameters
470
- * - <0: Other errors
412
+ * @param channelMap - Array mapping input to output channels
413
+ * @returns 0 on success, negative AVERROR on error
471
414
  *
472
415
  * @example
473
416
  * ```typescript
474
- * import { FFmpegError } from 'node-av';
475
- *
476
- * // Map channels: 0->0, 1->1, mute channel 2
477
- * const ret = swr.setChannelMapping([0, 1, -1]);
417
+ * // Map stereo to reverse stereo (swap L/R)
418
+ * const ret = resampler.setChannelMapping([1, 0]);
478
419
  * FFmpegError.throwIfError(ret, 'setChannelMapping');
479
420
  * ```
480
- *
481
- * @see {@link setMatrix} For custom mixing matrix
482
421
  */
483
422
  setChannelMapping(channelMap) {
484
423
  return this.native.setChannelMapping(channelMap);
485
424
  }
486
425
  /**
487
- * Set a customized remix matrix.
426
+ * Set mixing matrix.
488
427
  *
489
- * Sets custom coefficients for channel mixing.
490
- * matrix[i + stride * o] is the weight of input channel i in output channel o.
428
+ * Sets a custom mixing matrix for channel remapping.
491
429
  *
492
- * Direct mapping to swr_set_matrix()
430
+ * Direct mapping to swr_set_matrix().
493
431
  *
494
- * @param matrix - Remix coefficients
495
- * @param stride - Offset between lines of the matrix
496
- *
497
- * @returns 0 on success, negative AVERROR on error:
498
- * - 0: Success
499
- * - AVERROR(EINVAL): Invalid parameters
500
- * - <0: Other errors
432
+ * @param matrix - Mixing matrix coefficients
433
+ * @param stride - Matrix row stride
434
+ * @returns 0 on success, negative AVERROR on error
501
435
  *
502
436
  * @example
503
437
  * ```typescript
504
- * import { FFmpegError } from 'node-av';
505
- *
506
- * // Set custom mix matrix for stereo to mono
507
- * const matrix = [0.5, 0.5]; // Mix both channels equally
508
- * const ret = swr.setMatrix(matrix, 1);
438
+ * // Custom downmix matrix
439
+ * const matrix = [
440
+ * 1.0, 0.0, // Left channel
441
+ * 0.0, 1.0, // Right channel
442
+ * ];
443
+ * const ret = resampler.setMatrix(matrix, 2);
509
444
  * FFmpegError.throwIfError(ret, 'setMatrix');
510
445
  * ```
511
- *
512
- * @see {@link setChannelMapping} For channel remapping
513
446
  */
514
447
  setMatrix(matrix, stride) {
515
448
  return this.native.setMatrix(matrix, stride);
516
449
  }
517
450
  /**
518
- * Drops the specified number of output samples.
451
+ * Drop output samples.
519
452
  *
520
- * Discards output samples for "hard" timestamp compensation.
521
- * Automatically called by nextPts() when needed.
522
- *
523
- * Direct mapping to swr_drop_output()
453
+ * Drops the specified number of output samples.
454
+ * Used for synchronization adjustments.
524
455
  *
525
- * @param count - Number of samples to be dropped
456
+ * Direct mapping to swr_drop_output().
526
457
  *
527
- * @returns 0 on success, negative AVERROR on error:
528
- * - 0: Success
529
- * - AVERROR(EINVAL): Invalid parameters
530
- * - <0: Other errors
458
+ * @param count - Number of samples to drop
459
+ * @returns 0 on success, negative AVERROR on error
531
460
  *
532
461
  * @example
533
462
  * ```typescript
534
- * import { FFmpegError } from 'node-av';
535
- *
536
- * const ret = swr.dropOutput(100);
537
- * FFmpegError.throwIfError(ret, 'dropOutput');
463
+ * // Drop 100 output samples
464
+ * const ret = resampler.dropOutput(100);
465
+ * if (ret >= 0) {
466
+ * console.log(`Dropped ${ret} samples`);
467
+ * }
538
468
  * ```
539
- *
540
- * @see {@link injectSilence} For adding silence
541
- * @see {@link nextPts} For automatic compensation
542
469
  */
543
470
  dropOutput(count) {
544
471
  return this.native.dropOutput(count);
545
472
  }
546
473
  /**
547
- * Injects the specified number of silence samples.
474
+ * Inject silence.
548
475
  *
549
- * Inserts silent samples for "hard" timestamp compensation.
550
- * Automatically called by nextPts() when needed.
476
+ * Injects silent samples into the output.
477
+ * Used for padding or synchronization.
551
478
  *
552
- * Direct mapping to swr_inject_silence()
479
+ * Direct mapping to swr_inject_silence().
553
480
  *
554
- * @param count - Number of samples to be injected
555
- *
556
- * @returns 0 on success, negative AVERROR on error:
557
- * - 0: Success
558
- * - AVERROR(EINVAL): Invalid parameters
559
- * - <0: Other errors
481
+ * @param count - Number of silent samples to inject
482
+ * @returns 0 on success, negative AVERROR on error
560
483
  *
561
484
  * @example
562
485
  * ```typescript
563
- * import { FFmpegError } from 'node-av';
564
- *
565
- * const ret = swr.injectSilence(100);
566
- * FFmpegError.throwIfError(ret, 'injectSilence');
486
+ * // Inject 100 silent samples
487
+ * const ret = resampler.injectSilence(100);
488
+ * if (ret >= 0) {
489
+ * console.log(`Injected ${ret} silent samples`);
490
+ * }
567
491
  * ```
568
- *
569
- * @see {@link dropOutput} For dropping samples
570
- * @see {@link nextPts} For automatic compensation
571
492
  */
572
493
  injectSilence(count) {
573
494
  return this.native.injectSilence(count);
574
495
  }
575
496
  /**
576
- * Get the native FFmpeg SwrContext pointer.
497
+ * Get the underlying native SoftwareResampleContext object.
498
+ *
499
+ * @returns The native SoftwareResampleContext binding object
577
500
  *
578
- * @internal For use by other wrapper classes
579
- * @returns The underlying native resample context object
501
+ * @internal
580
502
  */
581
503
  getNative() {
582
504
  return this.native;
583
505
  }
584
506
  /**
585
- * Dispose of the resample context.
507
+ * Dispose of the resampler context.
586
508
  *
587
509
  * Implements the Disposable interface for automatic cleanup.
588
510
  * Equivalent to calling free().
589
511
  *
590
512
  * @example
591
513
  * ```typescript
592
- * import { SoftwareResampleContext, FFmpegError } from 'node-av';
593
- *
594
514
  * {
595
- * using swr = new SoftwareResampleContext();
596
- * const ret = swr.allocSetOpts2(...);
597
- * FFmpegError.throwIfError(ret, 'allocSetOpts2');
598
- * const initRet = swr.init();
599
- * FFmpegError.throwIfError(initRet, 'init');
600
- * // ... use context
515
+ * using resampler = new SoftwareResampleContext();
516
+ * resampler.allocSetOpts2(...);
517
+ * resampler.init();
518
+ * // Use resampler...
601
519
  * } // Automatically freed when leaving scope
602
520
  * ```
603
- *
604
- * @see {@link free} For manual cleanup
605
521
  */
606
522
  [Symbol.dispose]() {
607
523
  this.native[Symbol.dispose]();