bare-ffmpeg 1.0.0-20 → 1.0.0-21

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/README.md CHANGED
@@ -40,6 +40,74 @@ Destroys the `IOContext` and frees all associated resources. Automatically calle
40
40
 
41
41
  **Returns**: `void`
42
42
 
43
+ ### `Dictionary`
44
+
45
+ The `Dictionary` API provides functionality to store and retrieve key-value pairs, commonly used for passing options to various FFmpeg components.
46
+
47
+ ```js
48
+ const dict = new ffmpeg.Dictionary()
49
+ ```
50
+
51
+ **Returns**: A new `Dictionary` instance
52
+
53
+ Example:
54
+
55
+ ```js
56
+ const dict = new ffmpeg.Dictionary()
57
+ dict.set('video_codec', 'h264')
58
+ dict.set('audio_codec', 'aac')
59
+ dict.set('bitrate', '1000k')
60
+ ```
61
+
62
+ #### Methods
63
+
64
+ ##### `Dictionary.set(key, value)`
65
+
66
+ Sets a key-value pair in the dictionary. Non-string values are automatically converted to strings.
67
+
68
+ Parameters:
69
+
70
+ - `key` (`string`): The dictionary key
71
+ - `value` (`string` | `number`): The value to store
72
+
73
+ **Returns**: `void`
74
+
75
+ ##### `Dictionary.get(key)`
76
+
77
+ Retrieves a value from the dictionary by key.
78
+
79
+ Parameters:
80
+
81
+ - `key` (`string`): The dictionary key
82
+
83
+ **Returns**: `string` value or `null` if the key doesn't exist
84
+
85
+ ##### `Dictionary.entries()`
86
+
87
+ Retrieves all keys and values.
88
+
89
+ **Returns**: `Array<[string, string]>` value
90
+
91
+ ##### `Dictionary.destroy()`
92
+
93
+ Destroys the `Dictionary` and frees all associated resources. Automatically called when the object is managed by a `using` declaration.
94
+
95
+ **Returns**: `void`
96
+
97
+ #### Iteration
98
+
99
+ The `Dictionary` class implements the iterator protocol, allowing you to iterate over all key-value pairs:
100
+
101
+ ```js
102
+ const dict = new ffmpeg.Dictionary()
103
+ dict.set('foo', 'bar')
104
+ dict.set('baz', 'qux')
105
+
106
+ for (const [key, value] of dict) {
107
+ console.log(`${key}: ${value}`)
108
+ }
109
+ ```
110
+
43
111
  ### `FormatContext`
44
112
 
45
113
  The `FormatContext` API provides the base functionality for reading and writing media files.
@@ -400,6 +468,45 @@ Gets or sets the channel layout, see `ffmpeg.constants.channelLayouts`
400
468
 
401
469
  **Returns**: `ChannelLayout`
402
470
 
471
+ ##### `CodecParameters.blockAlign`
472
+
473
+ Audio only. The number of bytes per coded audio frame, required by some
474
+ formats.
475
+
476
+ Corresponds to `nBlockAlign` in `WAVEFORMATEX`.
477
+
478
+ **Returns**: `number`
479
+
480
+ ##### `CodecParameters.initalPadding`
481
+
482
+ Audio only. The amount of padding (in samples) inserted by the encoder at the beginning of the audio. I.e. this number of leading decoded samples must be discarded by the caller to get the original audio without leading padding.
483
+
484
+ **Returns**: `number`
485
+
486
+ ##### `CodecParameters.trailingPadding`
487
+
488
+ Audio only. The amount of padding (in samples) appended by the encoder to the end of the audio. I.e. this number of decoded samples must be discarded by the caller from the end of the stream to get the original audio without any trailing padding.
489
+
490
+ ##### `CodecParameters.seekPreroll`
491
+
492
+ Audio only. Number of samples to skip after a discontinuity.
493
+
494
+ **Returns**: `number`
495
+
496
+ ##### `CodecParameters.sampleAspectRatio`
497
+
498
+ Video only. The aspect ratio (width / height) which a single pixel should have when displayed.
499
+
500
+ When the aspect ratio is unknown / undefined, the numerator should be set to 0 (the denominator may have any value).
501
+
502
+ **Returns**: `number`
503
+
504
+ ##### `CodecParameters.videoDelay`
505
+
506
+ Video only. Number of delayed frames.
507
+
508
+ **Returns**: `number`
509
+
403
510
  #### Methods
404
511
 
405
512
  ##### `CodecParameters.fromContext(context)`
package/binding.cc CHANGED
@@ -3,6 +3,8 @@
3
3
  #include <stddef.h>
4
4
  #include <stdint.h>
5
5
  #include <string.h>
6
+ #include <tuple>
7
+ #include <vector>
6
8
 
7
9
  #include <bare.h>
8
10
  #include <js.h>
@@ -504,11 +506,6 @@ bare_ffmpeg_format_context_write_header(
504
506
  } else {
505
507
  auto dict = *muxer_options;
506
508
  err = avformat_write_header(context->handle, &dict->handle);
507
-
508
- const AVDictionaryEntry *option = NULL;
509
- while ((option = av_dict_iterate(dict->handle, option))) {
510
- av_log(context->handle, AV_LOG_WARNING, "Ignored option key='%s' value='%s'\n", option->key, option->value);
511
- }
512
509
  }
513
510
 
514
511
  if (err < 0) {
@@ -1208,6 +1205,32 @@ bare_ffmpeg_codec_parameters_to_context(
1208
1205
  }
1209
1206
  }
1210
1207
 
1208
+ static js_arraybuffer_t
1209
+ bare_ffmpeg_codec_parameters_alloc(
1210
+ js_env_t *env,
1211
+ js_receiver_t
1212
+ ) {
1213
+ int err;
1214
+
1215
+ js_arraybuffer_t handle;
1216
+ bare_ffmpeg_codec_parameters_t *parameters;
1217
+ err = js_create_arraybuffer(env, parameters, handle);
1218
+ assert(err == 0);
1219
+
1220
+ parameters->handle = avcodec_parameters_alloc();
1221
+
1222
+ return handle;
1223
+ }
1224
+
1225
+ static void
1226
+ bare_ffmpeg_codec_parameters_destroy(
1227
+ js_env_t *env,
1228
+ js_receiver_t,
1229
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1230
+ ) {
1231
+ avcodec_parameters_free(&parameters->handle);
1232
+ }
1233
+
1211
1234
  static int64_t
1212
1235
  bare_ffmpeg_codec_parameters_get_bit_rate(
1213
1236
  js_env_t *env,
@@ -1576,6 +1599,132 @@ bare_ffmpeg_codec_parameters_set_extra_data(
1576
1599
  parameters->handle->extradata_size = static_cast<int>(len);
1577
1600
  }
1578
1601
 
1602
+ static int
1603
+ bare_ffmpeg_codec_parameters_get_block_align(
1604
+ js_env_t *env,
1605
+ js_receiver_t,
1606
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1607
+ ) {
1608
+ return parameters->handle->block_align;
1609
+ }
1610
+
1611
+ static void
1612
+ bare_ffmpeg_codec_parameters_set_block_align(
1613
+ js_env_t *env,
1614
+ js_receiver_t,
1615
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1616
+ int block_align
1617
+ ) {
1618
+ parameters->handle->block_align = block_align;
1619
+ }
1620
+
1621
+ static int
1622
+ bare_ffmpeg_codec_parameters_get_initial_padding(
1623
+ js_env_t *env,
1624
+ js_receiver_t,
1625
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1626
+ ) {
1627
+ return parameters->handle->initial_padding;
1628
+ }
1629
+
1630
+ static void
1631
+ bare_ffmpeg_codec_parameters_set_initial_padding(
1632
+ js_env_t *env,
1633
+ js_receiver_t,
1634
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1635
+ int initial_padding
1636
+ ) {
1637
+ parameters->handle->initial_padding = initial_padding;
1638
+ }
1639
+
1640
+ static int
1641
+ bare_ffmpeg_codec_parameters_get_trailing_padding(
1642
+ js_env_t *env,
1643
+ js_receiver_t,
1644
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1645
+ ) {
1646
+ return parameters->handle->trailing_padding;
1647
+ }
1648
+
1649
+ static void
1650
+ bare_ffmpeg_codec_parameters_set_trailing_padding(
1651
+ js_env_t *env,
1652
+ js_receiver_t,
1653
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1654
+ int trailing_padding
1655
+ ) {
1656
+ parameters->handle->trailing_padding = trailing_padding;
1657
+ }
1658
+
1659
+ static int
1660
+ bare_ffmpeg_codec_parameters_get_seek_preroll(
1661
+ js_env_t *env,
1662
+ js_receiver_t,
1663
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1664
+ ) {
1665
+ return parameters->handle->seek_preroll;
1666
+ }
1667
+
1668
+ static void
1669
+ bare_ffmpeg_codec_parameters_set_seek_preroll(
1670
+ js_env_t *env,
1671
+ js_receiver_t,
1672
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1673
+ int seek_preroll
1674
+ ) {
1675
+ parameters->handle->seek_preroll = seek_preroll;
1676
+ }
1677
+
1678
+ static js_arraybuffer_t
1679
+ bare_ffmpeg_codec_parameters_get_sample_aspect_ratio(
1680
+ js_env_t *env,
1681
+ js_receiver_t,
1682
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1683
+ ) {
1684
+ int err;
1685
+ js_arraybuffer_t result;
1686
+
1687
+ int32_t *data;
1688
+ err = js_create_arraybuffer(env, 2, data, result);
1689
+ assert(err == 0);
1690
+
1691
+ data[0] = parameters->handle->sample_aspect_ratio.num;
1692
+ data[1] = parameters->handle->sample_aspect_ratio.den;
1693
+
1694
+ return result;
1695
+ }
1696
+
1697
+ static void
1698
+ bare_ffmpeg_codec_parameters_set_sample_aspect_ratio(
1699
+ js_env_t *env,
1700
+ js_receiver_t,
1701
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1702
+ int num,
1703
+ int den
1704
+ ) {
1705
+ parameters->handle->sample_aspect_ratio.num = num;
1706
+ parameters->handle->sample_aspect_ratio.den = den;
1707
+ }
1708
+
1709
+ static int
1710
+ bare_ffmpeg_codec_parameters_get_video_delay(
1711
+ js_env_t *env,
1712
+ js_receiver_t,
1713
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
1714
+ ) {
1715
+ return parameters->handle->video_delay;
1716
+ }
1717
+
1718
+ static void
1719
+ bare_ffmpeg_codec_parameters_set_video_delay(
1720
+ js_env_t *env,
1721
+ js_receiver_t,
1722
+ js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
1723
+ int delay
1724
+ ) {
1725
+ parameters->handle->video_delay = delay;
1726
+ }
1727
+
1579
1728
  static js_arraybuffer_t
1580
1729
  bare_ffmpeg_frame_init(js_env_t *env, js_receiver_t) {
1581
1730
  int err;
@@ -2345,6 +2494,22 @@ bare_ffmpeg_dictionary_set_entry(
2345
2494
  assert(err == 0);
2346
2495
  }
2347
2496
 
2497
+ static std::vector<std::tuple<const char *, const char *>>
2498
+ bare_ffmpeg_dictionary_get_entries(
2499
+ js_env_t *env,
2500
+ js_receiver_t,
2501
+ js_arraybuffer_span_of_t<bare_ffmpeg_dictionary_t, 1> dict
2502
+ ) {
2503
+ std::vector<std::tuple<const char *, const char *>> entries{};
2504
+
2505
+ const AVDictionaryEntry *entry = nullptr;
2506
+ while ((entry = av_dict_iterate(dict->handle, entry))) {
2507
+ entries.emplace_back(entry->key, entry->value);
2508
+ }
2509
+
2510
+ return entries;
2511
+ }
2512
+
2348
2513
  static std::optional<std::string>
2349
2514
  bare_ffmpeg_dictionary_get_entry(
2350
2515
  js_env_t *env,
@@ -2799,6 +2964,8 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
2799
2964
 
2800
2965
  V("codecParametersFromContext", bare_ffmpeg_codec_parameters_from_context)
2801
2966
  V("codecParametersToContext", bare_ffmpeg_codec_parameters_to_context)
2967
+ V("allocCodecParameters", bare_ffmpeg_codec_parameters_alloc)
2968
+ V("destroyCodecParameters", bare_ffmpeg_codec_parameters_destroy)
2802
2969
  V("getCodecParametersBitRate", bare_ffmpeg_codec_parameters_get_bit_rate)
2803
2970
  V("setCodecParametersBitRate", bare_ffmpeg_codec_parameters_set_bit_rate)
2804
2971
  V("getCodecParametersBitsPerCodedSample", bare_ffmpeg_codec_parameters_get_bits_per_coded_sample)
@@ -2831,6 +2998,18 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
2831
2998
  V("setCodecParametersHeight", bare_ffmpeg_codec_parameters_set_height)
2832
2999
  V("getCodecParametersExtraData", bare_ffmpeg_codec_parameters_get_extra_data)
2833
3000
  V("setCodecParametersExtraData", bare_ffmpeg_codec_parameters_set_extra_data)
3001
+ V("getCodecParametersBlockAlign", bare_ffmpeg_codec_parameters_get_block_align)
3002
+ V("setCodecParametersBlockAlign", bare_ffmpeg_codec_parameters_set_block_align)
3003
+ V("getCodecParametersInitialPadding", bare_ffmpeg_codec_parameters_get_initial_padding)
3004
+ V("setCodecParametersInitialPadding", bare_ffmpeg_codec_parameters_set_initial_padding)
3005
+ V("getCodecParametersTrailingPadding", bare_ffmpeg_codec_parameters_get_trailing_padding)
3006
+ V("setCodecParametersTrailingPadding", bare_ffmpeg_codec_parameters_set_trailing_padding)
3007
+ V("getCodecParametersSeekPreroll", bare_ffmpeg_codec_parameters_get_seek_preroll)
3008
+ V("setCodecParametersSeekPreroll", bare_ffmpeg_codec_parameters_set_seek_preroll)
3009
+ V("getCodecParametersSampleAspectRatio", bare_ffmpeg_codec_parameters_get_sample_aspect_ratio)
3010
+ V("setCodecParametersSampleAspectRatio", bare_ffmpeg_codec_parameters_set_sample_aspect_ratio)
3011
+ V("getCodecParametersVideoDelay", bare_ffmpeg_codec_parameters_get_video_delay)
3012
+ V("setCodecParametersVideoDelay", bare_ffmpeg_codec_parameters_set_video_delay)
2834
3013
 
2835
3014
  V("initFrame", bare_ffmpeg_frame_init)
2836
3015
  V("destroyFrame", bare_ffmpeg_frame_destroy)
@@ -2892,6 +3071,7 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
2892
3071
  V("destroyDictionary", bare_ffmpeg_dictionary_destroy)
2893
3072
  V("getDictionaryEntry", bare_ffmpeg_dictionary_get_entry)
2894
3073
  V("setDictionaryEntry", bare_ffmpeg_dictionary_set_entry)
3074
+ V("getDictionaryEntries", bare_ffmpeg_dictionary_get_entries)
2895
3075
 
2896
3076
  V("initResampler", bare_ffmpeg_resampler_init)
2897
3077
  V("destroyResampler", bare_ffmpeg_resampler_destroy)
@@ -3,10 +3,13 @@ const ChannelLayout = require('./channel-layout')
3
3
  const Rational = require('./rational')
4
4
 
5
5
  module.exports = class FFmpegCodecParameters {
6
- constructor(handle) {
6
+ constructor(handle, owned = false) {
7
7
  this._handle = handle
8
+ this._owned = owned
8
9
  }
9
10
 
11
+ // Getters, Setters
12
+
10
13
  get bitRate() {
11
14
  return binding.getCodecParametersBitRate(this._handle)
12
15
  }
@@ -39,6 +42,21 @@ module.exports = class FFmpegCodecParameters {
39
42
  binding.setCodecParametersSampleRate(this._handle, rate)
40
43
  }
41
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
+
42
60
  get frameRate() {
43
61
  const view = new Int32Array(
44
62
  binding.getCodecParametersFramerate(this._handle)
@@ -54,6 +72,14 @@ module.exports = class FFmpegCodecParameters {
54
72
  )
55
73
  }
56
74
 
75
+ get videoDelay() {
76
+ return binding.getCodecParametersVideoDelay(this._handle)
77
+ }
78
+
79
+ set videoDelay(delay) {
80
+ binding.setCodecParametersVideoDelay(this._handle, delay)
81
+ }
82
+
57
83
  get nbChannels() {
58
84
  return binding.getCodecParametersNbChannels(this._handle)
59
85
  }
@@ -152,6 +178,40 @@ module.exports = class FFmpegCodecParameters {
152
178
  )
153
179
  }
154
180
 
181
+ get blockAlign() {
182
+ return binding.getCodecParametersBlockAlign(this._handle)
183
+ }
184
+
185
+ set blockAlign(value) {
186
+ binding.setCodecParametersBlockAlign(this._handle, value)
187
+ }
188
+
189
+ get initialPadding() {
190
+ return binding.getCodecParametersInitialPadding(this._handle)
191
+ }
192
+
193
+ set initialPadding(value) {
194
+ binding.setCodecParametersInitialPadding(this._handle, value)
195
+ }
196
+
197
+ get trailingPadding() {
198
+ return binding.getCodecParametersTrailingPadding(this._handle)
199
+ }
200
+
201
+ set trailingPadding(value) {
202
+ binding.setCodecParametersTrailingPadding(this._handle, value)
203
+ }
204
+
205
+ get seekPreroll() {
206
+ return binding.getCodecParametersSeekPreroll(this._handle)
207
+ }
208
+
209
+ set seekPreroll(value) {
210
+ binding.setCodecParametersSeekPreroll(this._handle, value)
211
+ }
212
+
213
+ // Methods
214
+
155
215
  fromContext(context) {
156
216
  binding.codecParametersFromContext(this._handle, context._handle)
157
217
  }
@@ -160,6 +220,14 @@ module.exports = class FFmpegCodecParameters {
160
220
  binding.codecParametersToContext(context._handle, this._handle)
161
221
  }
162
222
 
223
+ destroy() {
224
+ if (this._owned) binding.destroyCodecParameters(this._handle)
225
+ }
226
+
227
+ [Symbol.dispose]() {
228
+ this.destroy()
229
+ }
230
+
163
231
  // TODO: add other props
164
232
  [Symbol.for('bare.inspect')]() {
165
233
  return {
@@ -178,7 +246,15 @@ module.exports = class FFmpegCodecParameters {
178
246
  nbChannels: this.nbChannels,
179
247
  channelLayout: this.channelLayout,
180
248
  frameRate: this.frameRate,
181
- extraData: this.extraData
249
+ extraData: this.extraData,
250
+ blockAlign: this.blockAlign,
251
+ initialPadding: this.initialPadding,
252
+ trailingPadding: this.trailingPadding,
253
+ seekPreroll: this.seekPreroll
182
254
  }
183
255
  }
256
+
257
+ static alloc() {
258
+ return new FFmpegCodecParameters(binding.allocCodecParameters(), true)
259
+ }
184
260
  }
package/lib/dictionary.js CHANGED
@@ -22,6 +22,14 @@ module.exports = class FFmpegDictionary {
22
22
  binding.setDictionaryEntry(this._handle, key, value)
23
23
  }
24
24
 
25
+ entries() {
26
+ return binding.getDictionaryEntries(this._handle)
27
+ }
28
+
29
+ *[Symbol.iterator]() {
30
+ yield* this.entries()
31
+ }
32
+
25
33
  [Symbol.dispose]() {
26
34
  this.destroy()
27
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-ffmpeg",
3
- "version": "1.0.0-20",
3
+ "version": "1.0.0-21",
4
4
  "description": "Low-level FFmpeg bindings for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",