@revizly/node-av 5.2.2-beta.1

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 (254) hide show
  1. package/BUILD_LINUX.md +61 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +662 -0
  4. package/build_mac_local.sh +69 -0
  5. package/dist/api/audio-frame-buffer.d.ts +205 -0
  6. package/dist/api/audio-frame-buffer.js +287 -0
  7. package/dist/api/audio-frame-buffer.js.map +1 -0
  8. package/dist/api/bitstream-filter.d.ts +820 -0
  9. package/dist/api/bitstream-filter.js +1242 -0
  10. package/dist/api/bitstream-filter.js.map +1 -0
  11. package/dist/api/constants.d.ts +44 -0
  12. package/dist/api/constants.js +45 -0
  13. package/dist/api/constants.js.map +1 -0
  14. package/dist/api/data/test_av1.ivf +0 -0
  15. package/dist/api/data/test_h264.h264 +0 -0
  16. package/dist/api/data/test_hevc.h265 +0 -0
  17. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  18. package/dist/api/data/test_vp8.ivf +0 -0
  19. package/dist/api/data/test_vp9.ivf +0 -0
  20. package/dist/api/decoder.d.ts +1088 -0
  21. package/dist/api/decoder.js +1775 -0
  22. package/dist/api/decoder.js.map +1 -0
  23. package/dist/api/demuxer.d.ts +1219 -0
  24. package/dist/api/demuxer.js +2081 -0
  25. package/dist/api/demuxer.js.map +1 -0
  26. package/dist/api/device.d.ts +586 -0
  27. package/dist/api/device.js +961 -0
  28. package/dist/api/device.js.map +1 -0
  29. package/dist/api/encoder.d.ts +1132 -0
  30. package/dist/api/encoder.js +1988 -0
  31. package/dist/api/encoder.js.map +1 -0
  32. package/dist/api/filter-complex.d.ts +821 -0
  33. package/dist/api/filter-complex.js +1604 -0
  34. package/dist/api/filter-complex.js.map +1 -0
  35. package/dist/api/filter-presets.d.ts +1286 -0
  36. package/dist/api/filter-presets.js +2152 -0
  37. package/dist/api/filter-presets.js.map +1 -0
  38. package/dist/api/filter.d.ts +1234 -0
  39. package/dist/api/filter.js +1976 -0
  40. package/dist/api/filter.js.map +1 -0
  41. package/dist/api/fmp4-stream.d.ts +426 -0
  42. package/dist/api/fmp4-stream.js +739 -0
  43. package/dist/api/fmp4-stream.js.map +1 -0
  44. package/dist/api/hardware.d.ts +651 -0
  45. package/dist/api/hardware.js +1260 -0
  46. package/dist/api/hardware.js.map +1 -0
  47. package/dist/api/index.d.ts +17 -0
  48. package/dist/api/index.js +32 -0
  49. package/dist/api/index.js.map +1 -0
  50. package/dist/api/io-stream.d.ts +307 -0
  51. package/dist/api/io-stream.js +282 -0
  52. package/dist/api/io-stream.js.map +1 -0
  53. package/dist/api/muxer.d.ts +957 -0
  54. package/dist/api/muxer.js +2002 -0
  55. package/dist/api/muxer.js.map +1 -0
  56. package/dist/api/pipeline.d.ts +607 -0
  57. package/dist/api/pipeline.js +1145 -0
  58. package/dist/api/pipeline.js.map +1 -0
  59. package/dist/api/utilities/async-queue.d.ts +120 -0
  60. package/dist/api/utilities/async-queue.js +211 -0
  61. package/dist/api/utilities/async-queue.js.map +1 -0
  62. package/dist/api/utilities/audio-sample.d.ts +117 -0
  63. package/dist/api/utilities/audio-sample.js +112 -0
  64. package/dist/api/utilities/audio-sample.js.map +1 -0
  65. package/dist/api/utilities/channel-layout.d.ts +76 -0
  66. package/dist/api/utilities/channel-layout.js +80 -0
  67. package/dist/api/utilities/channel-layout.js.map +1 -0
  68. package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
  69. package/dist/api/utilities/electron-shared-texture.js +503 -0
  70. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  71. package/dist/api/utilities/image.d.ts +207 -0
  72. package/dist/api/utilities/image.js +213 -0
  73. package/dist/api/utilities/image.js.map +1 -0
  74. package/dist/api/utilities/index.d.ts +12 -0
  75. package/dist/api/utilities/index.js +25 -0
  76. package/dist/api/utilities/index.js.map +1 -0
  77. package/dist/api/utilities/media-type.d.ts +49 -0
  78. package/dist/api/utilities/media-type.js +53 -0
  79. package/dist/api/utilities/media-type.js.map +1 -0
  80. package/dist/api/utilities/pixel-format.d.ts +89 -0
  81. package/dist/api/utilities/pixel-format.js +97 -0
  82. package/dist/api/utilities/pixel-format.js.map +1 -0
  83. package/dist/api/utilities/sample-format.d.ts +129 -0
  84. package/dist/api/utilities/sample-format.js +141 -0
  85. package/dist/api/utilities/sample-format.js.map +1 -0
  86. package/dist/api/utilities/scheduler.d.ts +138 -0
  87. package/dist/api/utilities/scheduler.js +98 -0
  88. package/dist/api/utilities/scheduler.js.map +1 -0
  89. package/dist/api/utilities/streaming.d.ts +186 -0
  90. package/dist/api/utilities/streaming.js +309 -0
  91. package/dist/api/utilities/streaming.js.map +1 -0
  92. package/dist/api/utilities/timestamp.d.ts +193 -0
  93. package/dist/api/utilities/timestamp.js +206 -0
  94. package/dist/api/utilities/timestamp.js.map +1 -0
  95. package/dist/api/utilities/whisper-model.d.ts +310 -0
  96. package/dist/api/utilities/whisper-model.js +528 -0
  97. package/dist/api/utilities/whisper-model.js.map +1 -0
  98. package/dist/api/utils.d.ts +19 -0
  99. package/dist/api/utils.js +39 -0
  100. package/dist/api/utils.js.map +1 -0
  101. package/dist/api/whisper.d.ts +324 -0
  102. package/dist/api/whisper.js +362 -0
  103. package/dist/api/whisper.js.map +1 -0
  104. package/dist/constants/channel-layouts.d.ts +53 -0
  105. package/dist/constants/channel-layouts.js +57 -0
  106. package/dist/constants/channel-layouts.js.map +1 -0
  107. package/dist/constants/constants.d.ts +2325 -0
  108. package/dist/constants/constants.js +1887 -0
  109. package/dist/constants/constants.js.map +1 -0
  110. package/dist/constants/decoders.d.ts +633 -0
  111. package/dist/constants/decoders.js +641 -0
  112. package/dist/constants/decoders.js.map +1 -0
  113. package/dist/constants/encoders.d.ts +295 -0
  114. package/dist/constants/encoders.js +308 -0
  115. package/dist/constants/encoders.js.map +1 -0
  116. package/dist/constants/hardware.d.ts +26 -0
  117. package/dist/constants/hardware.js +27 -0
  118. package/dist/constants/hardware.js.map +1 -0
  119. package/dist/constants/index.d.ts +5 -0
  120. package/dist/constants/index.js +6 -0
  121. package/dist/constants/index.js.map +1 -0
  122. package/dist/ffmpeg/index.d.ts +99 -0
  123. package/dist/ffmpeg/index.js +115 -0
  124. package/dist/ffmpeg/index.js.map +1 -0
  125. package/dist/ffmpeg/utils.d.ts +31 -0
  126. package/dist/ffmpeg/utils.js +68 -0
  127. package/dist/ffmpeg/utils.js.map +1 -0
  128. package/dist/ffmpeg/version.d.ts +6 -0
  129. package/dist/ffmpeg/version.js +7 -0
  130. package/dist/ffmpeg/version.js.map +1 -0
  131. package/dist/index.d.ts +4 -0
  132. package/dist/index.js +9 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/lib/audio-fifo.d.ts +399 -0
  135. package/dist/lib/audio-fifo.js +431 -0
  136. package/dist/lib/audio-fifo.js.map +1 -0
  137. package/dist/lib/binding.d.ts +228 -0
  138. package/dist/lib/binding.js +60 -0
  139. package/dist/lib/binding.js.map +1 -0
  140. package/dist/lib/bitstream-filter-context.d.ts +379 -0
  141. package/dist/lib/bitstream-filter-context.js +441 -0
  142. package/dist/lib/bitstream-filter-context.js.map +1 -0
  143. package/dist/lib/bitstream-filter.d.ts +140 -0
  144. package/dist/lib/bitstream-filter.js +154 -0
  145. package/dist/lib/bitstream-filter.js.map +1 -0
  146. package/dist/lib/codec-context.d.ts +1071 -0
  147. package/dist/lib/codec-context.js +1354 -0
  148. package/dist/lib/codec-context.js.map +1 -0
  149. package/dist/lib/codec-parameters.d.ts +616 -0
  150. package/dist/lib/codec-parameters.js +761 -0
  151. package/dist/lib/codec-parameters.js.map +1 -0
  152. package/dist/lib/codec-parser.d.ts +201 -0
  153. package/dist/lib/codec-parser.js +213 -0
  154. package/dist/lib/codec-parser.js.map +1 -0
  155. package/dist/lib/codec.d.ts +586 -0
  156. package/dist/lib/codec.js +713 -0
  157. package/dist/lib/codec.js.map +1 -0
  158. package/dist/lib/device.d.ts +291 -0
  159. package/dist/lib/device.js +324 -0
  160. package/dist/lib/device.js.map +1 -0
  161. package/dist/lib/dictionary.d.ts +333 -0
  162. package/dist/lib/dictionary.js +372 -0
  163. package/dist/lib/dictionary.js.map +1 -0
  164. package/dist/lib/error.d.ts +242 -0
  165. package/dist/lib/error.js +303 -0
  166. package/dist/lib/error.js.map +1 -0
  167. package/dist/lib/fifo.d.ts +416 -0
  168. package/dist/lib/fifo.js +453 -0
  169. package/dist/lib/fifo.js.map +1 -0
  170. package/dist/lib/filter-context.d.ts +712 -0
  171. package/dist/lib/filter-context.js +789 -0
  172. package/dist/lib/filter-context.js.map +1 -0
  173. package/dist/lib/filter-graph-segment.d.ts +160 -0
  174. package/dist/lib/filter-graph-segment.js +171 -0
  175. package/dist/lib/filter-graph-segment.js.map +1 -0
  176. package/dist/lib/filter-graph.d.ts +641 -0
  177. package/dist/lib/filter-graph.js +704 -0
  178. package/dist/lib/filter-graph.js.map +1 -0
  179. package/dist/lib/filter-inout.d.ts +198 -0
  180. package/dist/lib/filter-inout.js +257 -0
  181. package/dist/lib/filter-inout.js.map +1 -0
  182. package/dist/lib/filter.d.ts +243 -0
  183. package/dist/lib/filter.js +272 -0
  184. package/dist/lib/filter.js.map +1 -0
  185. package/dist/lib/format-context.d.ts +1254 -0
  186. package/dist/lib/format-context.js +1379 -0
  187. package/dist/lib/format-context.js.map +1 -0
  188. package/dist/lib/frame-utils.d.ts +116 -0
  189. package/dist/lib/frame-utils.js +98 -0
  190. package/dist/lib/frame-utils.js.map +1 -0
  191. package/dist/lib/frame.d.ts +1222 -0
  192. package/dist/lib/frame.js +1435 -0
  193. package/dist/lib/frame.js.map +1 -0
  194. package/dist/lib/hardware-device-context.d.ts +362 -0
  195. package/dist/lib/hardware-device-context.js +383 -0
  196. package/dist/lib/hardware-device-context.js.map +1 -0
  197. package/dist/lib/hardware-frames-context.d.ts +419 -0
  198. package/dist/lib/hardware-frames-context.js +477 -0
  199. package/dist/lib/hardware-frames-context.js.map +1 -0
  200. package/dist/lib/index.d.ts +35 -0
  201. package/dist/lib/index.js +60 -0
  202. package/dist/lib/index.js.map +1 -0
  203. package/dist/lib/input-format.d.ts +249 -0
  204. package/dist/lib/input-format.js +306 -0
  205. package/dist/lib/input-format.js.map +1 -0
  206. package/dist/lib/io-context.d.ts +696 -0
  207. package/dist/lib/io-context.js +769 -0
  208. package/dist/lib/io-context.js.map +1 -0
  209. package/dist/lib/log.d.ts +174 -0
  210. package/dist/lib/log.js +184 -0
  211. package/dist/lib/log.js.map +1 -0
  212. package/dist/lib/native-types.d.ts +946 -0
  213. package/dist/lib/native-types.js +2 -0
  214. package/dist/lib/native-types.js.map +1 -0
  215. package/dist/lib/option.d.ts +927 -0
  216. package/dist/lib/option.js +1583 -0
  217. package/dist/lib/option.js.map +1 -0
  218. package/dist/lib/output-format.d.ts +180 -0
  219. package/dist/lib/output-format.js +213 -0
  220. package/dist/lib/output-format.js.map +1 -0
  221. package/dist/lib/packet.d.ts +501 -0
  222. package/dist/lib/packet.js +590 -0
  223. package/dist/lib/packet.js.map +1 -0
  224. package/dist/lib/rational.d.ts +251 -0
  225. package/dist/lib/rational.js +278 -0
  226. package/dist/lib/rational.js.map +1 -0
  227. package/dist/lib/software-resample-context.d.ts +552 -0
  228. package/dist/lib/software-resample-context.js +592 -0
  229. package/dist/lib/software-resample-context.js.map +1 -0
  230. package/dist/lib/software-scale-context.d.ts +344 -0
  231. package/dist/lib/software-scale-context.js +366 -0
  232. package/dist/lib/software-scale-context.js.map +1 -0
  233. package/dist/lib/stream.d.ts +379 -0
  234. package/dist/lib/stream.js +526 -0
  235. package/dist/lib/stream.js.map +1 -0
  236. package/dist/lib/sync-queue.d.ts +179 -0
  237. package/dist/lib/sync-queue.js +197 -0
  238. package/dist/lib/sync-queue.js.map +1 -0
  239. package/dist/lib/types.d.ts +34 -0
  240. package/dist/lib/types.js +2 -0
  241. package/dist/lib/types.js.map +1 -0
  242. package/dist/lib/utilities.d.ts +1127 -0
  243. package/dist/lib/utilities.js +1225 -0
  244. package/dist/lib/utilities.js.map +1 -0
  245. package/dist/utils/electron.d.ts +49 -0
  246. package/dist/utils/electron.js +63 -0
  247. package/dist/utils/electron.js.map +1 -0
  248. package/dist/utils/index.d.ts +4 -0
  249. package/dist/utils/index.js +5 -0
  250. package/dist/utils/index.js.map +1 -0
  251. package/install/check.js +121 -0
  252. package/install/ffmpeg.js +66 -0
  253. package/jellyfin-ffmpeg.patch +181 -0
  254. package/package.json +129 -0
@@ -0,0 +1,1583 @@
1
+ import { AV_OPT_SEARCH_CHILDREN, AV_OPT_TYPE_BINARY, AV_OPT_TYPE_BINARY_INT_ARRAY, AV_OPT_TYPE_BOOL, AV_OPT_TYPE_CHLAYOUT, AV_OPT_TYPE_COLOR, AV_OPT_TYPE_CONST, AV_OPT_TYPE_DICT, AV_OPT_TYPE_DOUBLE, AV_OPT_TYPE_DURATION, AV_OPT_TYPE_FLAGS, AV_OPT_TYPE_FLOAT, AV_OPT_TYPE_IMAGE_SIZE, AV_OPT_TYPE_INT, AV_OPT_TYPE_INT64, AV_OPT_TYPE_PIXEL_FMT, AV_OPT_TYPE_RATIONAL, AV_OPT_TYPE_SAMPLE_FMT, AV_OPT_TYPE_STRING, AV_OPT_TYPE_UINT, AV_OPT_TYPE_UINT64, AV_OPT_TYPE_VIDEO_RATE, AVFLAG_NONE, } from '../constants/constants.js';
2
+ import { bindings } from './binding.js';
3
+ import { Dictionary } from './dictionary.js';
4
+ import { FFmpegError, PosixError } from './error.js';
5
+ import { Rational } from './rational.js';
6
+ import { avGetPixFmtFromName, avGetSampleFmtFromName } from './utilities.js';
7
+ /**
8
+ * Option information descriptor.
9
+ *
10
+ * Describes a single option available on an FFmpeg object.
11
+ * Contains metadata about the option including name, type, default value,
12
+ * valid range, and documentation. Used to discover and validate options.
13
+ *
14
+ * Direct mapping to FFmpeg's AVOption.
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * import { Option } from 'node-av';
19
+ *
20
+ * // Get option info
21
+ * const optInfo = Option.find(obj, 'bitrate');
22
+ * if (optInfo) {
23
+ * console.log(`Option: ${optInfo.name}`);
24
+ * console.log(`Help: ${optInfo.help}`);
25
+ * console.log(`Type: ${optInfo.type}`);
26
+ * console.log(`Default: ${optInfo.defaultValue}`);
27
+ * console.log(`Range: ${optInfo.min} - ${optInfo.max}`);
28
+ * }
29
+ * ```
30
+ *
31
+ * @see [AVOption](https://ffmpeg.org/doxygen/trunk/structAVOption.html) - FFmpeg Doxygen
32
+ */
33
+ export class OptionInfo {
34
+ native;
35
+ /**
36
+ * @param native - The native option instance
37
+ *
38
+ * @internal
39
+ */
40
+ constructor(native) {
41
+ this.native = native;
42
+ }
43
+ /**
44
+ * Option name.
45
+ *
46
+ * The name used to get/set this option.
47
+ *
48
+ * Direct mapping to AVOption->name.
49
+ */
50
+ get name() {
51
+ return this.native.name;
52
+ }
53
+ /**
54
+ * Option help text.
55
+ *
56
+ * Human-readable description of the option's purpose.
57
+ *
58
+ * Direct mapping to AVOption->help.
59
+ */
60
+ get help() {
61
+ return this.native.help;
62
+ }
63
+ /**
64
+ * Option type.
65
+ *
66
+ * Data type of the option value (AV_OPT_TYPE_*).
67
+ *
68
+ * Direct mapping to AVOption->type.
69
+ */
70
+ get type() {
71
+ return this.native.type;
72
+ }
73
+ /**
74
+ * Default value.
75
+ *
76
+ * The default value for this option.
77
+ * Type depends on the option type.
78
+ *
79
+ * Direct mapping to AVOption->default_val.
80
+ */
81
+ get defaultValue() {
82
+ return this.native.defaultValue;
83
+ }
84
+ /**
85
+ * Minimum value.
86
+ *
87
+ * Minimum valid value for numeric options.
88
+ *
89
+ * Direct mapping to AVOption->min.
90
+ */
91
+ get min() {
92
+ return this.native.min;
93
+ }
94
+ /**
95
+ * Maximum value.
96
+ *
97
+ * Maximum valid value for numeric options.
98
+ *
99
+ * Direct mapping to AVOption->max.
100
+ */
101
+ get max() {
102
+ return this.native.max;
103
+ }
104
+ /**
105
+ * Option flags.
106
+ *
107
+ * Combination of AV_OPT_FLAG_* indicating option properties.
108
+ *
109
+ * Direct mapping to AVOption->flags.
110
+ */
111
+ get flags() {
112
+ return this.native.flags;
113
+ }
114
+ /**
115
+ * Check if option has specific flags.
116
+ *
117
+ * Tests whether all specified flags are set using bitwise AND.
118
+ *
119
+ * @param flags - One or more flag values to check
120
+ *
121
+ * @returns true if all specified flags are set, false otherwise
122
+ *
123
+ * @example
124
+ * ```typescript
125
+ * import { AV_OPT_FLAG_ENCODING_PARAM } from 'node-av/constants';
126
+ *
127
+ * if (option.hasFlags(AV_OPT_FLAG_ENCODING_PARAM)) {
128
+ * console.log('This option is used for encoding');
129
+ * }
130
+ * ```
131
+ *
132
+ * @see {@link flags} For direct flags access
133
+ */
134
+ hasFlags(...flags) {
135
+ for (const flag of flags) {
136
+ if ((this.native.flags & flag) !== flag) {
137
+ return false;
138
+ }
139
+ }
140
+ return true;
141
+ }
142
+ /**
143
+ * Option unit.
144
+ *
145
+ * Unit string for grouping related options.
146
+ *
147
+ * Direct mapping to AVOption->unit.
148
+ */
149
+ get unit() {
150
+ return this.native.unit;
151
+ }
152
+ /**
153
+ * Get the underlying native Option object.
154
+ *
155
+ * @returns The native Option binding object
156
+ *
157
+ * @internal
158
+ */
159
+ getNative() {
160
+ return this.native;
161
+ }
162
+ }
163
+ /**
164
+ * FFmpeg option management utilities.
165
+ *
166
+ * Provides static methods for getting, setting, and querying options
167
+ * on FFmpeg objects that support the AVOption API. Handles type conversion
168
+ * and validation for various option types including strings, numbers,
169
+ * rationals, pixel formats, and more.
170
+ *
171
+ * Direct mapping to FFmpeg's AVOption API.
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * import { Option, FFmpegError } from 'node-av';
176
+ * import { AV_OPT_SEARCH_CHILDREN, AV_PIX_FMT_YUV420P } from 'node-av/constants';
177
+ *
178
+ * // Set various option types
179
+ * let ret = Option.set(obj, 'preset', 'fast');
180
+ * FFmpegError.throwIfError(ret, 'set preset');
181
+ *
182
+ * ret = Option.setInt(obj, 'bitrate', 2000000);
183
+ * FFmpegError.throwIfError(ret, 'set bitrate');
184
+ *
185
+ * ret = Option.setRational(obj, 'framerate', { num: 30, den: 1 });
186
+ * FFmpegError.throwIfError(ret, 'set framerate');
187
+ *
188
+ * // Get option values
189
+ * const preset = Option.get(obj, 'preset');
190
+ * const bitrate = Option.getInt(obj, 'bitrate');
191
+ * const framerate = Option.getRational(obj, 'framerate');
192
+ *
193
+ * // List all options
194
+ * let opt = null;
195
+ * while ((opt = Option.next(obj, opt))) {
196
+ * console.log(`${opt.name}: ${opt.help}`);
197
+ * }
198
+ * ```
199
+ *
200
+ * @see [AVOption API](https://ffmpeg.org/doxygen/trunk/group__avoptions.html) - FFmpeg Doxygen
201
+ * @see {@link OptionMember} For inherited option support
202
+ */
203
+ export class Option {
204
+ /**
205
+ * Iterate to next option.
206
+ *
207
+ * Iterates through available options on an object.
208
+ *
209
+ * Direct mapping to av_opt_next().
210
+ *
211
+ * @param obj - Object with options
212
+ *
213
+ * @param prev - Previous option (null to get first)
214
+ *
215
+ * @returns Next option, or null if no more
216
+ *
217
+ * @example
218
+ * ```typescript
219
+ * let opt = null;
220
+ * while ((opt = Option.next(obj, opt))) {
221
+ * console.log(`Option: ${opt.name}`);
222
+ * }
223
+ * ```
224
+ */
225
+ static next(obj, prev = null) {
226
+ const result = bindings.Option.next(obj, prev?.getNative());
227
+ return result ? new OptionInfo(result) : null;
228
+ }
229
+ /**
230
+ * Find option by name.
231
+ *
232
+ * Searches for an option with the specified name.
233
+ *
234
+ * Direct mapping to av_opt_find().
235
+ *
236
+ * @param obj - Object to search
237
+ *
238
+ * @param name - Option name
239
+ *
240
+ * @param searchFlags - Search flags
241
+ *
242
+ * @returns Option info if found, null otherwise
243
+ *
244
+ * @example
245
+ * ```typescript
246
+ * const opt = Option.find(obj, 'bitrate');
247
+ * if (opt) {
248
+ * console.log(`Found: ${opt.name}, Type: ${opt.type}`);
249
+ * }
250
+ * ```
251
+ */
252
+ static find(obj, name, searchFlags = AVFLAG_NONE) {
253
+ const result = bindings.Option.find(obj, name, searchFlags);
254
+ return result ? new OptionInfo(result) : null;
255
+ }
256
+ /**
257
+ * Find option with target info.
258
+ *
259
+ * Like find() but also indicates if option was found on different target.
260
+ *
261
+ * Direct mapping to av_opt_find2().
262
+ *
263
+ * @param obj - Object to search
264
+ *
265
+ * @param name - Option name
266
+ *
267
+ * @param searchFlags - Search flags
268
+ *
269
+ * @returns Object with option and target info
270
+ *
271
+ * @example
272
+ * ```typescript
273
+ * const result = Option.find2(obj, 'bitrate', AV_OPT_SEARCH_CHILDREN);
274
+ * if (result?.option) {
275
+ * console.log(`Found on ${result.isDifferentTarget ? 'child' : 'object'}`);
276
+ * }
277
+ * ```
278
+ */
279
+ static find2(obj, name, searchFlags = AVFLAG_NONE) {
280
+ const result = bindings.Option.find2(obj, name, searchFlags);
281
+ if (!result)
282
+ return null;
283
+ return {
284
+ option: result.option ? new OptionInfo(result.option) : null,
285
+ isDifferentTarget: result.isDifferentTarget,
286
+ };
287
+ }
288
+ /**
289
+ * Get string option value.
290
+ *
291
+ * Direct mapping to av_opt_get().
292
+ *
293
+ * @param obj - Object to query
294
+ *
295
+ * @param name - Option name
296
+ *
297
+ * @param searchFlags - Search flags
298
+ *
299
+ * @returns Option value as string, or null
300
+ *
301
+ * @example
302
+ * ```typescript
303
+ * // Get codec preset option
304
+ * const preset = Option.get(codecContext, 'preset', AV_OPT_SEARCH_CHILDREN);
305
+ * console.log('Codec preset:', preset); // 'medium', 'fast', etc.
306
+ * ```
307
+ */
308
+ static get(obj, name, searchFlags = AVFLAG_NONE) {
309
+ return bindings.Option.get(obj, name, searchFlags);
310
+ }
311
+ /**
312
+ * Get integer option value.
313
+ *
314
+ * Direct mapping to av_opt_get_int().
315
+ *
316
+ * @param obj - Object to query
317
+ *
318
+ * @param name - Option name
319
+ *
320
+ * @param searchFlags - Search flags
321
+ *
322
+ * @returns Option value as integer, or null
323
+ *
324
+ * @example
325
+ * ```typescript
326
+ * // Get codec GOP size
327
+ * const gopSize = Option.getInt(codecContext, 'g', AV_OPT_SEARCH_CHILDREN);
328
+ * console.log('GOP size:', gopSize); // 60, 120, etc.
329
+ * ```
330
+ */
331
+ static getInt(obj, name, searchFlags = AVFLAG_NONE) {
332
+ return bindings.Option.getInt(obj, name, searchFlags);
333
+ }
334
+ /**
335
+ * Get double option value.
336
+ *
337
+ * Direct mapping to av_opt_get_double().
338
+ *
339
+ * @param obj - Object to query
340
+ *
341
+ * @param name - Option name
342
+ *
343
+ * @param searchFlags - Search flags
344
+ *
345
+ * @returns Option value as double, or null
346
+ *
347
+ * @example
348
+ * ```typescript
349
+ * // Get codec quality scale
350
+ * const crf = Option.getDouble(codecContext, 'crf', AV_OPT_SEARCH_CHILDREN);
351
+ * console.log('CRF value:', crf); // 23.0, 18.0, etc.
352
+ * ```
353
+ */
354
+ static getDouble(obj, name, searchFlags = AVFLAG_NONE) {
355
+ return bindings.Option.getDouble(obj, name, searchFlags);
356
+ }
357
+ /**
358
+ * Get rational option value.
359
+ *
360
+ * Direct mapping to av_opt_get_q().
361
+ *
362
+ * @param obj - Object to query
363
+ *
364
+ * @param name - Option name
365
+ *
366
+ * @param searchFlags - Search flags
367
+ *
368
+ * @returns Option value as rational, or null
369
+ *
370
+ * @example
371
+ * ```typescript
372
+ * // Get codec time base
373
+ * const timeBase = Option.getRational(codecContext, 'time_base', AV_OPT_SEARCH_CHILDREN);
374
+ * console.log('Time base:', timeBase); // { num: 1, den: 30 }
375
+ * ```
376
+ */
377
+ static getRational(obj, name, searchFlags = AVFLAG_NONE) {
378
+ return bindings.Option.getRational(obj, name, searchFlags);
379
+ }
380
+ /**
381
+ * Get pixel format option value.
382
+ *
383
+ * Direct mapping to av_opt_get_pixel_fmt().
384
+ *
385
+ * @param obj - Object to query
386
+ *
387
+ * @param name - Option name
388
+ *
389
+ * @param searchFlags - Search flags
390
+ *
391
+ * @returns Pixel format value, or null
392
+ *
393
+ * @example
394
+ * ```typescript
395
+ * // Get filter pixel format
396
+ * const pixFmt = Option.getPixelFormat(filterContext, 'pix_fmt', AV_OPT_SEARCH_CHILDREN);
397
+ * console.log('Pixel format:', pixFmt); // AV_PIX_FMT_YUV420P, etc.
398
+ * ```
399
+ */
400
+ static getPixelFormat(obj, name, searchFlags = AVFLAG_NONE) {
401
+ return bindings.Option.getPixelFormat(obj, name, searchFlags);
402
+ }
403
+ /**
404
+ * Get sample format option value.
405
+ *
406
+ * Direct mapping to av_opt_get_sample_fmt().
407
+ *
408
+ * @param obj - Object to query
409
+ *
410
+ * @param name - Option name
411
+ *
412
+ * @param searchFlags - Search flags
413
+ *
414
+ * @returns Sample format value, or null
415
+ *
416
+ * @example
417
+ * ```typescript
418
+ * // Get audio codec sample format
419
+ * const sampleFmt = Option.getSampleFormat(codecContext, 'sample_fmt', AV_OPT_SEARCH_CHILDREN);
420
+ * console.log('Sample format:', sampleFmt); // AV_SAMPLE_FMT_FLTP, etc.
421
+ * ```
422
+ */
423
+ static getSampleFormat(obj, name, searchFlags = AVFLAG_NONE) {
424
+ return bindings.Option.getSampleFormat(obj, name, searchFlags);
425
+ }
426
+ /**
427
+ * Get image size option value.
428
+ *
429
+ * Direct mapping to av_opt_get_image_size().
430
+ *
431
+ * @param obj - Object to query
432
+ *
433
+ * @param name - Option name
434
+ *
435
+ * @param searchFlags - Search flags
436
+ *
437
+ * @returns Width and height, or null
438
+ *
439
+ * @example
440
+ * ```typescript
441
+ * // Get filter output size
442
+ * const size = Option.getImageSize(filterContext, 'size', AV_OPT_SEARCH_CHILDREN);
443
+ * console.log('Output size:', size); // { width: 1920, height: 1080 }
444
+ * ```
445
+ */
446
+ static getImageSize(obj, name, searchFlags = AVFLAG_NONE) {
447
+ return bindings.Option.getImageSize(obj, name, searchFlags);
448
+ }
449
+ /**
450
+ * Get channel layout option value.
451
+ *
452
+ * Direct mapping to av_opt_get_chlayout().
453
+ *
454
+ * @param obj - Object to query
455
+ *
456
+ * @param name - Option name
457
+ *
458
+ * @param searchFlags - Search flags
459
+ *
460
+ * @returns Channel layout, or null
461
+ *
462
+ * @example
463
+ * ```typescript
464
+ * // Get audio channel layout
465
+ * const layout = Option.getChannelLayout(codecContext, 'channel_layout', AV_OPT_SEARCH_CHILDREN);
466
+ * console.log('Channel layout:', layout); // stereo, 5.1, etc.
467
+ * ```
468
+ */
469
+ static getChannelLayout(obj, name, searchFlags = AVFLAG_NONE) {
470
+ return bindings.Option.getChannelLayout(obj, name, searchFlags);
471
+ }
472
+ /**
473
+ * Get dictionary option value.
474
+ *
475
+ * Direct mapping to av_opt_get_dict_val().
476
+ *
477
+ * @param obj - Object to query
478
+ *
479
+ * @param name - Option name
480
+ *
481
+ * @param searchFlags - Search flags
482
+ *
483
+ * @returns Dictionary value, or null
484
+ *
485
+ * @example
486
+ * ```typescript
487
+ * // Get metadata dictionary
488
+ * const metadata = Option.getDict(formatContext, 'metadata', AV_OPT_SEARCH_CHILDREN);
489
+ * console.log('Metadata:', metadata?.get('title'));
490
+ * ```
491
+ */
492
+ static getDict(obj, name, searchFlags = AVFLAG_NONE) {
493
+ const native = bindings.Option.getDict(obj, name, searchFlags);
494
+ return native ? Dictionary.fromNative(native) : null;
495
+ }
496
+ /**
497
+ * Set string option value.
498
+ *
499
+ * Direct mapping to av_opt_set().
500
+ *
501
+ * @param obj - Object to modify
502
+ *
503
+ * @param name - Option name
504
+ *
505
+ * @param value - String value
506
+ *
507
+ * @param searchFlags - Search flags
508
+ *
509
+ * @returns 0 on success, negative AVERROR on error
510
+ *
511
+ * @example
512
+ * ```typescript
513
+ * // Set codec preset
514
+ * const ret = Option.set(codecContext, 'preset', 'fast', AV_OPT_SEARCH_CHILDREN);
515
+ * FFmpegError.throwIfError(ret, 'Failed to set preset');
516
+ * ```
517
+ */
518
+ static set(obj, name, value, searchFlags = AVFLAG_NONE) {
519
+ return bindings.Option.set(obj, name, value, searchFlags);
520
+ }
521
+ /**
522
+ * Set integer option value.
523
+ *
524
+ * Direct mapping to av_opt_set_int().
525
+ *
526
+ * @param obj - Object to modify
527
+ *
528
+ * @param name - Option name
529
+ *
530
+ * @param value - Integer value
531
+ *
532
+ * @param searchFlags - Search flags
533
+ *
534
+ * @returns 0 on success, negative AVERROR on error
535
+ *
536
+ * @example
537
+ * ```typescript
538
+ * // Set codec bitrate
539
+ * const ret = Option.setInt(codecContext, 'b', 2000000, AV_OPT_SEARCH_CHILDREN);
540
+ * FFmpegError.throwIfError(ret, 'Failed to set bitrate');
541
+ * ```
542
+ */
543
+ static setInt(obj, name, value, searchFlags = AVFLAG_NONE) {
544
+ return bindings.Option.setInt(obj, name, value, searchFlags);
545
+ }
546
+ /**
547
+ * Set double option value.
548
+ *
549
+ * Direct mapping to av_opt_set_double().
550
+ *
551
+ * @param obj - Object to modify
552
+ *
553
+ * @param name - Option name
554
+ *
555
+ * @param value - Double value
556
+ *
557
+ * @param searchFlags - Search flags
558
+ *
559
+ * @returns 0 on success, negative AVERROR on error
560
+ *
561
+ * @example
562
+ * ```typescript
563
+ * // Set codec CRF value
564
+ * const ret = Option.setDouble(codecContext, 'crf', 23.0, AV_OPT_SEARCH_CHILDREN);
565
+ * FFmpegError.throwIfError(ret, 'Failed to set CRF');
566
+ * ```
567
+ */
568
+ static setDouble(obj, name, value, searchFlags = AVFLAG_NONE) {
569
+ return bindings.Option.setDouble(obj, name, value, searchFlags);
570
+ }
571
+ /**
572
+ * Set rational option value.
573
+ *
574
+ * Direct mapping to av_opt_set_q().
575
+ *
576
+ * @param obj - Object to modify
577
+ *
578
+ * @param name - Option name
579
+ *
580
+ * @param value - Rational value
581
+ *
582
+ * @param searchFlags - Search flags
583
+ *
584
+ * @returns 0 on success, negative AVERROR on error
585
+ *
586
+ * @example
587
+ * ```typescript
588
+ * // Set codec frame rate
589
+ * const ret = Option.setRational(codecContext, 'framerate', { num: 30, den: 1 }, AV_OPT_SEARCH_CHILDREN);
590
+ * FFmpegError.throwIfError(ret, 'Failed to set framerate');
591
+ * ```
592
+ */
593
+ static setRational(obj, name, value, searchFlags = AVFLAG_NONE) {
594
+ return bindings.Option.setRational(obj, name, value, searchFlags);
595
+ }
596
+ /**
597
+ * Set pixel format option value.
598
+ *
599
+ * Direct mapping to av_opt_set_pixel_fmt().
600
+ *
601
+ * @param obj - Object to modify
602
+ *
603
+ * @param name - Option name
604
+ *
605
+ * @param value - Pixel format
606
+ *
607
+ * @param searchFlags - Search flags
608
+ *
609
+ * @returns 0 on success, negative AVERROR on error
610
+ *
611
+ * @example
612
+ * ```typescript
613
+ * // Set filter pixel format
614
+ * const ret = Option.setPixelFormat(filterContext, 'pix_fmt', AV_PIX_FMT_YUV420P, AV_OPT_SEARCH_CHILDREN);
615
+ * FFmpegError.throwIfError(ret, 'Failed to set pixel format');
616
+ * ```
617
+ */
618
+ static setPixelFormat(obj, name, value, searchFlags = AVFLAG_NONE) {
619
+ return bindings.Option.setPixelFormat(obj, name, value, searchFlags);
620
+ }
621
+ /**
622
+ * Set sample format option value.
623
+ *
624
+ * Direct mapping to av_opt_set_sample_fmt().
625
+ *
626
+ * @param obj - Object to modify
627
+ *
628
+ * @param name - Option name
629
+ *
630
+ * @param value - Sample format
631
+ *
632
+ * @param searchFlags - Search flags
633
+ *
634
+ * @returns 0 on success, negative AVERROR on error
635
+ *
636
+ * @example
637
+ * ```typescript
638
+ * // Set audio codec sample format
639
+ * const ret = Option.setSampleFormat(codecContext, 'sample_fmt', AV_SAMPLE_FMT_FLTP, AV_OPT_SEARCH_CHILDREN);
640
+ * FFmpegError.throwIfError(ret, 'Failed to set sample format');
641
+ * ```
642
+ */
643
+ static setSampleFormat(obj, name, value, searchFlags = AVFLAG_NONE) {
644
+ return bindings.Option.setSampleFormat(obj, name, value, searchFlags);
645
+ }
646
+ /**
647
+ * Set image size option value.
648
+ *
649
+ * Direct mapping to av_opt_set_image_size().
650
+ *
651
+ * @param obj - Object to modify
652
+ *
653
+ * @param name - Option name
654
+ *
655
+ * @param width - Image width
656
+ *
657
+ * @param height - Image height
658
+ *
659
+ * @param searchFlags - Search flags
660
+ *
661
+ * @returns 0 on success, negative AVERROR on error
662
+ *
663
+ * @example
664
+ * ```typescript
665
+ * // Set filter output size
666
+ * const ret = Option.setImageSize(filterContext, 'size', 1920, 1080, AV_OPT_SEARCH_CHILDREN);
667
+ * FFmpegError.throwIfError(ret, 'Failed to set image size');
668
+ * ```
669
+ */
670
+ static setImageSize(obj, name, width, height, searchFlags = AVFLAG_NONE) {
671
+ return bindings.Option.setImageSize(obj, name, width, height, searchFlags);
672
+ }
673
+ /**
674
+ * Set channel layout option value.
675
+ *
676
+ * Direct mapping to av_opt_set_chlayout().
677
+ *
678
+ * @param obj - Object to modify
679
+ *
680
+ * @param name - Option name
681
+ *
682
+ * @param value - Channel layout
683
+ *
684
+ * @param searchFlags - Search flags
685
+ *
686
+ * @returns 0 on success, negative AVERROR on error
687
+ *
688
+ * @example
689
+ * ```typescript
690
+ * // Set audio channel layout to stereo
691
+ * const ret = Option.setChannelLayout(codecContext, 'channel_layout', AV_CHANNEL_LAYOUT_STEREO, AV_OPT_SEARCH_CHILDREN);
692
+ * FFmpegError.throwIfError(ret, 'Failed to set channel layout');
693
+ * ```
694
+ */
695
+ static setChannelLayout(obj, name, value, searchFlags = AVFLAG_NONE) {
696
+ return bindings.Option.setChannelLayout(obj, name, value, searchFlags);
697
+ }
698
+ /**
699
+ * Set dictionary option value.
700
+ *
701
+ * Direct mapping to av_opt_set_dict_val().
702
+ *
703
+ * @param obj - Object to modify
704
+ *
705
+ * @param name - Option name
706
+ *
707
+ * @param value - Dictionary value
708
+ *
709
+ * @param searchFlags - Search flags
710
+ *
711
+ * @returns 0 on success, negative AVERROR on error
712
+ *
713
+ * @example
714
+ * ```typescript
715
+ * // Set metadata dictionary
716
+ * const dict = new Dictionary();
717
+ * dict.set('title', 'My Video');
718
+ * const ret = Option.setDict(formatContext, 'metadata', dict, AV_OPT_SEARCH_CHILDREN);
719
+ * FFmpegError.throwIfError(ret, 'Failed to set metadata');
720
+ * ```
721
+ */
722
+ static setDict(obj, name, value, searchFlags = AVFLAG_NONE) {
723
+ return bindings.Option.setDict(obj, name, value.getNative(), searchFlags);
724
+ }
725
+ /**
726
+ * Set binary option value.
727
+ *
728
+ * Direct mapping to av_opt_set_bin().
729
+ *
730
+ * @param obj - Object to modify
731
+ *
732
+ * @param name - Option name
733
+ *
734
+ * @param value - Binary data
735
+ *
736
+ * @param searchFlags - Search flags
737
+ *
738
+ * @returns 0 on success, negative AVERROR on error
739
+ *
740
+ * @example
741
+ * ```typescript
742
+ * // Set binary extradata
743
+ * const extradata = Buffer.from([0x00, 0x01, 0x02, 0x03]);
744
+ * const ret = Option.setBin(codecContext, 'extradata', extradata, AV_OPT_SEARCH_CHILDREN);
745
+ * FFmpegError.throwIfError(ret, 'Failed to set extradata');
746
+ * ```
747
+ */
748
+ static setBin(obj, name, value, searchFlags = AVFLAG_NONE) {
749
+ return bindings.Option.setBin(obj, name, value, searchFlags);
750
+ }
751
+ /**
752
+ * Set defaults on object.
753
+ *
754
+ * Sets all options to their default values.
755
+ *
756
+ * Direct mapping to av_opt_set_defaults().
757
+ *
758
+ * @param obj - Object to reset
759
+ *
760
+ * @example
761
+ * ```typescript
762
+ * // Reset all codec options to defaults
763
+ * Option.setDefaults(codecContext);
764
+ * ```
765
+ */
766
+ static setDefaults(obj) {
767
+ bindings.Option.setDefaults(obj);
768
+ }
769
+ /**
770
+ * Copy options between objects.
771
+ *
772
+ * Copies option values from source to destination.
773
+ *
774
+ * Direct mapping to av_opt_copy().
775
+ *
776
+ * @param dest - Destination object
777
+ *
778
+ * @param src - Source object
779
+ *
780
+ * @returns 0 on success, negative AVERROR on error
781
+ *
782
+ * @example
783
+ * ```typescript
784
+ * // Copy options from one codec context to another
785
+ * const ret = Option.copy(destCodecContext, srcCodecContext);
786
+ * FFmpegError.throwIfError(ret, 'Failed to copy options');
787
+ * ```
788
+ */
789
+ static copy(dest, src) {
790
+ return bindings.Option.copy(dest, src);
791
+ }
792
+ /**
793
+ * Check if option is set to default.
794
+ *
795
+ * Direct mapping to av_opt_is_set_to_default().
796
+ *
797
+ * @param obj - Object to check
798
+ *
799
+ * @param name - Option name
800
+ *
801
+ * @param searchFlags - Search flags
802
+ *
803
+ * @returns True if default, false if modified, null if not found
804
+ *
805
+ * @example
806
+ * ```typescript
807
+ * // Check if bitrate is at default value
808
+ * const isDefault = Option.isSetToDefault(codecContext, 'b', AV_OPT_SEARCH_CHILDREN);
809
+ * console.log('Bitrate is default:', isDefault);
810
+ * ```
811
+ */
812
+ static isSetToDefault(obj, name, searchFlags = AVFLAG_NONE) {
813
+ return bindings.Option.isSetToDefault(obj, name, searchFlags);
814
+ }
815
+ /**
816
+ * Serialize options to string.
817
+ *
818
+ * Direct mapping to av_opt_serialize().
819
+ *
820
+ * @param obj - Object to serialize
821
+ *
822
+ * @param optFlags - Option flags filter
823
+ *
824
+ * @param flags - Serialization flags
825
+ *
826
+ * @param keyValSep - Key-value separator
827
+ *
828
+ * @param pairsSep - Pairs separator
829
+ *
830
+ * @returns Serialized string, or null on error
831
+ *
832
+ * @example
833
+ * ```typescript
834
+ * // Serialize codec options to string
835
+ * const serialized = Option.serialize(codecContext, 0, 0, '=', ':');
836
+ * console.log('Options:', serialized); // 'bitrate=2000000:preset=fast'
837
+ * ```
838
+ */
839
+ static serialize(obj, optFlags = 0, flags = 0, keyValSep = '=', pairsSep = ',') {
840
+ return bindings.Option.serialize(obj, optFlags, flags, keyValSep, pairsSep);
841
+ }
842
+ /**
843
+ * Free option resources.
844
+ *
845
+ * Direct mapping to av_opt_free().
846
+ *
847
+ * @param obj - Object to free options from
848
+ *
849
+ * @example
850
+ * ```typescript
851
+ * // Free codec context options
852
+ * Option.free(codecContext);
853
+ * ```
854
+ */
855
+ static free(obj) {
856
+ bindings.Option.free(obj);
857
+ }
858
+ /**
859
+ * Show options for debugging.
860
+ *
861
+ * Direct mapping to av_opt_show2().
862
+ *
863
+ * @param obj - Object to show options for
864
+ *
865
+ * @param reqFlags - Required flags
866
+ *
867
+ * @param rejFlags - Rejected flags
868
+ *
869
+ * @returns 0 on success, negative AVERROR on error
870
+ *
871
+ * @example
872
+ * ```typescript
873
+ * // Show all codec options for debugging
874
+ * const ret = Option.show(codecContext, 0, 0);
875
+ * FFmpegError.throwIfError(ret, 'Failed to show options');
876
+ * ```
877
+ */
878
+ static show(obj, reqFlags = 0, rejFlags = 0) {
879
+ return bindings.Option.show(obj, reqFlags, rejFlags);
880
+ }
881
+ }
882
+ /**
883
+ * Base class for FFmpeg objects that support AVOptions.
884
+ *
885
+ * Provides a common interface for getting, setting, and listing options
886
+ * on FFmpeg objects that have an AVClass structure. This includes codecs,
887
+ * formats, filters, and various processing contexts.
888
+ *
889
+ * Classes that support AVOptions should extend this class to inherit
890
+ * the option management functionality.
891
+ *
892
+ * @template T - The native FFmpeg object type that supports AVOptions
893
+ *
894
+ * @example
895
+ * ```typescript
896
+ * import { OptionMember, FFmpegError } from 'node-av';
897
+ * import { AV_OPT_TYPE_INT, AV_OPT_TYPE_STRING, AV_OPT_TYPE_RATIONAL } from 'node-av/constants';
898
+ *
899
+ * class CodecContext extends OptionMember<NativeCodecContext> {
900
+ * constructor(native: NativeCodecContext) {
901
+ * super(native);
902
+ * }
903
+ * }
904
+ *
905
+ * // Use inherited methods
906
+ * const codec = new CodecContext(native);
907
+ *
908
+ * // Set options with automatic type handling
909
+ * let ret = codec.setOption('preset', 'fast');
910
+ * FFmpegError.throwIfError(ret, 'set preset');
911
+ *
912
+ * ret = codec.setOption('bitrate', 2000000, AV_OPT_TYPE_INT);
913
+ * FFmpegError.throwIfError(ret, 'set bitrate');
914
+ *
915
+ * ret = codec.setOption('framerate', { num: 30, den: 1 }, AV_OPT_TYPE_RATIONAL);
916
+ * FFmpegError.throwIfError(ret, 'set framerate');
917
+ *
918
+ * // Get typed options
919
+ * const preset = codec.getOption('preset');
920
+ * const bitrate = codec.getOption('bitrate', AV_OPT_TYPE_INT);
921
+ * const framerate = codec.getOption('framerate', AV_OPT_TYPE_RATIONAL);
922
+ *
923
+ * // List all available options
924
+ * const options = codec.listOptions();
925
+ * for (const opt of options) {
926
+ * console.log(`${opt.name}: ${opt.help}`);
927
+ * }
928
+ * ```
929
+ *
930
+ * @see {@link Option} For static option methods
931
+ * @see {@link OptionInfo} For option metadata
932
+ */
933
+ export class OptionMember {
934
+ native;
935
+ constructor(native) {
936
+ this.native = native;
937
+ }
938
+ /**
939
+ * Set an option on this object.
940
+ *
941
+ * Uses the AVOption API to set options.
942
+ * Available options depend on the specific object type.
943
+ *
944
+ * Direct mapping to av_opt_set* functions.
945
+ *
946
+ * @param name - Option name
947
+ *
948
+ * @param value - Option value
949
+ *
950
+ * @param type - Option type (defaults to AV_OPT_TYPE_STRING)
951
+ *
952
+ * @param searchFlags - Search flags (default: AV_OPT_SEARCH_CHILDREN)
953
+ *
954
+ * @returns 0 on success, negative AVERROR on error:
955
+ * - AVERROR_ENOENT: Option not found
956
+ * - AVERROR_ERANGE: Value out of range
957
+ * - AVERROR_EINVAL: Invalid value
958
+ *
959
+ * @example
960
+ * ```typescript
961
+ * import { FFmpegError } from 'node-av';
962
+ * import { AV_OPT_TYPE_STRING, AV_OPT_TYPE_INT64, AV_OPT_TYPE_RATIONAL, AV_OPT_TYPE_PIXEL_FMT } from 'node-av/constants';
963
+ *
964
+ * // String options (default)
965
+ * let ret = obj.setOption('preset', 'fast');
966
+ * FFmpegError.throwIfError(ret, 'set preset');
967
+ *
968
+ * ret = obj.setOption('codec', 'h264', AV_OPT_TYPE_STRING);
969
+ * FFmpegError.throwIfError(ret, 'set codec');
970
+ *
971
+ * // Integer options
972
+ * ret = obj.setOption('bitrate', 2000000, AV_OPT_TYPE_INT64);
973
+ * FFmpegError.throwIfError(ret, 'set bitrate');
974
+ *
975
+ * ret = obj.setOption('threads', 4, AV_OPT_TYPE_INT);
976
+ * FFmpegError.throwIfError(ret, 'set threads');
977
+ *
978
+ * // Complex types with proper types
979
+ * ret = obj.setOption('framerate', {num: 30, den: 1}, AV_OPT_TYPE_RATIONAL);
980
+ * FFmpegError.throwIfError(ret, 'set framerate');
981
+ *
982
+ * ret = obj.setOption('pix_fmt', AV_PIX_FMT_YUV420P, AV_OPT_TYPE_PIXEL_FMT);
983
+ * FFmpegError.throwIfError(ret, 'set pixel format');
984
+ * ```
985
+ */
986
+ setOption(name, value, type = AV_OPT_TYPE_STRING, searchFlags = AV_OPT_SEARCH_CHILDREN) {
987
+ if (value === undefined || value === null) {
988
+ return 0;
989
+ }
990
+ // Do we need to infer type? FFmpeg can handle unknown options
991
+ if (type === undefined) {
992
+ return this.setUnknownOption(name, value);
993
+ }
994
+ // searchFlags ??= AV_OPT_SEARCH_CHILDREN;
995
+ switch (type) {
996
+ case AV_OPT_TYPE_STRING:
997
+ case AV_OPT_TYPE_COLOR: // Colors are set as strings
998
+ return Option.set(this.native, name, String(value), searchFlags);
999
+ case AV_OPT_TYPE_INT:
1000
+ const intVal = Number(value);
1001
+ if (!Number.isInteger(intVal)) {
1002
+ throw new TypeError(`Option '${name}': Expected integer value, got ${value}`);
1003
+ }
1004
+ return Option.setInt(this.native, name, intVal, searchFlags);
1005
+ case AV_OPT_TYPE_UINT:
1006
+ const uintVal = Number(value);
1007
+ if (!Number.isInteger(uintVal) || uintVal < 0) {
1008
+ throw new RangeError(`Option '${name}': Expected non-negative integer value, got ${value}`);
1009
+ }
1010
+ return Option.setInt(this.native, name, uintVal, searchFlags);
1011
+ case AV_OPT_TYPE_FLAGS:
1012
+ case AV_OPT_TYPE_DURATION:
1013
+ case AV_OPT_TYPE_CONST:
1014
+ return Option.setInt(this.native, name, Number(value), searchFlags);
1015
+ case AV_OPT_TYPE_BOOL:
1016
+ // Convert to 0 or 1 for FFmpeg
1017
+ return Option.setInt(this.native, name, value ? 1 : 0, searchFlags);
1018
+ case AV_OPT_TYPE_INT64:
1019
+ // Accept both bigint and number
1020
+ if (typeof value === 'bigint') {
1021
+ return Option.setInt(this.native, name, value, searchFlags);
1022
+ }
1023
+ else if (typeof value === 'number') {
1024
+ if (!Number.isInteger(value)) {
1025
+ throw new TypeError(`Option '${name}': Expected integer value for INT64, got ${value}`);
1026
+ }
1027
+ return Option.setInt(this.native, name, value, searchFlags);
1028
+ }
1029
+ else {
1030
+ throw new TypeError(`Option '${name}': Expected bigint or number for INT64, got ${typeof value}`);
1031
+ }
1032
+ case AV_OPT_TYPE_UINT64:
1033
+ // Accept both bigint and number, but must be non-negative
1034
+ if (typeof value === 'bigint') {
1035
+ if (value < 0n) {
1036
+ throw new RangeError(`Option '${name}': Expected non-negative value for UINT64, got ${value}`);
1037
+ }
1038
+ return Option.setInt(this.native, name, value, searchFlags);
1039
+ }
1040
+ else if (typeof value === 'number') {
1041
+ if (!Number.isInteger(value) || value < 0) {
1042
+ throw new RangeError(`Option '${name}': Expected non-negative integer for UINT64, got ${value}`);
1043
+ }
1044
+ return Option.setInt(this.native, name, value, searchFlags);
1045
+ }
1046
+ else {
1047
+ throw new TypeError(`Option '${name}': Expected bigint or number for UINT64, got ${typeof value}`);
1048
+ }
1049
+ case AV_OPT_TYPE_DOUBLE:
1050
+ case AV_OPT_TYPE_FLOAT:
1051
+ return Option.setDouble(this.native, name, Number(value), searchFlags);
1052
+ case AV_OPT_TYPE_RATIONAL:
1053
+ case AV_OPT_TYPE_VIDEO_RATE:
1054
+ if (typeof value !== 'object' || !('num' in value) || !('den' in value)) {
1055
+ throw new TypeError(`Option '${name}': Expected Rational object with {num, den}, got ${JSON.stringify(value)}`);
1056
+ }
1057
+ if (value.den === 0) {
1058
+ throw new RangeError(`Option '${name}': Rational denominator cannot be zero`);
1059
+ }
1060
+ return Option.setRational(this.native, name, value, searchFlags);
1061
+ case AV_OPT_TYPE_PIXEL_FMT:
1062
+ const pixFmt = Number(value);
1063
+ if (!Number.isInteger(pixFmt)) {
1064
+ throw new TypeError(`Option '${name}': Expected integer pixel format value, got ${value}`);
1065
+ }
1066
+ return Option.setPixelFormat(this.native, name, pixFmt, searchFlags);
1067
+ case AV_OPT_TYPE_SAMPLE_FMT:
1068
+ const sampleFmt = Number(value);
1069
+ if (!Number.isInteger(sampleFmt)) {
1070
+ throw new TypeError(`Option '${name}': Expected integer sample format value, got ${value}`);
1071
+ }
1072
+ return Option.setSampleFormat(this.native, name, sampleFmt, searchFlags);
1073
+ case AV_OPT_TYPE_IMAGE_SIZE:
1074
+ // Expect value as {width, height}
1075
+ if (typeof value === 'object' && 'width' in value && 'height' in value) {
1076
+ const width = Number(value.width);
1077
+ const height = Number(value.height);
1078
+ if (!Number.isInteger(width) || width <= 0) {
1079
+ throw new RangeError(`Option '${name}': Width must be a positive integer, got ${value.width}`);
1080
+ }
1081
+ if (!Number.isInteger(height) || height <= 0) {
1082
+ throw new RangeError(`Option '${name}': Height must be a positive integer, got ${value.height}`);
1083
+ }
1084
+ return Option.setImageSize(this.native, name, width, height, searchFlags);
1085
+ }
1086
+ throw new TypeError(`Option '${name}': Expected object with {width, height}, got ${JSON.stringify(value)}`);
1087
+ case AV_OPT_TYPE_CHLAYOUT:
1088
+ return Option.setChannelLayout(this.native, name, Number(value), searchFlags);
1089
+ case AV_OPT_TYPE_BINARY:
1090
+ if (Buffer.isBuffer(value)) {
1091
+ return Option.setBin(this.native, name, value, searchFlags);
1092
+ }
1093
+ throw new Error('Invalid value for BINARY option: expected Buffer');
1094
+ case AV_OPT_TYPE_BINARY_INT_ARRAY:
1095
+ if (Array.isArray(value)) {
1096
+ // Convert array of integers to buffer
1097
+ const buffer = Buffer.allocUnsafe(value.length * 4);
1098
+ for (let i = 0; i < value.length; i++) {
1099
+ buffer.writeInt32LE(value[i], i * 4);
1100
+ }
1101
+ return Option.setBin(this.native, name, buffer, searchFlags);
1102
+ }
1103
+ throw new Error('Invalid value for BINARY_INT_ARRAY option: expected number[]');
1104
+ case AV_OPT_TYPE_DICT:
1105
+ if (value instanceof Dictionary) {
1106
+ return Option.setDict(this.native, name, value, searchFlags);
1107
+ }
1108
+ throw new Error('Invalid value for DICT option: expected Dictionary');
1109
+ default:
1110
+ // Fallback to string
1111
+ return Option.set(this.native, name, String(value), searchFlags);
1112
+ }
1113
+ }
1114
+ /**
1115
+ * Get an option value from this object.
1116
+ *
1117
+ * Uses the AVOption API to retrieve options.
1118
+ *
1119
+ * Direct mapping to av_opt_get* functions.
1120
+ *
1121
+ * @param name - Option name
1122
+ *
1123
+ * @param type - Option type (defaults to AV_OPT_TYPE_STRING)
1124
+ *
1125
+ * @param searchFlags - Search flags (default: AV_OPT_SEARCH_CHILDREN)
1126
+ *
1127
+ * @returns Option value (type depends on type parameter), or null if not found
1128
+ *
1129
+ * @example
1130
+ * ```typescript
1131
+ * import { AV_OPT_TYPE_STRING, AV_OPT_TYPE_RATIONAL, AV_OPT_TYPE_PIXEL_FMT, AV_OPT_TYPE_INT64 } from 'node-av/constants';
1132
+ *
1133
+ * // String options (default)
1134
+ * const preset = obj.getOption('preset');
1135
+ * const codec = obj.getOption('codec', AV_OPT_TYPE_STRING);
1136
+ *
1137
+ * // Typed options
1138
+ * const framerate = obj.getOption('framerate', AV_OPT_TYPE_RATIONAL); // Returns {num, den}
1139
+ * const pixFmt = obj.getOption('pix_fmt', AV_OPT_TYPE_PIXEL_FMT); // Returns AVPixelFormat
1140
+ * const bitrate = obj.getOption('bitrate', AV_OPT_TYPE_INT64); // Returns bigint
1141
+ * ```
1142
+ */
1143
+ getOption(name, type = AV_OPT_TYPE_STRING, searchFlags = AV_OPT_SEARCH_CHILDREN) {
1144
+ // Use specific getter based on type
1145
+ switch (type) {
1146
+ case AV_OPT_TYPE_STRING:
1147
+ case AV_OPT_TYPE_COLOR:
1148
+ return Option.get(this.native, name, searchFlags);
1149
+ case AV_OPT_TYPE_INT:
1150
+ case AV_OPT_TYPE_UINT:
1151
+ case AV_OPT_TYPE_FLAGS:
1152
+ case AV_OPT_TYPE_DURATION:
1153
+ case AV_OPT_TYPE_CONST:
1154
+ return Option.getInt(this.native, name, searchFlags);
1155
+ case AV_OPT_TYPE_INT64:
1156
+ case AV_OPT_TYPE_UINT64:
1157
+ // For INT64/UINT64, we should return bigint for proper precision
1158
+ const int64Val = Option.getInt(this.native, name, searchFlags);
1159
+ return int64Val !== null ? BigInt(int64Val) : null;
1160
+ case AV_OPT_TYPE_BOOL:
1161
+ const val = Option.getInt(this.native, name, searchFlags);
1162
+ return val !== null ? Boolean(val) : null;
1163
+ case AV_OPT_TYPE_DOUBLE:
1164
+ case AV_OPT_TYPE_FLOAT:
1165
+ return Option.getDouble(this.native, name, searchFlags);
1166
+ case AV_OPT_TYPE_RATIONAL:
1167
+ case AV_OPT_TYPE_VIDEO_RATE:
1168
+ const rational = Option.getRational(this.native, name, searchFlags);
1169
+ return rational ? new Rational(rational.num, rational.den) : null;
1170
+ case AV_OPT_TYPE_PIXEL_FMT:
1171
+ return Option.getPixelFormat(this.native, name, searchFlags);
1172
+ case AV_OPT_TYPE_SAMPLE_FMT:
1173
+ return Option.getSampleFormat(this.native, name, searchFlags);
1174
+ case AV_OPT_TYPE_IMAGE_SIZE:
1175
+ return Option.getImageSize(this.native, name, searchFlags);
1176
+ case AV_OPT_TYPE_CHLAYOUT:
1177
+ return Option.getChannelLayout(this.native, name, searchFlags);
1178
+ case AV_OPT_TYPE_DICT:
1179
+ return Option.getDict(this.native, name, searchFlags);
1180
+ case AV_OPT_TYPE_BINARY:
1181
+ // Binary data can only be retrieved as string
1182
+ return Option.get(this.native, name, searchFlags);
1183
+ case AV_OPT_TYPE_BINARY_INT_ARRAY:
1184
+ // Getting binary int arrays is not supported (requires av_opt_get_bin())
1185
+ // These are typically write-only options like 'pix_fmts' in buffersink
1186
+ throw new Error('Getting BINARY_INT_ARRAY options is not supported. These are typically write-only options.');
1187
+ default:
1188
+ // Fallback to string
1189
+ return Option.get(this.native, name, searchFlags);
1190
+ }
1191
+ }
1192
+ /**
1193
+ * List all available options for this object.
1194
+ *
1195
+ * Uses the AVOption API to enumerate all options.
1196
+ * Useful for discovering available settings and their types.
1197
+ *
1198
+ * Direct mapping to av_opt_next() iteration.
1199
+ *
1200
+ * @returns Array of option information objects
1201
+ *
1202
+ * @example
1203
+ * ```typescript
1204
+ * const options = obj.listOptions();
1205
+ * for (const opt of options) {
1206
+ * console.log(`${opt.name}: ${opt.help}`);
1207
+ * console.log(` Type: ${opt.type}, Default: ${opt.defaultValue}`);
1208
+ * console.log(` Range: ${opt.min} - ${opt.max}`);
1209
+ * }
1210
+ * ```
1211
+ *
1212
+ * @see {@link OptionInfo} For option metadata structure
1213
+ */
1214
+ listOptions() {
1215
+ const options = [];
1216
+ let opt = null;
1217
+ while ((opt = Option.next(this.native, opt))) {
1218
+ options.push(opt);
1219
+ }
1220
+ return options;
1221
+ }
1222
+ /**
1223
+ * Intelligently set a format option based on its FFmpeg type.
1224
+ *
1225
+ * Queries the option type using av_opt_find() and calls the appropriate
1226
+ * typed setOption() overload. Handles automatic type conversion from
1227
+ * JavaScript types to FFmpeg option types.
1228
+ *
1229
+ * @param name - Option name
1230
+ *
1231
+ * @param value - Option value (null/undefined are skipped)
1232
+ *
1233
+ * @returns 0 on success, negative on error
1234
+ *
1235
+ * @internal
1236
+ */
1237
+ setUnknownOption(name, value) {
1238
+ if (value === undefined || value === null) {
1239
+ return 0;
1240
+ }
1241
+ // Try to find the option to get its type
1242
+ const optInfo = Option.find(this.native, name, AV_OPT_SEARCH_CHILDREN);
1243
+ if (optInfo) {
1244
+ const optType = optInfo.type;
1245
+ // Handle based on FFmpeg option type
1246
+ switch (optType) {
1247
+ case AV_OPT_TYPE_INT:
1248
+ if (typeof value === 'number') {
1249
+ return this.setOption(name, value, AV_OPT_TYPE_INT);
1250
+ }
1251
+ else if (typeof value === 'boolean') {
1252
+ return this.setOption(name, value ? 1 : 0, AV_OPT_TYPE_INT);
1253
+ }
1254
+ else if (typeof value === 'bigint') {
1255
+ return this.setOption(name, Number(value), AV_OPT_TYPE_INT);
1256
+ }
1257
+ else if (typeof value === 'string') {
1258
+ return this.setOption(name, parseInt(value, 10), AV_OPT_TYPE_INT);
1259
+ }
1260
+ else {
1261
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1262
+ }
1263
+ case AV_OPT_TYPE_UINT:
1264
+ if (typeof value === 'number') {
1265
+ return this.setOption(name, value, AV_OPT_TYPE_UINT);
1266
+ }
1267
+ else if (typeof value === 'boolean') {
1268
+ return this.setOption(name, value ? 1 : 0, AV_OPT_TYPE_UINT);
1269
+ }
1270
+ else if (typeof value === 'bigint') {
1271
+ return this.setOption(name, Number(value), AV_OPT_TYPE_UINT);
1272
+ }
1273
+ else if (typeof value === 'string') {
1274
+ return this.setOption(name, parseInt(value, 10), AV_OPT_TYPE_UINT);
1275
+ }
1276
+ else {
1277
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1278
+ }
1279
+ case AV_OPT_TYPE_FLAGS:
1280
+ if (typeof value === 'number') {
1281
+ return this.setOption(name, value, AV_OPT_TYPE_FLAGS);
1282
+ }
1283
+ else if (typeof value === 'boolean') {
1284
+ return this.setOption(name, value ? 1 : 0, AV_OPT_TYPE_FLAGS);
1285
+ }
1286
+ else if (typeof value === 'bigint') {
1287
+ return this.setOption(name, Number(value), AV_OPT_TYPE_FLAGS);
1288
+ }
1289
+ else if (typeof value === 'string') {
1290
+ return this.setOption(name, parseInt(value, 10), AV_OPT_TYPE_FLAGS);
1291
+ }
1292
+ else {
1293
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1294
+ }
1295
+ case AV_OPT_TYPE_CONST:
1296
+ if (typeof value === 'number') {
1297
+ return this.setOption(name, value, AV_OPT_TYPE_CONST);
1298
+ }
1299
+ else if (typeof value === 'boolean') {
1300
+ return this.setOption(name, value ? 1 : 0, AV_OPT_TYPE_CONST);
1301
+ }
1302
+ else if (typeof value === 'bigint') {
1303
+ return this.setOption(name, Number(value), AV_OPT_TYPE_CONST);
1304
+ }
1305
+ else if (typeof value === 'string') {
1306
+ return this.setOption(name, parseInt(value, 10), AV_OPT_TYPE_CONST);
1307
+ }
1308
+ else {
1309
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1310
+ }
1311
+ case AV_OPT_TYPE_DURATION:
1312
+ if (typeof value === 'number') {
1313
+ return this.setOption(name, value, AV_OPT_TYPE_DURATION);
1314
+ }
1315
+ else if (typeof value === 'boolean') {
1316
+ return this.setOption(name, value ? 1 : 0, AV_OPT_TYPE_DURATION);
1317
+ }
1318
+ else if (typeof value === 'bigint') {
1319
+ return this.setOption(name, Number(value), AV_OPT_TYPE_DURATION);
1320
+ }
1321
+ else if (typeof value === 'string') {
1322
+ return this.setOption(name, parseInt(value, 10), AV_OPT_TYPE_DURATION);
1323
+ }
1324
+ else {
1325
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1326
+ }
1327
+ case AV_OPT_TYPE_INT64:
1328
+ if (typeof value === 'bigint') {
1329
+ return this.setOption(name, value, AV_OPT_TYPE_INT64);
1330
+ }
1331
+ else if (typeof value === 'number') {
1332
+ return this.setOption(name, BigInt(value), AV_OPT_TYPE_INT64);
1333
+ }
1334
+ else if (typeof value === 'boolean') {
1335
+ return this.setOption(name, value ? 1n : 0n, AV_OPT_TYPE_INT64);
1336
+ }
1337
+ else if (typeof value === 'string') {
1338
+ return this.setOption(name, BigInt(value), AV_OPT_TYPE_INT64);
1339
+ }
1340
+ else {
1341
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1342
+ }
1343
+ case AV_OPT_TYPE_UINT64:
1344
+ if (typeof value === 'bigint') {
1345
+ return this.setOption(name, value, AV_OPT_TYPE_UINT64);
1346
+ }
1347
+ else if (typeof value === 'number') {
1348
+ return this.setOption(name, BigInt(value), AV_OPT_TYPE_UINT64);
1349
+ }
1350
+ else if (typeof value === 'boolean') {
1351
+ return this.setOption(name, value ? 1n : 0n, AV_OPT_TYPE_UINT64);
1352
+ }
1353
+ else if (typeof value === 'string') {
1354
+ return this.setOption(name, BigInt(value), AV_OPT_TYPE_UINT64);
1355
+ }
1356
+ else {
1357
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1358
+ }
1359
+ case AV_OPT_TYPE_CHLAYOUT:
1360
+ if (typeof value === 'bigint') {
1361
+ return this.setOption(name, value, AV_OPT_TYPE_CHLAYOUT);
1362
+ }
1363
+ else if (typeof value === 'number') {
1364
+ return this.setOption(name, BigInt(value), AV_OPT_TYPE_CHLAYOUT);
1365
+ }
1366
+ else if (typeof value === 'boolean') {
1367
+ return this.setOption(name, value ? 1n : 0n, AV_OPT_TYPE_CHLAYOUT);
1368
+ }
1369
+ else if (typeof value === 'string') {
1370
+ return this.setOption(name, BigInt(value), AV_OPT_TYPE_CHLAYOUT);
1371
+ }
1372
+ else {
1373
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1374
+ }
1375
+ case AV_OPT_TYPE_FLOAT:
1376
+ if (typeof value === 'number') {
1377
+ return this.setOption(name, value, AV_OPT_TYPE_FLOAT);
1378
+ }
1379
+ else if (typeof value === 'boolean') {
1380
+ return this.setOption(name, value ? 1.0 : 0.0, AV_OPT_TYPE_FLOAT);
1381
+ }
1382
+ else if (typeof value === 'bigint') {
1383
+ return this.setOption(name, Number(value), AV_OPT_TYPE_FLOAT);
1384
+ }
1385
+ else if (typeof value === 'string') {
1386
+ return this.setOption(name, parseFloat(value), AV_OPT_TYPE_FLOAT);
1387
+ }
1388
+ else {
1389
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1390
+ }
1391
+ case AV_OPT_TYPE_DOUBLE:
1392
+ if (typeof value === 'number') {
1393
+ return this.setOption(name, value, AV_OPT_TYPE_DOUBLE);
1394
+ }
1395
+ else if (typeof value === 'boolean') {
1396
+ return this.setOption(name, value ? 1.0 : 0.0, AV_OPT_TYPE_DOUBLE);
1397
+ }
1398
+ else if (typeof value === 'bigint') {
1399
+ return this.setOption(name, Number(value), AV_OPT_TYPE_DOUBLE);
1400
+ }
1401
+ else if (typeof value === 'string') {
1402
+ return this.setOption(name, parseFloat(value), AV_OPT_TYPE_DOUBLE);
1403
+ }
1404
+ else {
1405
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1406
+ }
1407
+ case AV_OPT_TYPE_BOOL:
1408
+ if (typeof value === 'boolean') {
1409
+ return this.setOption(name, value, AV_OPT_TYPE_BOOL);
1410
+ }
1411
+ else if (typeof value === 'number') {
1412
+ return this.setOption(name, value !== 0, AV_OPT_TYPE_BOOL);
1413
+ }
1414
+ else if (typeof value === 'bigint') {
1415
+ return this.setOption(name, value !== 0n, AV_OPT_TYPE_BOOL);
1416
+ }
1417
+ else if (typeof value === 'string') {
1418
+ // Parse string as boolean (1/true/yes/on = true, everything else = false)
1419
+ const str = value.toLowerCase();
1420
+ return this.setOption(name, str === '1' || str === 'true' || str === 'yes' || str === 'on', AV_OPT_TYPE_BOOL);
1421
+ }
1422
+ else {
1423
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1424
+ }
1425
+ case AV_OPT_TYPE_STRING:
1426
+ if (typeof value === 'string') {
1427
+ return this.setOption(name, value, AV_OPT_TYPE_STRING);
1428
+ }
1429
+ else if (typeof value === 'object') {
1430
+ return this.setOption(name, JSON.stringify(value), AV_OPT_TYPE_STRING);
1431
+ }
1432
+ else {
1433
+ return this.setOption(name, String(value), AV_OPT_TYPE_STRING);
1434
+ }
1435
+ case AV_OPT_TYPE_COLOR:
1436
+ if (typeof value === 'string') {
1437
+ return this.setOption(name, value, AV_OPT_TYPE_COLOR);
1438
+ }
1439
+ else if (typeof value === 'object') {
1440
+ return this.setOption(name, JSON.stringify(value), AV_OPT_TYPE_COLOR);
1441
+ }
1442
+ else {
1443
+ return this.setOption(name, String(value), AV_OPT_TYPE_COLOR);
1444
+ }
1445
+ case AV_OPT_TYPE_RATIONAL:
1446
+ case AV_OPT_TYPE_VIDEO_RATE:
1447
+ if (typeof value === 'object' && 'num' in value && 'den' in value) {
1448
+ return this.setOption(name, value, AV_OPT_TYPE_RATIONAL);
1449
+ }
1450
+ else if (typeof value === 'string') {
1451
+ // Try to parse "30/1" or "30:1" format
1452
+ const match = /^(\d+)[/:](\d+)$/.exec(value);
1453
+ if (match) {
1454
+ return this.setOption(name, { num: parseInt(match[1], 10), den: parseInt(match[2], 10) }, AV_OPT_TYPE_RATIONAL);
1455
+ }
1456
+ // Fallback to string (let FFmpeg parse it)
1457
+ return this.setOption(name, value, AV_OPT_TYPE_STRING);
1458
+ }
1459
+ else {
1460
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1461
+ }
1462
+ // Image size type - handle all input types
1463
+ case AV_OPT_TYPE_IMAGE_SIZE:
1464
+ if (typeof value === 'object' && 'width' in value && 'height' in value) {
1465
+ return this.setOption(name, value, AV_OPT_TYPE_IMAGE_SIZE);
1466
+ }
1467
+ else if (typeof value === 'string') {
1468
+ // Try to parse "1920x1080" format
1469
+ const match = /^(\d+)x(\d+)$/.exec(value);
1470
+ if (match) {
1471
+ return this.setOption(name, { width: parseInt(match[1], 10), height: parseInt(match[2], 10) }, AV_OPT_TYPE_IMAGE_SIZE);
1472
+ }
1473
+ // Fallback to string (let FFmpeg parse it)
1474
+ return this.setOption(name, value, AV_OPT_TYPE_STRING);
1475
+ }
1476
+ else {
1477
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1478
+ }
1479
+ // Pixel/Sample format types - handle all input types
1480
+ case AV_OPT_TYPE_PIXEL_FMT:
1481
+ if (typeof value === 'number') {
1482
+ return this.setOption(name, value, AV_OPT_TYPE_PIXEL_FMT);
1483
+ }
1484
+ else if (typeof value === 'bigint') {
1485
+ return this.setOption(name, Number(value), AV_OPT_TYPE_PIXEL_FMT);
1486
+ }
1487
+ else if (typeof value === 'string') {
1488
+ return this.setOption(name, avGetPixFmtFromName(value), AV_OPT_TYPE_PIXEL_FMT);
1489
+ }
1490
+ else {
1491
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1492
+ }
1493
+ case AV_OPT_TYPE_SAMPLE_FMT:
1494
+ if (typeof value === 'number') {
1495
+ return this.setOption(name, value, AV_OPT_TYPE_SAMPLE_FMT);
1496
+ }
1497
+ else if (typeof value === 'bigint') {
1498
+ return this.setOption(name, Number(value), AV_OPT_TYPE_SAMPLE_FMT);
1499
+ }
1500
+ else if (typeof value === 'string') {
1501
+ return this.setOption(name, avGetSampleFmtFromName(value), AV_OPT_TYPE_SAMPLE_FMT);
1502
+ }
1503
+ else {
1504
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1505
+ }
1506
+ // Binary type - handle all input types
1507
+ case AV_OPT_TYPE_BINARY:
1508
+ if (Buffer.isBuffer(value)) {
1509
+ return this.setOption(name, value, AV_OPT_TYPE_BINARY);
1510
+ }
1511
+ else if (typeof value === 'string') {
1512
+ return this.setOption(name, Buffer.from(value), AV_OPT_TYPE_BINARY);
1513
+ }
1514
+ else {
1515
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1516
+ }
1517
+ // Binary int array type - handle all input types
1518
+ case AV_OPT_TYPE_BINARY_INT_ARRAY:
1519
+ if (Array.isArray(value)) {
1520
+ // Convert all elements to numbers
1521
+ return this.setOption(name, value.map((v) => (typeof v === 'number' ? v : Number(v))), AV_OPT_TYPE_BINARY_INT_ARRAY);
1522
+ }
1523
+ else if (typeof value === 'string') {
1524
+ // Parse comma-separated values "1,2,3" → [1, 2, 3]
1525
+ const arr = value.split(',').map((s) => parseInt(s.trim(), 10));
1526
+ return this.setOption(name, arr, AV_OPT_TYPE_BINARY_INT_ARRAY);
1527
+ }
1528
+ else if (typeof value === 'number') {
1529
+ // Single number → single-element array
1530
+ return this.setOption(name, [value], AV_OPT_TYPE_BINARY_INT_ARRAY);
1531
+ }
1532
+ else if (typeof value === 'bigint') {
1533
+ // Single bigint → single-element array
1534
+ return this.setOption(name, [Number(value)], AV_OPT_TYPE_BINARY_INT_ARRAY);
1535
+ }
1536
+ else if (typeof value === 'boolean') {
1537
+ // Boolean → single-element array
1538
+ return this.setOption(name, [value ? 1 : 0], AV_OPT_TYPE_BINARY_INT_ARRAY);
1539
+ }
1540
+ else {
1541
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1542
+ }
1543
+ // Dictionary type - handle all input types
1544
+ case AV_OPT_TYPE_DICT:
1545
+ if (value instanceof Dictionary) {
1546
+ return this.setOption(name, value, AV_OPT_TYPE_DICT);
1547
+ }
1548
+ else if (typeof value === 'object' && !Array.isArray(value)) {
1549
+ // Convert plain object to Dictionary
1550
+ const dict = Dictionary.fromObject(value);
1551
+ return this.setOption(name, dict, AV_OPT_TYPE_DICT);
1552
+ }
1553
+ else {
1554
+ return FFmpegError.AVERROR(PosixError.EINVAL);
1555
+ }
1556
+ // Unknown type - fallback to string
1557
+ default:
1558
+ if (typeof value === 'string') {
1559
+ return this.setOption(name, value, AV_OPT_TYPE_STRING);
1560
+ }
1561
+ else if (typeof value === 'object') {
1562
+ return this.setOption(name, JSON.stringify(value), AV_OPT_TYPE_STRING);
1563
+ }
1564
+ else {
1565
+ return this.setOption(name, String(value), AV_OPT_TYPE_STRING);
1566
+ }
1567
+ }
1568
+ }
1569
+ else {
1570
+ // Option not found - fallback to string (for private/undocumented options)
1571
+ if (typeof value === 'string') {
1572
+ return this.setOption(name, value, AV_OPT_TYPE_STRING);
1573
+ }
1574
+ else if (typeof value === 'object') {
1575
+ return this.setOption(name, JSON.stringify(value), AV_OPT_TYPE_STRING);
1576
+ }
1577
+ else {
1578
+ return this.setOption(name, String(value), AV_OPT_TYPE_STRING);
1579
+ }
1580
+ }
1581
+ }
1582
+ }
1583
+ //# sourceMappingURL=option.js.map