bare-ffmpeg 1.0.0-3 → 1.0.0-31

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 (51) hide show
  1. package/CMakeLists.txt +10 -3
  2. package/README.md +1811 -0
  3. package/binding.cc +4638 -0
  4. package/cmake/ports/ffmpeg/port.cmake +514 -0
  5. package/cmake/ports/opus/patches/01-windows-clang.patch +52 -0
  6. package/cmake/ports/opus/port.cmake +42 -0
  7. package/cmake/ports/svt-av1/port.cmake +42 -0
  8. package/cmake/ports/x264/patches/01-windows-clang.patch +33 -0
  9. package/cmake/ports/x264/port.cmake +157 -0
  10. package/index.js +22 -4
  11. package/lib/audio-fifo.js +47 -0
  12. package/lib/channel-layout.js +35 -0
  13. package/lib/codec-context.js +210 -16
  14. package/lib/codec-parameters.js +242 -8
  15. package/lib/codec.js +19 -1
  16. package/lib/constants.js +245 -9
  17. package/lib/dictionary.js +28 -15
  18. package/lib/errors.js +38 -0
  19. package/lib/filter-context.js +7 -0
  20. package/lib/filter-graph.js +47 -0
  21. package/lib/filter-inout.js +55 -0
  22. package/lib/filter.js +7 -0
  23. package/lib/format-context.js +72 -31
  24. package/lib/frame.js +88 -22
  25. package/lib/image.js +22 -0
  26. package/lib/input-format.js +36 -4
  27. package/lib/io-context.js +36 -6
  28. package/lib/log.js +16 -0
  29. package/lib/output-format.js +33 -2
  30. package/lib/packet.js +153 -12
  31. package/lib/rational.js +49 -1
  32. package/lib/resampler.js +63 -0
  33. package/lib/samples.js +96 -0
  34. package/lib/scaler.js +8 -7
  35. package/lib/stream.js +58 -14
  36. package/package.json +9 -4
  37. package/prebuilds/android-arm/bare-ffmpeg.bare +0 -0
  38. package/prebuilds/android-arm64/bare-ffmpeg.bare +0 -0
  39. package/prebuilds/android-ia32/bare-ffmpeg.bare +0 -0
  40. package/prebuilds/android-x64/bare-ffmpeg.bare +0 -0
  41. package/prebuilds/darwin-arm64/bare-ffmpeg.bare +0 -0
  42. package/prebuilds/darwin-x64/bare-ffmpeg.bare +0 -0
  43. package/prebuilds/ios-arm64/bare-ffmpeg.bare +0 -0
  44. package/prebuilds/ios-arm64-simulator/bare-ffmpeg.bare +0 -0
  45. package/prebuilds/ios-x64-simulator/bare-ffmpeg.bare +0 -0
  46. package/prebuilds/linux-arm64/bare-ffmpeg.bare +0 -0
  47. package/prebuilds/linux-x64/bare-ffmpeg.bare +0 -0
  48. package/prebuilds/win32-arm64/bare-ffmpeg.bare +0 -0
  49. package/prebuilds/win32-x64/bare-ffmpeg.bare +0 -0
  50. package/binding.c +0 -2203
  51. package/lib/reference-counted.js +0 -39
@@ -1,33 +1,225 @@
1
1
  const binding = require('../binding')
2
- const ReferenceCounted = require('./reference-counted')
3
-
4
- module.exports = class FFmpegCodecParameters extends ReferenceCounted {
5
- constructor(handle) {
6
- super()
2
+ const ChannelLayout = require('./channel-layout')
3
+ const Rational = require('./rational')
7
4
 
5
+ module.exports = class FFmpegCodecParameters {
6
+ constructor(handle, owned = false) {
8
7
  this._handle = handle
8
+ this._owned = owned
9
9
  }
10
10
 
11
- _destroy() {
12
- this._handle = null
13
- }
11
+ // Getters, Setters
14
12
 
15
13
  get bitRate() {
16
14
  return binding.getCodecParametersBitRate(this._handle)
17
15
  }
18
16
 
17
+ set bitRate(rate) {
18
+ binding.setCodecParametersBitRate(this._handle, rate)
19
+ }
20
+
19
21
  get bitsPerCodedSample() {
20
22
  return binding.getCodecParametersBitsPerCodedSample(this._handle)
21
23
  }
22
24
 
25
+ set bitsPerCodedSample(bits) {
26
+ binding.setCodecParametersBitsPerCodedSample(this._handle, bits)
27
+ }
28
+
23
29
  get bitsPerRawSample() {
24
30
  return binding.getCodecParametersBitsPerRawSample(this._handle)
25
31
  }
26
32
 
33
+ set bitsPerRawSample(bits) {
34
+ binding.setCodecParametersBitsPerRawSample(this._handle, bits)
35
+ }
36
+
27
37
  get sampleRate() {
28
38
  return binding.getCodecParametersSampleRate(this._handle)
29
39
  }
30
40
 
41
+ set sampleRate(rate) {
42
+ binding.setCodecParametersSampleRate(this._handle, rate)
43
+ }
44
+
45
+ get sampleAspectRatio() {
46
+ const view = new Int32Array(
47
+ binding.getCodecParametersSampleAspectRatio(this._handle)
48
+ )
49
+ return new Rational(view[0], view[1])
50
+ }
51
+
52
+ set sampleAspectRatio(ratio) {
53
+ binding.setCodecParametersSampleAspectRatio(
54
+ this._handle,
55
+ ratio.numerator,
56
+ ratio.denominator
57
+ )
58
+ }
59
+
60
+ get frameRate() {
61
+ const view = new Int32Array(
62
+ binding.getCodecParametersFramerate(this._handle)
63
+ )
64
+ return new Rational(view[0], view[1])
65
+ }
66
+
67
+ set frameRate(rate) {
68
+ binding.setCodecParametersFramerate(
69
+ this._handle,
70
+ rate.numerator,
71
+ rate.denominator
72
+ )
73
+ }
74
+
75
+ get frameSize() {
76
+ return binding.getCodecParametersFrameSize(this._handle)
77
+ }
78
+
79
+ set frameSize(size) {
80
+ binding.setCodecParametersFrameSize(this._handle, size)
81
+ }
82
+
83
+ get videoDelay() {
84
+ return binding.getCodecParametersVideoDelay(this._handle)
85
+ }
86
+
87
+ set videoDelay(delay) {
88
+ binding.setCodecParametersVideoDelay(this._handle, delay)
89
+ }
90
+
91
+ get nbChannels() {
92
+ return binding.getCodecParametersNbChannels(this._handle)
93
+ }
94
+
95
+ set nbChannels(numberOfChannels) {
96
+ binding.setCodecParametersNbChannels(this._handle, numberOfChannels)
97
+ }
98
+
99
+ get type() {
100
+ return binding.getCodecParametersType(this._handle)
101
+ }
102
+
103
+ set type(type) {
104
+ binding.setCodecParametersType(this._handle, type)
105
+ }
106
+
107
+ get tag() {
108
+ return binding.getCodecParametersTag(this._handle)
109
+ }
110
+
111
+ set tag(tag) {
112
+ binding.setCodecParametersTag(this._handle, tag)
113
+ }
114
+
115
+ get id() {
116
+ return binding.getCodecParametersId(this._handle)
117
+ }
118
+
119
+ set id(id) {
120
+ binding.setCodecParametersId(this._handle, id)
121
+ }
122
+
123
+ get level() {
124
+ return binding.getCodecParametersLevel(this._handle)
125
+ }
126
+
127
+ set level(level) {
128
+ binding.setCodecParametersLevel(this._handle, level)
129
+ }
130
+
131
+ get profile() {
132
+ return binding.getCodecParametersProfile(this._handle)
133
+ }
134
+
135
+ set profile(profile) {
136
+ binding.setCodecParametersProfile(this._handle, profile)
137
+ }
138
+
139
+ get format() {
140
+ return binding.getCodecParametersFormat(this._handle)
141
+ }
142
+
143
+ set format(format) {
144
+ binding.setCodecParametersFormat(this._handle, format)
145
+ }
146
+
147
+ get channelLayout() {
148
+ return new ChannelLayout(
149
+ binding.getCodecParametersChannelLayout(this._handle)
150
+ )
151
+ }
152
+
153
+ set channelLayout(value) {
154
+ binding.setCodecParametersChannelLayout(
155
+ this._handle,
156
+ ChannelLayout.from(value)._handle
157
+ )
158
+ }
159
+
160
+ get width() {
161
+ return binding.getCodecParametersWidth(this._handle)
162
+ }
163
+
164
+ set width(value) {
165
+ binding.setCodecParametersWidth(this._handle, value)
166
+ }
167
+
168
+ get height() {
169
+ return binding.getCodecParametersHeight(this._handle)
170
+ }
171
+
172
+ set height(value) {
173
+ binding.setCodecParametersHeight(this._handle, value)
174
+ }
175
+
176
+ get extraData() {
177
+ return Buffer.from(binding.getCodecParametersExtraData(this._handle))
178
+ }
179
+
180
+ set extraData(value) {
181
+ binding.setCodecParametersExtraData(
182
+ this._handle,
183
+ value.buffer,
184
+ value.byteOffset,
185
+ value.byteLength
186
+ )
187
+ }
188
+
189
+ get blockAlign() {
190
+ return binding.getCodecParametersBlockAlign(this._handle)
191
+ }
192
+
193
+ set blockAlign(value) {
194
+ binding.setCodecParametersBlockAlign(this._handle, value)
195
+ }
196
+
197
+ get initialPadding() {
198
+ return binding.getCodecParametersInitialPadding(this._handle)
199
+ }
200
+
201
+ set initialPadding(value) {
202
+ binding.setCodecParametersInitialPadding(this._handle, value)
203
+ }
204
+
205
+ get trailingPadding() {
206
+ return binding.getCodecParametersTrailingPadding(this._handle)
207
+ }
208
+
209
+ set trailingPadding(value) {
210
+ binding.setCodecParametersTrailingPadding(this._handle, value)
211
+ }
212
+
213
+ get seekPreroll() {
214
+ return binding.getCodecParametersSeekPreroll(this._handle)
215
+ }
216
+
217
+ set seekPreroll(value) {
218
+ binding.setCodecParametersSeekPreroll(this._handle, value)
219
+ }
220
+
221
+ // Methods
222
+
31
223
  fromContext(context) {
32
224
  binding.codecParametersFromContext(this._handle, context._handle)
33
225
  }
@@ -35,4 +227,46 @@ module.exports = class FFmpegCodecParameters extends ReferenceCounted {
35
227
  toContext(context) {
36
228
  binding.codecParametersToContext(context._handle, this._handle)
37
229
  }
230
+
231
+ destroy() {
232
+ if (this._owned) binding.destroyCodecParameters(this._handle)
233
+ }
234
+
235
+ [Symbol.dispose]() {
236
+ this.destroy()
237
+ }
238
+
239
+ // TODO: add other props
240
+ [Symbol.for('bare.inspect')]() {
241
+ return {
242
+ __proto__: { constructor: FFmpegCodecParameters },
243
+ type: this.type,
244
+ id: this.id,
245
+ format: this.format,
246
+ tag: this.tag,
247
+ frameRate: this.frameRate,
248
+ videoDelay: this.videoDelay,
249
+ profile: this.profile,
250
+ level: this.level,
251
+ width: this.width,
252
+ height: this.height,
253
+ sampleAsectRatio: this.sampleAspectRatio,
254
+ bitRate: this.bitRate,
255
+ bitsPerCodedSample: this.bitsPerCodedSample,
256
+ bitsPerRawSample: this.bitsPerRawSample,
257
+ sampleRate: this.sampleRate,
258
+ nbChannels: this.nbChannels,
259
+ channelLayout: this.channelLayout,
260
+ extraData: this.extraData,
261
+ blockAlign: this.blockAlign,
262
+ initialPadding: this.initialPadding,
263
+ trailingPadding: this.trailingPadding,
264
+ seekPreroll: this.seekPreroll,
265
+ frameSize: this.frameSize
266
+ }
267
+ }
268
+
269
+ static alloc() {
270
+ return new FFmpegCodecParameters(binding.allocCodecParameters(), true)
271
+ }
38
272
  }
package/lib/codec.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const Decoder = require('./decoder')
2
2
  const Encoder = require('./encoder')
3
3
  const constants = require('./constants')
4
+ const binding = require('../binding')
4
5
 
5
6
  const codecs = new Map()
6
7
 
@@ -25,6 +26,21 @@ module.exports = class FFmpegCodec {
25
26
  return this._encoder
26
27
  }
27
28
 
29
+ get name() {
30
+ if (Number.isInteger(this._id)) {
31
+ return binding.getCodecNameByID(this._id)
32
+ }
33
+ }
34
+
35
+ [Symbol.for('bare.inspect')]() {
36
+ return {
37
+ __proto__: { constructor: FFmpegCodec },
38
+ id: this.id,
39
+ name: this.name
40
+ }
41
+ }
42
+
43
+ /** @return {FFmpegCodec} */
28
44
  static for(id) {
29
45
  let codec = codecs.get(id)
30
46
  if (codec === undefined) {
@@ -35,5 +51,7 @@ module.exports = class FFmpegCodec {
35
51
  }
36
52
 
37
53
  static MJPEG = this.for(constants.codecs.MJPEG)
38
- static H264 = this.for(constants.codecs.H264)
54
+ static AAC = this.for(constants.codecs.AAC)
55
+ static OPUS = this.for(constants.codecs.OPUS)
56
+ static AV1 = this.for(constants.codecs.AV1)
39
57
  }
package/lib/constants.js CHANGED
@@ -1,18 +1,49 @@
1
1
  const binding = require('../binding')
2
+ const errors = require('./errors')
3
+
4
+ function makeTag(a, b, c, d) {
5
+ return (
6
+ a.charCodeAt(0) |
7
+ (b.charCodeAt(0) << 8) |
8
+ (c.charCodeAt(0) << 16) |
9
+ (d.charCodeAt(0) << 24)
10
+ )
11
+ }
2
12
 
3
13
  module.exports = exports = {
4
14
  codecs: {
5
15
  MJPEG: binding.AV_CODEC_ID_MJPEG,
6
- H264: binding.AV_CODEC_ID_H264
16
+ AAC: binding.AV_CODEC_ID_AAC,
17
+ OPUS: binding.AV_CODEC_ID_OPUS,
18
+ AV1: binding.AV_CODEC_ID_AV1,
19
+ FLAC: binding.AV_CODEC_ID_FLAC,
20
+ MP3: binding.AV_CODEC_ID_MP3
21
+ },
22
+ tags: {
23
+ MJPEG: makeTag('M', 'J', 'P', 'G'),
24
+ AV1: makeTag('A', 'V', '0', '1'),
25
+ AAC: 0x00ff,
26
+ FLAC: 0xf1ac,
27
+ MP3: 0x0055
28
+ },
29
+ profiles: {
30
+ H264_MAIN: binding.AV_PROFILE_H264_MAIN
31
+ },
32
+ levels: {
33
+ UNKNOWN: binding.AV_LEVEL_UNKNOWN
7
34
  },
8
35
  pixelFormats: {
36
+ NONE: binding.AV_PIX_FMT_NONE,
9
37
  RGBA: binding.AV_PIX_FMT_RGBA,
10
38
  RGB24: binding.AV_PIX_FMT_RGB24,
11
39
  YUVJ420P: binding.AV_PIX_FMT_YUVJ420P,
12
40
  UYVY422: binding.AV_PIX_FMT_UYVY422,
13
- YUV420P: binding.AV_PIX_FMT_YUV420P
41
+ YUV420P: binding.AV_PIX_FMT_YUV420P,
42
+ NV12: binding.AV_PIX_FMT_NV12,
43
+ NV21: binding.AV_PIX_FMT_NV21,
44
+ NV24: binding.AV_PIX_FMT_NV24
14
45
  },
15
- mediaType: {
46
+ mediaTypes: {
16
47
  UNKNOWN: binding.AVMEDIA_TYPE_UNKNOWN,
17
48
  VIDEO: binding.AVMEDIA_TYPE_VIDEO,
18
49
  AUDIO: binding.AVMEDIA_TYPE_AUDIO,
@@ -20,17 +51,222 @@ module.exports = exports = {
20
51
  SUBTITLE: binding.AVMEDIA_TYPE_SUBTITLE,
21
52
  ATTACHEMENT: binding.AVMEDIA_TYPE_ATTACHMENT,
22
53
  NB: binding.AVMEDIA_TYPE_NB
54
+ },
55
+ sampleFormats: {
56
+ NONE: binding.AV_SAMPLE_FMT_NONE,
57
+ U8: binding.AV_SAMPLE_FMT_U8,
58
+ S16: binding.AV_SAMPLE_FMT_S16,
59
+ S32: binding.AV_SAMPLE_FMT_S32,
60
+ S64: binding.AV_SAMPLE_FMT_S64,
61
+ FLT: binding.AV_SAMPLE_FMT_FLT,
62
+ DBL: binding.AV_SAMPLE_FMT_DBL,
63
+ U8P: binding.AV_SAMPLE_FMT_U8P,
64
+ S16P: binding.AV_SAMPLE_FMT_S16P,
65
+ S32P: binding.AV_SAMPLE_FMT_S32P,
66
+ S64P: binding.AV_SAMPLE_FMT_S64P,
67
+ FLTP: binding.AV_SAMPLE_FMT_FLTP,
68
+ DBLP: binding.AV_SAMPLE_FMT_DBLP,
69
+ NB: binding.AV_SAMPLE_FMT_NB
70
+ },
71
+ channelLayouts: {
72
+ MONO: binding.AV_CH_LAYOUT_MONO,
73
+ STEREO: binding.AV_CH_LAYOUT_STEREO,
74
+ QUAD: binding.AV_CH_LAYOUT_QUAD,
75
+ SURROUND: binding.AV_CH_LAYOUT_SURROUND,
76
+ 2_1: binding.AV_CH_LAYOUT_2POINT1,
77
+ 5_0: binding.AV_CH_LAYOUT_5POINT0,
78
+ 5_1: binding.AV_CH_LAYOUT_5POINT1,
79
+ 7_1: binding.AV_CH_LAYOUT_7POINT1,
80
+ // Aliases
81
+ 2.1: binding.AV_CH_LAYOUT_2POINT1,
82
+ '5.0': binding.AV_CH_LAYOUT_5POINT0,
83
+ 5.1: binding.AV_CH_LAYOUT_5POINT1,
84
+ 7.1: binding.AV_CH_LAYOUT_7POINT1
85
+ },
86
+ pictureTypes: {
87
+ NONE: binding.AV_PICTURE_TYPE_NONE,
88
+ I: binding.AV_PICTURE_TYPE_I,
89
+ P: binding.AV_PICTURE_TYPE_P,
90
+ B: binding.AV_PICTURE_TYPE_B,
91
+ S: binding.AV_PICTURE_TYPE_S,
92
+ SI: binding.AV_PICTURE_TYPE_SI,
93
+ SP: binding.AV_PICTURE_TYPE_SP,
94
+ BI: binding.AV_PICTURE_TYPE_BI
95
+ },
96
+ logLevels: {
97
+ QUIET: binding.AV_LOG_QUIET,
98
+ PANIC: binding.AV_LOG_PANIC,
99
+ FATAL: binding.AV_LOG_FATAL,
100
+ ERROR: binding.AV_LOG_ERROR,
101
+ WARNING: binding.AV_LOG_WARNING,
102
+ INFO: binding.AV_LOG_INFO,
103
+ VERBOSE: binding.AV_LOG_VERBOSE,
104
+ DEBUG: binding.AV_LOG_DEBUG,
105
+ TRACE: binding.AV_LOG_TRACE
106
+ },
107
+ codecFlags: {
108
+ COPY_OPAQUE: binding.AV_CODEC_FLAG_COPY_OPAQUE,
109
+ FRAME_DURATION: binding.AV_CODEC_FLAG_FRAME_DURATION,
110
+ PASS1: binding.AV_CODEC_FLAG_PASS1,
111
+ PASS2: binding.AV_CODEC_FLAG_PASS2,
112
+ LOOP_FILTER: binding.AV_CODEC_FLAG_LOOP_FILTER,
113
+ GRAY: binding.AV_CODEC_FLAG_GRAY,
114
+ PSNR: binding.AV_CODEC_FLAG_PSNR,
115
+ INTERLACED_DCT: binding.AV_CODEC_FLAG_INTERLACED_DCT,
116
+ LOW_DELAY: binding.AV_CODEC_FLAG_LOW_DELAY,
117
+ GLOBAL_HEADER: binding.AV_CODEC_FLAG_GLOBAL_HEADER,
118
+ BITEXACT: binding.AV_CODEC_FLAG_BITEXACT,
119
+ AC_PRED: binding.AV_CODEC_FLAG_AC_PRED,
120
+ INTERLACED_ME: binding.AV_CODEC_FLAG_INTERLACED_ME,
121
+ CLOSED_GOP: binding.AV_CODEC_FLAG_CLOSED_GOP
122
+ },
123
+ formatFlags: {
124
+ SHOW_IDS: binding.AVFMT_SHOW_IDS,
125
+ GENERIC_INDEX: binding.AVFMT_GENERIC_INDEX,
126
+ TS_DISCONT: binding.AVFMT_TS_DISCONT,
127
+ NOBINSEARCH: binding.AVFMT_NOBINSEARCH,
128
+ NOGENSEARCH: binding.AVFMT_NOGENSEARCH,
129
+ NO_BYTE_SEEK: binding.AVFMT_NO_BYTE_SEEK,
130
+ SEEK_TO_PTS: binding.AVFMT_SEEK_TO_PTS,
131
+ GLOBALHEADER: binding.AVFMT_GLOBALHEADER,
132
+ VARIABLE_FPS: binding.AVFMT_VARIABLE_FPS,
133
+ NODIMENSIONS: binding.AVFMT_NODIMENSIONS,
134
+ NOSTREAMS: binding.AVFMT_NOSTREAMS,
135
+ TS_NONSTRICT: binding.AVFMT_TS_NONSTRICT,
136
+ TS_NEGATIVE: binding.AVFMT_TS_NEGATIVE,
137
+ NOFILE: binding.AVFMT_NOFILE,
138
+ NEEDNUMBER: binding.AVFMT_NEEDNUMBER,
139
+ NOTIMESTAMPS: binding.AVFMT_NOTIMESTAMPS
140
+ },
141
+ seek: {
142
+ SIZE: binding.AVSEEK_SIZE,
143
+ FORCE: binding.AVSEEK_FORCE,
144
+ CUR: binding.SEEK_CUR,
145
+ SET: binding.SEEK_SET,
146
+ END: binding.SEEK_END
147
+ },
148
+ packetSideDataType: {
149
+ PALETTE: binding.AV_PKT_DATA_PALETTE,
150
+ NEW_EXTRADATA: binding.AV_PKT_DATA_NEW_EXTRADATA,
151
+ PARAM_CHANGE: binding.AV_PKT_DATA_PARAM_CHANGE,
152
+ H263_MB_INFO: binding.AV_PKT_DATA_H263_MB_INFO,
153
+ REPLAYGAIN: binding.AV_PKT_DATA_REPLAYGAIN,
154
+ DISPLAYMATRIX: binding.AV_PKT_DATA_DISPLAYMATRIX,
155
+ STEREO3D: binding.AV_PKT_DATA_STEREO3D,
156
+ AUDIO_SERVICE_TYPE: binding.AV_PKT_DATA_AUDIO_SERVICE_TYPE,
157
+ QUALITY_STATS: binding.AV_PKT_DATA_QUALITY_STATS,
158
+ FALLBACK_TRACK: binding.AV_PKT_DATA_FALLBACK_TRACK,
159
+ CPB_PROPERTIES: binding.AV_PKT_DATA_CPB_PROPERTIES,
160
+ SKIP_SAMPLES: binding.AV_PKT_DATA_SKIP_SAMPLES,
161
+ JP_DUALMONO: binding.AV_PKT_DATA_JP_DUALMONO,
162
+ STRINGS_METADATA: binding.AV_PKT_DATA_STRINGS_METADATA,
163
+ SUBTITLE_POSITION: binding.AV_PKT_DATA_SUBTITLE_POSITION,
164
+ MATROSKA_BLOCKADDITIONAL: binding.AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
165
+ WEBVTT_IDENTIFIER: binding.AV_PKT_DATA_WEBVTT_IDENTIFIER,
166
+ WEBVTT_SETTINGS: binding.AV_PKT_DATA_WEBVTT_SETTINGS,
167
+ METADATA_UPDATE: binding.AV_PKT_DATA_METADATA_UPDATE,
168
+ MPEGTS_STREAM_ID: binding.AV_PKT_DATA_MPEGTS_STREAM_ID,
169
+ MASTERING_DISPLAY_METADATA: binding.AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
170
+ SPHERICAL: binding.AV_PKT_DATA_SPHERICAL,
171
+ CONTENT_LIGHT_LEVEL: binding.AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
172
+ A53_CC: binding.AV_PKT_DATA_A53_CC,
173
+ ENCRYPTION_INIT_INFO: binding.AV_PKT_DATA_ENCRYPTION_INIT_INFO,
174
+ ENCRYPTION_INFO: binding.AV_PKT_DATA_ENCRYPTION_INFO,
175
+ AFD: binding.AV_PKT_DATA_AFD,
176
+ PRFT: binding.AV_PKT_DATA_PRFT,
177
+ ICC_PROFILE: binding.AV_PKT_DATA_ICC_PROFILE,
178
+ DOVI_CONF: binding.AV_PKT_DATA_DOVI_CONF,
179
+ S12M_TIMECODE: binding.AV_PKT_DATA_S12M_TIMECODE,
180
+ DYNAMIC_HDR10_PLUS: binding.AV_PKT_DATA_DYNAMIC_HDR10_PLUS,
181
+ IAMF_MIX_GAIN_PARAM: binding.AV_PKT_DATA_IAMF_MIX_GAIN_PARAM,
182
+ IAMF_DEMIXING_INFO_PARAM: binding.AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM,
183
+ IAMF_RECON_GAIN_INFO_PARAM: binding.AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM,
184
+ AMBIENT_VIEWING_ENVIRONMENT:
185
+ binding.AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,
186
+ FRAME_CROPPING: binding.AV_PKT_DATA_FRAME_CROPPING,
187
+ LCEVC: binding.AV_PKT_DATA_LCEVC,
188
+ '3D_REFERENCE_DISPLAYS': binding.AV_PKT_DATA_3D_REFERENCE_DISPLAYS,
189
+ RTCP_SR: binding.AV_PKT_DATA_RTCP_SR,
190
+ NB: binding.AV_PKT_DATA_NB
191
+ },
192
+ codecConfig: {
193
+ PIX_FORMAT: binding.AV_CODEC_CONFIG_PIX_FORMAT,
194
+ FRAME_RATE: binding.AV_CODEC_CONFIG_FRAME_RATE,
195
+ SAMPLE_RATE: binding.AV_CODEC_CONFIG_SAMPLE_RATE,
196
+ SAMPLE_FORMAT: binding.AV_CODEC_CONFIG_SAMPLE_FORMAT,
197
+ CHANNEL_LAYOUT: binding.AV_CODEC_CONFIG_CHANNEL_LAYOUT,
198
+ COLOR_RANGE: binding.AV_CODEC_CONFIG_COLOR_RANGE,
199
+ COLOR_SPACE: binding.AV_CODEC_CONFIG_COLOR_SPACE
200
+ },
201
+ rounding: {
202
+ AV_ROUND_ZERO: binding.AV_ROUND_ZERO,
203
+ AV_ROUND_INF: binding.AV_ROUND_INF,
204
+ AV_ROUND_DOWN: binding.AV_ROUND_DOWN,
205
+ AV_ROUND_UP: binding.AV_ROUND_UP,
206
+ AV_ROUND_NEAR_INF: binding.AV_ROUND_NEAR_INF,
207
+ AV_ROUND_PASS_MINMAX: binding.AV_ROUND_PASS_MINMAX
208
+ },
209
+ optionFlags: {
210
+ SEARCH_CHILDREN: binding.AV_OPT_SEARCH_CHILDREN,
211
+ SEARCH_FAKE_OBJ: binding.AV_OPT_SEARCH_FAKE_OBJ,
212
+ ALLOW_NULL: binding.AV_OPT_ALLOW_NULL,
213
+ ARRAY_REPLACE: binding.AV_OPT_ARRAY_REPLACE,
214
+ MULTI_COMPONENT_RANGE: binding.AV_OPT_MULTI_COMPONENT_RANGE
23
215
  }
24
216
  }
25
217
 
26
- exports.toPixelFormat = function toPixelFormat(pixelFormat) {
27
- if (typeof pixelFormat === 'number') return pixelFormat
218
+ exports.toPixelFormat = function toPixelFormat(format) {
219
+ if (typeof format === 'number') return format
28
220
 
29
- if (typeof pixelFormat === 'string') {
30
- if (pixelFormat in exports.pixelFormats === false) {
31
- throw errors.UNKNOWN_PIXEL_FORMAT(`Unknown pixel format '${pixelFormat}'`)
221
+ if (typeof format === 'string') {
222
+ if (format in exports.pixelFormats === false) {
223
+ throw errors.UNKNOWN_PIXEL_FORMAT(`Unknown pixel format '${format}'`)
32
224
  }
33
225
 
34
- return exports.pixelFormats[pixelFormat]
226
+ return exports.pixelFormats[format]
35
227
  }
228
+
229
+ throw new TypeError(
230
+ `Pixel format must be a number or string. Received ${typeof format} (${format})`
231
+ )
232
+ }
233
+
234
+ exports.toSampleFormat = function toSampleFormat(format) {
235
+ if (typeof format === 'number') return format
236
+
237
+ if (typeof format === 'string') {
238
+ if (format in exports.sampleFormats === false) {
239
+ throw errors.UNKNOWN_SAMPLE_FORMAT(`Unknown sample format '${format}'`)
240
+ }
241
+
242
+ return exports.sampleFormats[format]
243
+ }
244
+
245
+ throw new TypeError(
246
+ `Sample format must be a number or string. Received ${typeof format} (${format})`
247
+ )
248
+ }
249
+
250
+ exports.toChannelLayout = function toChannelLayout(layout) {
251
+ if (typeof layout === 'number') return layout
252
+
253
+ if (typeof layout === 'string') {
254
+ if (layout in exports.channelLayouts === false) {
255
+ throw errors.UNKNOWN_CHANNEL_LAYOUT(`Unknown channel layout '${layout}'`)
256
+ }
257
+
258
+ return exports.channelLayouts[layout]
259
+ }
260
+
261
+ throw new TypeError(
262
+ `Channel layout must be a number or string. Received ${typeof layout} (${layout})`
263
+ )
264
+ }
265
+
266
+ exports.getSampleFormatName = function (sampleFormat) {
267
+ return binding.getSampleFormatNameByID(sampleFormat)
268
+ }
269
+
270
+ exports.getPixelFormatName = function (pixelFormat) {
271
+ return binding.getPixelFormatNameByID(pixelFormat)
36
272
  }
package/lib/dictionary.js CHANGED
@@ -1,33 +1,46 @@
1
1
  const binding = require('../binding')
2
- const ReferenceCounted = require('./reference-counted')
3
2
 
4
- module.exports = class FFmpegDictionary extends ReferenceCounted {
5
- constructor() {
6
- super()
3
+ module.exports = class FFmpegDictionary {
4
+ static from(obj) {
5
+ const dictionary = new FFmpegDictionary()
6
+
7
+ for (const [key, value] of Object.entries(obj)) {
8
+ dictionary.set(key, value)
9
+ }
10
+
11
+ return dictionary
12
+ }
7
13
 
14
+ constructor() {
8
15
  this._handle = binding.initDictionary()
9
16
  }
10
17
 
11
- _destroy() {
18
+ destroy() {
12
19
  binding.destroyDictionary(this._handle)
13
20
  this._handle = null
14
21
  }
15
22
 
16
23
  get(key) {
17
- if (typeof key !== 'string' || key.length < 1) {
18
- throw new TypeError(`Key should be a non empty string`)
19
- }
20
- return binding.getDictionaryEntry(this._handle, key)
24
+ const value = binding.getDictionaryEntry(this._handle, key)
25
+ if (value === undefined) return null
26
+ return value
21
27
  }
22
28
 
23
29
  set(key, value) {
24
- if (typeof key !== 'string' || key.length < 1) {
25
- throw new TypeError(`Key should be a non empty string`)
26
- }
30
+ if (typeof value !== 'string') value = String(value)
27
31
 
28
- if (typeof value !== 'string' || value.length < 1) {
29
- throw new TypeError(`Value should be a non empty string`)
30
- }
31
32
  binding.setDictionaryEntry(this._handle, key, value)
32
33
  }
34
+
35
+ entries() {
36
+ return binding.getDictionaryEntries(this._handle)
37
+ }
38
+
39
+ *[Symbol.iterator]() {
40
+ yield* this.entries()
41
+ }
42
+
43
+ [Symbol.dispose]() {
44
+ this.destroy()
45
+ }
33
46
  }
package/lib/errors.js ADDED
@@ -0,0 +1,38 @@
1
+ module.exports = class FFmpegError extends Error {
2
+ constructor(msg, code, fn = FFmpegError) {
3
+ super(`${code}: ${msg}`)
4
+ this.code = code
5
+
6
+ if (Error.captureStackTrace) {
7
+ Error.captureStackTrace(this, fn)
8
+ }
9
+ }
10
+
11
+ get name() {
12
+ return 'FFmpegError'
13
+ }
14
+
15
+ static UNKNOWN_PIXEL_FORMAT(msg) {
16
+ return new FFmpegError(
17
+ msg,
18
+ 'UNKNOWN_PIXEL_FORMAT',
19
+ FFmpegError.UNKNOWN_PIXEL_FORMAT
20
+ )
21
+ }
22
+
23
+ static UNKNOWN_SAMPLE_FORMAT(msg) {
24
+ return new FFmpegError(
25
+ msg,
26
+ 'UNKNOWN_SAMPLE_FORMAT',
27
+ FFmpegError.UNKNOWN_SAMPLE_FORMAT
28
+ )
29
+ }
30
+
31
+ static UNKNOWN_CHANNEL_LAYOUT(msg) {
32
+ return new FFmpegError(
33
+ msg,
34
+ 'UNKNOWN_CHANNEL_LAYOUT',
35
+ FFmpegError.UNKNOWN_CHANNEL_LAYOUT
36
+ )
37
+ }
38
+ }
@@ -0,0 +1,7 @@
1
+ const binding = require('../binding')
2
+
3
+ module.exports = class FilterContext {
4
+ constructor() {
5
+ this._handle = binding.initFilterContext()
6
+ }
7
+ }