@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.
- package/BUILD_LINUX.md +61 -0
- package/LICENSE.md +22 -0
- package/README.md +662 -0
- package/build_mac_local.sh +69 -0
- package/dist/api/audio-frame-buffer.d.ts +205 -0
- package/dist/api/audio-frame-buffer.js +287 -0
- package/dist/api/audio-frame-buffer.js.map +1 -0
- package/dist/api/bitstream-filter.d.ts +820 -0
- package/dist/api/bitstream-filter.js +1242 -0
- package/dist/api/bitstream-filter.js.map +1 -0
- package/dist/api/constants.d.ts +44 -0
- package/dist/api/constants.js +45 -0
- package/dist/api/constants.js.map +1 -0
- package/dist/api/data/test_av1.ivf +0 -0
- package/dist/api/data/test_h264.h264 +0 -0
- package/dist/api/data/test_hevc.h265 +0 -0
- package/dist/api/data/test_mjpeg.mjpeg +0 -0
- package/dist/api/data/test_vp8.ivf +0 -0
- package/dist/api/data/test_vp9.ivf +0 -0
- package/dist/api/decoder.d.ts +1088 -0
- package/dist/api/decoder.js +1775 -0
- package/dist/api/decoder.js.map +1 -0
- package/dist/api/demuxer.d.ts +1219 -0
- package/dist/api/demuxer.js +2081 -0
- package/dist/api/demuxer.js.map +1 -0
- package/dist/api/device.d.ts +586 -0
- package/dist/api/device.js +961 -0
- package/dist/api/device.js.map +1 -0
- package/dist/api/encoder.d.ts +1132 -0
- package/dist/api/encoder.js +1988 -0
- package/dist/api/encoder.js.map +1 -0
- package/dist/api/filter-complex.d.ts +821 -0
- package/dist/api/filter-complex.js +1604 -0
- package/dist/api/filter-complex.js.map +1 -0
- package/dist/api/filter-presets.d.ts +1286 -0
- package/dist/api/filter-presets.js +2152 -0
- package/dist/api/filter-presets.js.map +1 -0
- package/dist/api/filter.d.ts +1234 -0
- package/dist/api/filter.js +1976 -0
- package/dist/api/filter.js.map +1 -0
- package/dist/api/fmp4-stream.d.ts +426 -0
- package/dist/api/fmp4-stream.js +739 -0
- package/dist/api/fmp4-stream.js.map +1 -0
- package/dist/api/hardware.d.ts +651 -0
- package/dist/api/hardware.js +1260 -0
- package/dist/api/hardware.js.map +1 -0
- package/dist/api/index.d.ts +17 -0
- package/dist/api/index.js +32 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/io-stream.d.ts +307 -0
- package/dist/api/io-stream.js +282 -0
- package/dist/api/io-stream.js.map +1 -0
- package/dist/api/muxer.d.ts +957 -0
- package/dist/api/muxer.js +2002 -0
- package/dist/api/muxer.js.map +1 -0
- package/dist/api/pipeline.d.ts +607 -0
- package/dist/api/pipeline.js +1145 -0
- package/dist/api/pipeline.js.map +1 -0
- package/dist/api/utilities/async-queue.d.ts +120 -0
- package/dist/api/utilities/async-queue.js +211 -0
- package/dist/api/utilities/async-queue.js.map +1 -0
- package/dist/api/utilities/audio-sample.d.ts +117 -0
- package/dist/api/utilities/audio-sample.js +112 -0
- package/dist/api/utilities/audio-sample.js.map +1 -0
- package/dist/api/utilities/channel-layout.d.ts +76 -0
- package/dist/api/utilities/channel-layout.js +80 -0
- package/dist/api/utilities/channel-layout.js.map +1 -0
- package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
- package/dist/api/utilities/electron-shared-texture.js +503 -0
- package/dist/api/utilities/electron-shared-texture.js.map +1 -0
- package/dist/api/utilities/image.d.ts +207 -0
- package/dist/api/utilities/image.js +213 -0
- package/dist/api/utilities/image.js.map +1 -0
- package/dist/api/utilities/index.d.ts +12 -0
- package/dist/api/utilities/index.js +25 -0
- package/dist/api/utilities/index.js.map +1 -0
- package/dist/api/utilities/media-type.d.ts +49 -0
- package/dist/api/utilities/media-type.js +53 -0
- package/dist/api/utilities/media-type.js.map +1 -0
- package/dist/api/utilities/pixel-format.d.ts +89 -0
- package/dist/api/utilities/pixel-format.js +97 -0
- package/dist/api/utilities/pixel-format.js.map +1 -0
- package/dist/api/utilities/sample-format.d.ts +129 -0
- package/dist/api/utilities/sample-format.js +141 -0
- package/dist/api/utilities/sample-format.js.map +1 -0
- package/dist/api/utilities/scheduler.d.ts +138 -0
- package/dist/api/utilities/scheduler.js +98 -0
- package/dist/api/utilities/scheduler.js.map +1 -0
- package/dist/api/utilities/streaming.d.ts +186 -0
- package/dist/api/utilities/streaming.js +309 -0
- package/dist/api/utilities/streaming.js.map +1 -0
- package/dist/api/utilities/timestamp.d.ts +193 -0
- package/dist/api/utilities/timestamp.js +206 -0
- package/dist/api/utilities/timestamp.js.map +1 -0
- package/dist/api/utilities/whisper-model.d.ts +310 -0
- package/dist/api/utilities/whisper-model.js +528 -0
- package/dist/api/utilities/whisper-model.js.map +1 -0
- package/dist/api/utils.d.ts +19 -0
- package/dist/api/utils.js +39 -0
- package/dist/api/utils.js.map +1 -0
- package/dist/api/whisper.d.ts +324 -0
- package/dist/api/whisper.js +362 -0
- package/dist/api/whisper.js.map +1 -0
- package/dist/constants/channel-layouts.d.ts +53 -0
- package/dist/constants/channel-layouts.js +57 -0
- package/dist/constants/channel-layouts.js.map +1 -0
- package/dist/constants/constants.d.ts +2325 -0
- package/dist/constants/constants.js +1887 -0
- package/dist/constants/constants.js.map +1 -0
- package/dist/constants/decoders.d.ts +633 -0
- package/dist/constants/decoders.js +641 -0
- package/dist/constants/decoders.js.map +1 -0
- package/dist/constants/encoders.d.ts +295 -0
- package/dist/constants/encoders.js +308 -0
- package/dist/constants/encoders.js.map +1 -0
- package/dist/constants/hardware.d.ts +26 -0
- package/dist/constants/hardware.js +27 -0
- package/dist/constants/hardware.js.map +1 -0
- package/dist/constants/index.d.ts +5 -0
- package/dist/constants/index.js +6 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +99 -0
- package/dist/ffmpeg/index.js +115 -0
- package/dist/ffmpeg/index.js.map +1 -0
- package/dist/ffmpeg/utils.d.ts +31 -0
- package/dist/ffmpeg/utils.js +68 -0
- package/dist/ffmpeg/utils.js.map +1 -0
- package/dist/ffmpeg/version.d.ts +6 -0
- package/dist/ffmpeg/version.js +7 -0
- package/dist/ffmpeg/version.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audio-fifo.d.ts +399 -0
- package/dist/lib/audio-fifo.js +431 -0
- package/dist/lib/audio-fifo.js.map +1 -0
- package/dist/lib/binding.d.ts +228 -0
- package/dist/lib/binding.js +60 -0
- package/dist/lib/binding.js.map +1 -0
- package/dist/lib/bitstream-filter-context.d.ts +379 -0
- package/dist/lib/bitstream-filter-context.js +441 -0
- package/dist/lib/bitstream-filter-context.js.map +1 -0
- package/dist/lib/bitstream-filter.d.ts +140 -0
- package/dist/lib/bitstream-filter.js +154 -0
- package/dist/lib/bitstream-filter.js.map +1 -0
- package/dist/lib/codec-context.d.ts +1071 -0
- package/dist/lib/codec-context.js +1354 -0
- package/dist/lib/codec-context.js.map +1 -0
- package/dist/lib/codec-parameters.d.ts +616 -0
- package/dist/lib/codec-parameters.js +761 -0
- package/dist/lib/codec-parameters.js.map +1 -0
- package/dist/lib/codec-parser.d.ts +201 -0
- package/dist/lib/codec-parser.js +213 -0
- package/dist/lib/codec-parser.js.map +1 -0
- package/dist/lib/codec.d.ts +586 -0
- package/dist/lib/codec.js +713 -0
- package/dist/lib/codec.js.map +1 -0
- package/dist/lib/device.d.ts +291 -0
- package/dist/lib/device.js +324 -0
- package/dist/lib/device.js.map +1 -0
- package/dist/lib/dictionary.d.ts +333 -0
- package/dist/lib/dictionary.js +372 -0
- package/dist/lib/dictionary.js.map +1 -0
- package/dist/lib/error.d.ts +242 -0
- package/dist/lib/error.js +303 -0
- package/dist/lib/error.js.map +1 -0
- package/dist/lib/fifo.d.ts +416 -0
- package/dist/lib/fifo.js +453 -0
- package/dist/lib/fifo.js.map +1 -0
- package/dist/lib/filter-context.d.ts +712 -0
- package/dist/lib/filter-context.js +789 -0
- package/dist/lib/filter-context.js.map +1 -0
- package/dist/lib/filter-graph-segment.d.ts +160 -0
- package/dist/lib/filter-graph-segment.js +171 -0
- package/dist/lib/filter-graph-segment.js.map +1 -0
- package/dist/lib/filter-graph.d.ts +641 -0
- package/dist/lib/filter-graph.js +704 -0
- package/dist/lib/filter-graph.js.map +1 -0
- package/dist/lib/filter-inout.d.ts +198 -0
- package/dist/lib/filter-inout.js +257 -0
- package/dist/lib/filter-inout.js.map +1 -0
- package/dist/lib/filter.d.ts +243 -0
- package/dist/lib/filter.js +272 -0
- package/dist/lib/filter.js.map +1 -0
- package/dist/lib/format-context.d.ts +1254 -0
- package/dist/lib/format-context.js +1379 -0
- package/dist/lib/format-context.js.map +1 -0
- package/dist/lib/frame-utils.d.ts +116 -0
- package/dist/lib/frame-utils.js +98 -0
- package/dist/lib/frame-utils.js.map +1 -0
- package/dist/lib/frame.d.ts +1222 -0
- package/dist/lib/frame.js +1435 -0
- package/dist/lib/frame.js.map +1 -0
- package/dist/lib/hardware-device-context.d.ts +362 -0
- package/dist/lib/hardware-device-context.js +383 -0
- package/dist/lib/hardware-device-context.js.map +1 -0
- package/dist/lib/hardware-frames-context.d.ts +419 -0
- package/dist/lib/hardware-frames-context.js +477 -0
- package/dist/lib/hardware-frames-context.js.map +1 -0
- package/dist/lib/index.d.ts +35 -0
- package/dist/lib/index.js +60 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/input-format.d.ts +249 -0
- package/dist/lib/input-format.js +306 -0
- package/dist/lib/input-format.js.map +1 -0
- package/dist/lib/io-context.d.ts +696 -0
- package/dist/lib/io-context.js +769 -0
- package/dist/lib/io-context.js.map +1 -0
- package/dist/lib/log.d.ts +174 -0
- package/dist/lib/log.js +184 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/native-types.d.ts +946 -0
- package/dist/lib/native-types.js +2 -0
- package/dist/lib/native-types.js.map +1 -0
- package/dist/lib/option.d.ts +927 -0
- package/dist/lib/option.js +1583 -0
- package/dist/lib/option.js.map +1 -0
- package/dist/lib/output-format.d.ts +180 -0
- package/dist/lib/output-format.js +213 -0
- package/dist/lib/output-format.js.map +1 -0
- package/dist/lib/packet.d.ts +501 -0
- package/dist/lib/packet.js +590 -0
- package/dist/lib/packet.js.map +1 -0
- package/dist/lib/rational.d.ts +251 -0
- package/dist/lib/rational.js +278 -0
- package/dist/lib/rational.js.map +1 -0
- package/dist/lib/software-resample-context.d.ts +552 -0
- package/dist/lib/software-resample-context.js +592 -0
- package/dist/lib/software-resample-context.js.map +1 -0
- package/dist/lib/software-scale-context.d.ts +344 -0
- package/dist/lib/software-scale-context.js +366 -0
- package/dist/lib/software-scale-context.js.map +1 -0
- package/dist/lib/stream.d.ts +379 -0
- package/dist/lib/stream.js +526 -0
- package/dist/lib/stream.js.map +1 -0
- package/dist/lib/sync-queue.d.ts +179 -0
- package/dist/lib/sync-queue.js +197 -0
- package/dist/lib/sync-queue.js.map +1 -0
- package/dist/lib/types.d.ts +34 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utilities.d.ts +1127 -0
- package/dist/lib/utilities.js +1225 -0
- package/dist/lib/utilities.js.map +1 -0
- package/dist/utils/electron.d.ts +49 -0
- package/dist/utils/electron.js +63 -0
- package/dist/utils/electron.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/install/check.js +121 -0
- package/install/ffmpeg.js +66 -0
- package/jellyfin-ffmpeg.patch +181 -0
- 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
|