bare-ffmpeg 1.0.0-24 → 1.0.0-26
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 +154 -4
- package/binding.cc +254 -28
- package/cmake/ports/ffmpeg/port.cmake +1 -1
- package/lib/codec-context.js +15 -1
- package/lib/codec-parameters.js +8 -0
- package/lib/constants.js +55 -0
- package/lib/packet.js +59 -0
- package/package.json +1 -1
- package/prebuilds/android-arm/bare-ffmpeg.bare +0 -0
- package/prebuilds/android-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/android-ia32/bare-ffmpeg.bare +0 -0
- package/prebuilds/android-x64/bare-ffmpeg.bare +0 -0
- package/prebuilds/darwin-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/darwin-x64/bare-ffmpeg.bare +0 -0
- package/prebuilds/ios-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/ios-arm64-simulator/bare-ffmpeg.bare +0 -0
- package/prebuilds/ios-x64-simulator/bare-ffmpeg.bare +0 -0
- package/prebuilds/linux-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/linux-x64/bare-ffmpeg.bare +0 -0
- package/prebuilds/win32-arm64/bare-ffmpeg.bare +0 -0
- package/prebuilds/win32-x64/bare-ffmpeg.bare +0 -0
package/README.md
CHANGED
|
@@ -10,19 +10,59 @@ npm i bare-ffmpeg
|
|
|
10
10
|
|
|
11
11
|
### `IOContext`
|
|
12
12
|
|
|
13
|
-
The `IOContext` API provides functionality to create input/output contexts for media files.
|
|
13
|
+
The `IOContext` API provides functionality to create input/output contexts for media files with support for streaming and custom I/O operations.
|
|
14
14
|
|
|
15
15
|
```js
|
|
16
|
-
const io = new ffmpeg.IOContext(buffer)
|
|
16
|
+
const io = new ffmpeg.IOContext(buffer[, options])
|
|
17
17
|
```
|
|
18
18
|
|
|
19
19
|
Parameters:
|
|
20
20
|
|
|
21
|
-
- `buffer` (`Buffer`): The media data buffer
|
|
21
|
+
- `buffer` (`Buffer` | `number`): The media data buffer or buffer size for streaming
|
|
22
|
+
- `options` (`object`, optional): Configuration options
|
|
23
|
+
- `onread` (`function`): A function for refilling the buffer.
|
|
24
|
+
- `onwrite` (`function`): A function for writing the buffer contents.
|
|
25
|
+
- `onseek` (`function`): A function for seeking to specified byte position.
|
|
22
26
|
|
|
23
27
|
**Returns**: A new `IOContext` instance
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
#### Constructor Options
|
|
30
|
+
|
|
31
|
+
##### `onread(buffer, requestedLen)`
|
|
32
|
+
|
|
33
|
+
Callback function called when FFmpeg needs to read data. For streaming scenarios where data is not available in a single buffer.
|
|
34
|
+
|
|
35
|
+
Parameters:
|
|
36
|
+
|
|
37
|
+
- `buffer` (`Buffer`): Buffer to fill with data
|
|
38
|
+
- `requestedLen` (`number`): Number of bytes requested
|
|
39
|
+
|
|
40
|
+
**Returns**: `number` - Number of bytes actually read, or 0 for EOF
|
|
41
|
+
|
|
42
|
+
##### `onwrite(buffer)`
|
|
43
|
+
|
|
44
|
+
Callback function called when FFmpeg needs to write data. For streaming output scenarios.
|
|
45
|
+
|
|
46
|
+
Parameters:
|
|
47
|
+
|
|
48
|
+
- `buffer` (`Buffer`): Buffer containing data to write
|
|
49
|
+
|
|
50
|
+
**Returns**: `number` - Number of bytes written
|
|
51
|
+
|
|
52
|
+
##### `onseek(offset, whence)`
|
|
53
|
+
|
|
54
|
+
Callback function called when FFmpeg needs to seek within the data source.
|
|
55
|
+
|
|
56
|
+
Parameters:
|
|
57
|
+
|
|
58
|
+
- `offset` (`number`): Offset to seek to
|
|
59
|
+
- `whence` (`number`): Seek mode (see `ffmpeg.constants.seek`)
|
|
60
|
+
|
|
61
|
+
**Returns**: `number` - New position or file size for `AVSEEK_SIZE`
|
|
62
|
+
|
|
63
|
+
#### Examples
|
|
64
|
+
|
|
65
|
+
**Basic usage with buffer:**
|
|
26
66
|
|
|
27
67
|
```js
|
|
28
68
|
const image = require('./fixtures/image/sample.jpeg', {
|
|
@@ -32,6 +72,43 @@ const io = new ffmpeg.IOContext(image)
|
|
|
32
72
|
io.destroy()
|
|
33
73
|
```
|
|
34
74
|
|
|
75
|
+
**Streaming with custom read callback:**
|
|
76
|
+
|
|
77
|
+
```js
|
|
78
|
+
const io = new ffmpeg.IOContext(4096, {
|
|
79
|
+
onread: (buffer) => {
|
|
80
|
+
const bytesToRead = Math.min(buffer.length, data.length - offset)
|
|
81
|
+
if (bytesToRead === 0) return 0
|
|
82
|
+
|
|
83
|
+
const chunk = data.subarray(offset, offset + bytesToRead)
|
|
84
|
+
buffer.set(chunk)
|
|
85
|
+
offset += bytesToRead
|
|
86
|
+
return bytesToRead
|
|
87
|
+
}
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
**Streaming with seek support:**
|
|
92
|
+
|
|
93
|
+
```js
|
|
94
|
+
const io = new ffmpeg.IOContext(4096, {
|
|
95
|
+
onread: (buffer) => {
|
|
96
|
+
// ... read implementation
|
|
97
|
+
},
|
|
98
|
+
onseek: (offset, whence) => {
|
|
99
|
+
switch (whence) {
|
|
100
|
+
case ffmpeg.constants.seek.SIZE:
|
|
101
|
+
return data.length
|
|
102
|
+
case ffmpeg.constants.seek.SET:
|
|
103
|
+
offset = offset
|
|
104
|
+
return offset
|
|
105
|
+
default:
|
|
106
|
+
return -1
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
})
|
|
110
|
+
```
|
|
111
|
+
|
|
35
112
|
#### Methods
|
|
36
113
|
|
|
37
114
|
##### `IOContext.destroy()`
|
|
@@ -675,6 +752,18 @@ Gets the stream index this packet belongs to.
|
|
|
675
752
|
|
|
676
753
|
**Returns**: `number`
|
|
677
754
|
|
|
755
|
+
##### `Packet.isKeyFrame`
|
|
756
|
+
|
|
757
|
+
Get or set the key frame flag.
|
|
758
|
+
|
|
759
|
+
**Returns**: `boolean`
|
|
760
|
+
|
|
761
|
+
##### `Packet.sideData`
|
|
762
|
+
|
|
763
|
+
Gets or sets the side data associated with the packet.
|
|
764
|
+
|
|
765
|
+
**Returns**: `Array<SideData>`
|
|
766
|
+
|
|
678
767
|
#### Methods
|
|
679
768
|
|
|
680
769
|
##### `Packet.unref()`
|
|
@@ -689,6 +778,67 @@ Destroys the `Packet` and frees all associated resources. Automatically called w
|
|
|
689
778
|
|
|
690
779
|
**Returns**: `void`
|
|
691
780
|
|
|
781
|
+
### `SideData`
|
|
782
|
+
|
|
783
|
+
The `SideData` API provides functionality to handle side data associated with packets. Side data contains additional metadata that may be useful for specific codecs or processing.
|
|
784
|
+
|
|
785
|
+
```js
|
|
786
|
+
const sideData = new ffmpeg.Packet.SideData(handle, options)
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
Parameters:
|
|
790
|
+
|
|
791
|
+
- `handle` (`ArrayBuffer`): Internal side data handle
|
|
792
|
+
- `options` (`object`, optional): Configuration options
|
|
793
|
+
- `type` (`number`): The side data type
|
|
794
|
+
- `data` (`Buffer`): The side data buffer
|
|
795
|
+
|
|
796
|
+
**Returns**: A new `SideData` instance
|
|
797
|
+
|
|
798
|
+
#### Static Methods
|
|
799
|
+
|
|
800
|
+
##### `SideData.fromData(data, type)`
|
|
801
|
+
|
|
802
|
+
Creates a new `SideData` instance from data and type.
|
|
803
|
+
|
|
804
|
+
Parameters:
|
|
805
|
+
|
|
806
|
+
- `data` (`Buffer`): The side data buffer
|
|
807
|
+
- `type` (`number`): The side data type constant
|
|
808
|
+
|
|
809
|
+
**Returns**: A new `SideData` instance
|
|
810
|
+
|
|
811
|
+
#### Properties
|
|
812
|
+
|
|
813
|
+
##### `SideData.type`
|
|
814
|
+
|
|
815
|
+
Gets the side data type.
|
|
816
|
+
|
|
817
|
+
**Returns**: `number`
|
|
818
|
+
|
|
819
|
+
##### `SideData.name`
|
|
820
|
+
|
|
821
|
+
Gets the human-readable name of the side data type.
|
|
822
|
+
|
|
823
|
+
**Returns**: `string`
|
|
824
|
+
|
|
825
|
+
##### `SideData.data`
|
|
826
|
+
|
|
827
|
+
Gets the side data buffer.
|
|
828
|
+
|
|
829
|
+
**Returns**: `Buffer`
|
|
830
|
+
|
|
831
|
+
#### Example
|
|
832
|
+
|
|
833
|
+
```js
|
|
834
|
+
const packet = new ffmpeg.Packet()
|
|
835
|
+
const sideData = ffmpeg.Packet.SideData.fromData(
|
|
836
|
+
Buffer.from('metadata'),
|
|
837
|
+
ffmpeg.constants.packetSideDataType.NEW_EXTRADATA
|
|
838
|
+
)
|
|
839
|
+
packet.sideData = [sideData]
|
|
840
|
+
```
|
|
841
|
+
|
|
692
842
|
### `Image`
|
|
693
843
|
|
|
694
844
|
The `Image` API provides functionality to create and manage image buffers.
|
package/binding.cc
CHANGED
|
@@ -35,7 +35,7 @@ extern "C" {
|
|
|
35
35
|
|
|
36
36
|
using bare_ffmpeg_io_context_write_cb_t = js_function_t<void, js_arraybuffer_t>;
|
|
37
37
|
using bare_ffmpeg_io_context_read_cb_t = js_function_t<int32_t, js_arraybuffer_t, int32_t>;
|
|
38
|
-
using bare_ffmpeg_io_context_seek_cb_t = js_function_t<int64_t, int64_t,
|
|
38
|
+
using bare_ffmpeg_io_context_seek_cb_t = js_function_t<int64_t, int64_t, int>;
|
|
39
39
|
|
|
40
40
|
typedef struct {
|
|
41
41
|
AVIOContext *handle;
|
|
@@ -103,6 +103,10 @@ typedef struct {
|
|
|
103
103
|
AVAudioFifo *handle;
|
|
104
104
|
} bare_ffmpeg_audio_fifo_t;
|
|
105
105
|
|
|
106
|
+
typedef struct {
|
|
107
|
+
AVPacketSideData *handle;
|
|
108
|
+
} bare_ffmpeg_side_data_t;
|
|
109
|
+
|
|
106
110
|
static uv_once_t bare_ffmpeg__init_guard = UV_ONCE_INIT;
|
|
107
111
|
|
|
108
112
|
static inline bool
|
|
@@ -145,7 +149,8 @@ bare_ffmpeg__on_io_context_write(void *opaque, const uint8_t *buf, int len) {
|
|
|
145
149
|
assert(err == 0);
|
|
146
150
|
|
|
147
151
|
err = js_call_function(env, callback, data);
|
|
148
|
-
|
|
152
|
+
|
|
153
|
+
if (err < 0) return AVERROR(EIO);
|
|
149
154
|
|
|
150
155
|
return 0;
|
|
151
156
|
}
|
|
@@ -181,39 +186,21 @@ bare_ffmpeg__on_io_context_read(void *opaque, uint8_t *buf, int len) {
|
|
|
181
186
|
|
|
182
187
|
static int64_t
|
|
183
188
|
bare_ffmpeg__on_io_context_seek(void *opaque, int64_t offset, int whence) {
|
|
184
|
-
int err;
|
|
185
|
-
|
|
186
189
|
auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
|
|
187
|
-
|
|
188
190
|
auto env = context->env;
|
|
189
191
|
|
|
190
192
|
int64_t result;
|
|
191
|
-
std::string whence_str;
|
|
192
|
-
switch (whence) {
|
|
193
|
-
case AVSEEK_SIZE:
|
|
194
|
-
whence_str = "avseek_size";
|
|
195
|
-
break;
|
|
196
|
-
case AVSEEK_FORCE:
|
|
197
|
-
whence_str = "avseek_force";
|
|
198
|
-
break;
|
|
199
|
-
case SEEK_SET:
|
|
200
|
-
whence_str = "seek_set";
|
|
201
|
-
break;
|
|
202
|
-
case SEEK_CUR:
|
|
203
|
-
whence_str = "seek_cur";
|
|
204
|
-
break;
|
|
205
|
-
case SEEK_END:
|
|
206
|
-
whence_str = "seek_end";
|
|
207
|
-
break;
|
|
208
|
-
default:
|
|
209
|
-
whence_str = "unknown:" + std::to_string(whence);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
193
|
bare_ffmpeg_io_context_seek_cb_t callback;
|
|
213
|
-
err = js_get_reference_value(env, context->on_seek, callback);
|
|
194
|
+
int err = js_get_reference_value(env, context->on_seek, callback);
|
|
214
195
|
assert(err == 0);
|
|
215
196
|
|
|
216
|
-
err = js_call_function<
|
|
197
|
+
err = js_call_function<
|
|
198
|
+
js_type_options_t{},
|
|
199
|
+
int64_t,
|
|
200
|
+
int64_t,
|
|
201
|
+
int>(
|
|
202
|
+
env, callback, offset, whence, result
|
|
203
|
+
);
|
|
217
204
|
if (err < 0) return AVERROR(EIO); // read-error
|
|
218
205
|
|
|
219
206
|
if (result == -1) {
|
|
@@ -391,6 +378,12 @@ bare_ffmpeg_format_context_open_input_with_io(
|
|
|
391
378
|
if (err < 0) {
|
|
392
379
|
avformat_free_context(context->handle);
|
|
393
380
|
|
|
381
|
+
bool is_exception_pending;
|
|
382
|
+
err = js_is_exception_pending(env, &is_exception_pending);
|
|
383
|
+
assert(err == 0);
|
|
384
|
+
|
|
385
|
+
if (is_exception_pending) throw js_pending_exception;
|
|
386
|
+
|
|
394
387
|
err = js_throw_error(env, NULL, av_err2str(err));
|
|
395
388
|
assert(err == 0);
|
|
396
389
|
|
|
@@ -828,6 +821,11 @@ bare_ffmpeg_get_codec_name_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
|
|
|
828
821
|
return std::string(name);
|
|
829
822
|
}
|
|
830
823
|
|
|
824
|
+
static std::string
|
|
825
|
+
bare_ffmpeg_get_sample_format_name_by_id(js_env_t *env, js_receiver_t, uint32_t id) {
|
|
826
|
+
return av_get_sample_fmt_name(static_cast<enum AVSampleFormat>(id));
|
|
827
|
+
}
|
|
828
|
+
|
|
831
829
|
static js_arraybuffer_t
|
|
832
830
|
bare_ffmpeg_codec_context_init(
|
|
833
831
|
js_env_t *env,
|
|
@@ -895,6 +893,49 @@ bare_ffmpeg_codec_context_set_flags(
|
|
|
895
893
|
context->handle->flags = value;
|
|
896
894
|
}
|
|
897
895
|
|
|
896
|
+
static js_arraybuffer_t
|
|
897
|
+
bare_ffmpeg_codec_context_get_extra_data(
|
|
898
|
+
js_env_t *env,
|
|
899
|
+
js_receiver_t,
|
|
900
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context
|
|
901
|
+
) {
|
|
902
|
+
js_arraybuffer_t buffer;
|
|
903
|
+
int err = js_create_arraybuffer(
|
|
904
|
+
env,
|
|
905
|
+
context->handle->extradata,
|
|
906
|
+
static_cast<size_t>(context->handle->extradata_size),
|
|
907
|
+
buffer
|
|
908
|
+
);
|
|
909
|
+
assert(err == 0);
|
|
910
|
+
|
|
911
|
+
return buffer;
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
void
|
|
915
|
+
bare_ffmpeg_codec_context_set_extra_data(
|
|
916
|
+
js_env_t *env,
|
|
917
|
+
js_receiver_t,
|
|
918
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_codec_context_t, 1> context,
|
|
919
|
+
js_arraybuffer_t buffer,
|
|
920
|
+
uint32_t offset,
|
|
921
|
+
uint32_t len
|
|
922
|
+
) {
|
|
923
|
+
std::span<uint8_t> view;
|
|
924
|
+
int err = js_get_arraybuffer_info(env, buffer, view);
|
|
925
|
+
assert(err == 0);
|
|
926
|
+
|
|
927
|
+
if (context->handle->extradata_size) {
|
|
928
|
+
av_free(context->handle->extradata);
|
|
929
|
+
}
|
|
930
|
+
|
|
931
|
+
context->handle->extradata = reinterpret_cast<uint8_t *>(av_malloc(len + AV_INPUT_BUFFER_PADDING_SIZE));
|
|
932
|
+
|
|
933
|
+
memset(&context->handle->extradata[len], 0, AV_INPUT_BUFFER_PADDING_SIZE);
|
|
934
|
+
memcpy(context->handle->extradata, &view[offset], len);
|
|
935
|
+
|
|
936
|
+
context->handle->extradata_size = static_cast<int>(len);
|
|
937
|
+
}
|
|
938
|
+
|
|
898
939
|
static int
|
|
899
940
|
bare_ffmpeg_frame_get_format(
|
|
900
941
|
js_env_t *env,
|
|
@@ -1820,6 +1861,25 @@ bare_ffmpeg_codec_parameters_set_video_delay(
|
|
|
1820
1861
|
parameters->handle->video_delay = delay;
|
|
1821
1862
|
}
|
|
1822
1863
|
|
|
1864
|
+
static int
|
|
1865
|
+
bare_ffmpeg_codec_parameters_get_frame_size(
|
|
1866
|
+
js_env_t *env,
|
|
1867
|
+
js_receiver_t,
|
|
1868
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters
|
|
1869
|
+
) {
|
|
1870
|
+
return parameters->handle->frame_size;
|
|
1871
|
+
}
|
|
1872
|
+
|
|
1873
|
+
static void
|
|
1874
|
+
bare_ffmpeg_codec_parameters_set_frame_size(
|
|
1875
|
+
js_env_t *env,
|
|
1876
|
+
js_receiver_t,
|
|
1877
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_codec_parameters_t, 1> parameters,
|
|
1878
|
+
int frame_size
|
|
1879
|
+
) {
|
|
1880
|
+
parameters->handle->frame_size = frame_size;
|
|
1881
|
+
}
|
|
1882
|
+
|
|
1823
1883
|
static js_arraybuffer_t
|
|
1824
1884
|
bare_ffmpeg_frame_init(js_env_t *env, js_receiver_t) {
|
|
1825
1885
|
int err;
|
|
@@ -2329,6 +2389,62 @@ bare_ffmpeg_packet_set_data(
|
|
|
2329
2389
|
memcpy(packet->handle->data, &data[offset], len);
|
|
2330
2390
|
}
|
|
2331
2391
|
|
|
2392
|
+
static std::vector<js_arraybuffer_t>
|
|
2393
|
+
bare_ffmpeg_packet_get_side_data(
|
|
2394
|
+
js_env_t *env,
|
|
2395
|
+
js_receiver_t,
|
|
2396
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet
|
|
2397
|
+
) {
|
|
2398
|
+
std::vector<js_arraybuffer_t> res{};
|
|
2399
|
+
|
|
2400
|
+
int count = packet->handle->side_data_elems;
|
|
2401
|
+
if (count == 0) return res;
|
|
2402
|
+
|
|
2403
|
+
for (int i = 0; i < count; i++) {
|
|
2404
|
+
js_arraybuffer_t handle;
|
|
2405
|
+
bare_ffmpeg_side_data_t *sd;
|
|
2406
|
+
int err = js_create_arraybuffer(env, sd, handle);
|
|
2407
|
+
assert(err == 0);
|
|
2408
|
+
|
|
2409
|
+
sd->handle = &packet->handle->side_data[i];
|
|
2410
|
+
|
|
2411
|
+
res.push_back(handle);
|
|
2412
|
+
}
|
|
2413
|
+
|
|
2414
|
+
return res;
|
|
2415
|
+
}
|
|
2416
|
+
|
|
2417
|
+
static void
|
|
2418
|
+
bare_ffmpeg_packet_set_side_data(
|
|
2419
|
+
js_env_t *env,
|
|
2420
|
+
js_receiver_t,
|
|
2421
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
|
|
2422
|
+
std::vector<js_object_t> side_data_array
|
|
2423
|
+
) {
|
|
2424
|
+
for (js_object_t side_data : side_data_array) {
|
|
2425
|
+
int err;
|
|
2426
|
+
|
|
2427
|
+
int32_t type;
|
|
2428
|
+
err = js_get_property(env, side_data, "type", type);
|
|
2429
|
+
assert(err == 0);
|
|
2430
|
+
|
|
2431
|
+
js_arraybuffer_span_t buf;
|
|
2432
|
+
err = js_get_property(env, side_data, "buffer", buf);
|
|
2433
|
+
assert(err == 0);
|
|
2434
|
+
|
|
2435
|
+
int32_t offset;
|
|
2436
|
+
err = js_get_property(env, side_data, "offset", offset);
|
|
2437
|
+
assert(err == 0);
|
|
2438
|
+
|
|
2439
|
+
int32_t len;
|
|
2440
|
+
err = js_get_property(env, side_data, "length", len);
|
|
2441
|
+
assert(err == 0);
|
|
2442
|
+
|
|
2443
|
+
uint8_t *data = av_packet_new_side_data(packet->handle, static_cast<AVPacketSideDataType>(type), static_cast<size_t>(len));
|
|
2444
|
+
memcpy(data, &buf[static_cast<size_t>(offset)], static_cast<size_t>(len));
|
|
2445
|
+
}
|
|
2446
|
+
}
|
|
2447
|
+
|
|
2332
2448
|
static bool
|
|
2333
2449
|
bare_ffmpeg_packet_is_keyframe(
|
|
2334
2450
|
js_env_t *,
|
|
@@ -2338,6 +2454,20 @@ bare_ffmpeg_packet_is_keyframe(
|
|
|
2338
2454
|
return packet->handle->flags & AV_PKT_FLAG_KEY;
|
|
2339
2455
|
}
|
|
2340
2456
|
|
|
2457
|
+
static void
|
|
2458
|
+
bare_ffmpeg_packet_set_is_keyframe(
|
|
2459
|
+
js_env_t *,
|
|
2460
|
+
js_receiver_t,
|
|
2461
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_packet_t, 1> packet,
|
|
2462
|
+
bool has_key_frame
|
|
2463
|
+
) {
|
|
2464
|
+
if (has_key_frame) {
|
|
2465
|
+
packet->handle->flags |= AV_PKT_FLAG_KEY;
|
|
2466
|
+
} else {
|
|
2467
|
+
packet->handle->flags &= ~AV_PKT_FLAG_KEY;
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
|
|
2341
2471
|
static int64_t
|
|
2342
2472
|
bare_ffmpeg_packet_get_dts(
|
|
2343
2473
|
js_env_t *env,
|
|
@@ -2480,6 +2610,40 @@ bare_ffmpeg_packet_set_flags(
|
|
|
2480
2610
|
packet->handle->flags = value;
|
|
2481
2611
|
}
|
|
2482
2612
|
|
|
2613
|
+
static int
|
|
2614
|
+
bare_ffmpeg_side_data_get_type(
|
|
2615
|
+
js_env_t *env,
|
|
2616
|
+
js_receiver_t,
|
|
2617
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_side_data_t, 1> side_data
|
|
2618
|
+
) {
|
|
2619
|
+
return side_data->handle->type;
|
|
2620
|
+
}
|
|
2621
|
+
|
|
2622
|
+
static std::string
|
|
2623
|
+
bare_ffmpeg_side_data_get_name(
|
|
2624
|
+
js_env_t *env,
|
|
2625
|
+
js_receiver_t,
|
|
2626
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_side_data_t, 1> side_data
|
|
2627
|
+
) {
|
|
2628
|
+
return av_packet_side_data_name(side_data->handle->type);
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
static js_arraybuffer_t
|
|
2632
|
+
bare_ffmpeg_side_data_get_data(
|
|
2633
|
+
js_env_t *env,
|
|
2634
|
+
js_receiver_t,
|
|
2635
|
+
js_arraybuffer_span_of_t<bare_ffmpeg_side_data_t, 1> side_data
|
|
2636
|
+
) {
|
|
2637
|
+
js_arraybuffer_t handle;
|
|
2638
|
+
uint8_t *buf;
|
|
2639
|
+
int err = js_create_arraybuffer(env, side_data->handle->size, buf, handle);
|
|
2640
|
+
assert(err == 0);
|
|
2641
|
+
|
|
2642
|
+
memcpy(buf, side_data->handle->data, side_data->handle->size);
|
|
2643
|
+
|
|
2644
|
+
return handle;
|
|
2645
|
+
}
|
|
2646
|
+
|
|
2483
2647
|
static js_arraybuffer_t
|
|
2484
2648
|
bare_ffmpeg_scaler_init(
|
|
2485
2649
|
js_env_t *env,
|
|
@@ -3031,6 +3195,7 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3031
3195
|
V("findDecoderByID", bare_ffmpeg_find_decoder_by_id)
|
|
3032
3196
|
V("findEncoderByID", bare_ffmpeg_find_encoder_by_id)
|
|
3033
3197
|
V("getCodecNameByID", bare_ffmpeg_get_codec_name_by_id)
|
|
3198
|
+
V("getSampleFormatNameByID", bare_ffmpeg_get_sample_format_name_by_id)
|
|
3034
3199
|
|
|
3035
3200
|
V("initCodecContext", bare_ffmpeg_codec_context_init)
|
|
3036
3201
|
V("destroyCodecContext", bare_ffmpeg_codec_context_destroy)
|
|
@@ -3056,6 +3221,8 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3056
3221
|
V("setCodecContextGOPSize", bare_ffmpeg_codec_context_set_gop_size)
|
|
3057
3222
|
V("getCodecContextFramerate", bare_ffmpeg_codec_context_get_framerate)
|
|
3058
3223
|
V("setCodecContextFramerate", bare_ffmpeg_codec_context_set_framerate)
|
|
3224
|
+
V("getCodecContextExtraData", bare_ffmpeg_codec_context_get_extra_data)
|
|
3225
|
+
V("setCodecContextExtraData", bare_ffmpeg_codec_context_set_extra_data)
|
|
3059
3226
|
|
|
3060
3227
|
V("sendCodecContextPacket", bare_ffmpeg_codec_context_send_packet)
|
|
3061
3228
|
V("receiveCodecContextPacket", bare_ffmpeg_codec_context_receive_packet)
|
|
@@ -3110,6 +3277,8 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3110
3277
|
V("setCodecParametersSampleAspectRatio", bare_ffmpeg_codec_parameters_set_sample_aspect_ratio)
|
|
3111
3278
|
V("getCodecParametersVideoDelay", bare_ffmpeg_codec_parameters_get_video_delay)
|
|
3112
3279
|
V("setCodecParametersVideoDelay", bare_ffmpeg_codec_parameters_set_video_delay)
|
|
3280
|
+
V("getCodecParametersFrameSize", bare_ffmpeg_codec_parameters_get_frame_size)
|
|
3281
|
+
V("setCodecParametersFrameSize", bare_ffmpeg_codec_parameters_set_frame_size)
|
|
3113
3282
|
|
|
3114
3283
|
V("initFrame", bare_ffmpeg_frame_init)
|
|
3115
3284
|
V("destroyFrame", bare_ffmpeg_frame_destroy)
|
|
@@ -3149,7 +3318,10 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3149
3318
|
V("setPacketStreamIndex", bare_ffmpeg_packet_set_stream_index)
|
|
3150
3319
|
V("getPacketData", bare_ffmpeg_packet_get_data)
|
|
3151
3320
|
V("setPacketData", bare_ffmpeg_packet_set_data)
|
|
3321
|
+
V("getPacketSideData", bare_ffmpeg_packet_get_side_data)
|
|
3322
|
+
V("setPacketSideData", bare_ffmpeg_packet_set_side_data)
|
|
3152
3323
|
V("isPacketKeyframe", bare_ffmpeg_packet_is_keyframe)
|
|
3324
|
+
V("setPacketIsKeyFrame", bare_ffmpeg_packet_set_is_keyframe)
|
|
3153
3325
|
V("getPacketDTS", bare_ffmpeg_packet_get_dts)
|
|
3154
3326
|
V("setPacketDTS", bare_ffmpeg_packet_set_dts)
|
|
3155
3327
|
V("getPacketPTS", bare_ffmpeg_packet_get_pts)
|
|
@@ -3162,6 +3334,10 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3162
3334
|
V("getPacketFlags", bare_ffmpeg_packet_get_flags)
|
|
3163
3335
|
V("setPacketFlags", bare_ffmpeg_packet_set_flags)
|
|
3164
3336
|
|
|
3337
|
+
V("getSideDataType", bare_ffmpeg_side_data_get_type)
|
|
3338
|
+
V("getSideDataName", bare_ffmpeg_side_data_get_name)
|
|
3339
|
+
V("getSideDataBuffer", bare_ffmpeg_side_data_get_data)
|
|
3340
|
+
|
|
3165
3341
|
V("initScaler", bare_ffmpeg_scaler_init)
|
|
3166
3342
|
V("destroyScaler", bare_ffmpeg_scaler_destroy)
|
|
3167
3343
|
V("scaleScaler", bare_ffmpeg_scaler_scale)
|
|
@@ -3421,6 +3597,56 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3421
3597
|
|
|
3422
3598
|
// Levels
|
|
3423
3599
|
V(AV_LEVEL_UNKNOWN)
|
|
3600
|
+
|
|
3601
|
+
// SEEK
|
|
3602
|
+
V(AVSEEK_SIZE)
|
|
3603
|
+
V(AVSEEK_FORCE)
|
|
3604
|
+
V(SEEK_CUR)
|
|
3605
|
+
V(SEEK_SET)
|
|
3606
|
+
V(SEEK_END)
|
|
3607
|
+
|
|
3608
|
+
V(AV_PKT_DATA_PALETTE)
|
|
3609
|
+
V(AV_PKT_DATA_NEW_EXTRADATA)
|
|
3610
|
+
V(AV_PKT_DATA_PARAM_CHANGE)
|
|
3611
|
+
V(AV_PKT_DATA_H263_MB_INFO)
|
|
3612
|
+
V(AV_PKT_DATA_REPLAYGAIN)
|
|
3613
|
+
V(AV_PKT_DATA_DISPLAYMATRIX)
|
|
3614
|
+
V(AV_PKT_DATA_STEREO3D)
|
|
3615
|
+
V(AV_PKT_DATA_AUDIO_SERVICE_TYPE)
|
|
3616
|
+
V(AV_PKT_DATA_QUALITY_STATS)
|
|
3617
|
+
V(AV_PKT_DATA_FALLBACK_TRACK)
|
|
3618
|
+
V(AV_PKT_DATA_CPB_PROPERTIES)
|
|
3619
|
+
V(AV_PKT_DATA_SKIP_SAMPLES)
|
|
3620
|
+
V(AV_PKT_DATA_JP_DUALMONO)
|
|
3621
|
+
V(AV_PKT_DATA_STRINGS_METADATA)
|
|
3622
|
+
V(AV_PKT_DATA_SUBTITLE_POSITION)
|
|
3623
|
+
V(AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL)
|
|
3624
|
+
V(AV_PKT_DATA_WEBVTT_IDENTIFIER)
|
|
3625
|
+
V(AV_PKT_DATA_WEBVTT_SETTINGS)
|
|
3626
|
+
V(AV_PKT_DATA_METADATA_UPDATE)
|
|
3627
|
+
V(AV_PKT_DATA_MPEGTS_STREAM_ID)
|
|
3628
|
+
V(AV_PKT_DATA_MASTERING_DISPLAY_METADATA)
|
|
3629
|
+
V(AV_PKT_DATA_SPHERICAL)
|
|
3630
|
+
V(AV_PKT_DATA_CONTENT_LIGHT_LEVEL)
|
|
3631
|
+
V(AV_PKT_DATA_A53_CC)
|
|
3632
|
+
V(AV_PKT_DATA_ENCRYPTION_INIT_INFO)
|
|
3633
|
+
V(AV_PKT_DATA_ENCRYPTION_INFO)
|
|
3634
|
+
V(AV_PKT_DATA_AFD)
|
|
3635
|
+
V(AV_PKT_DATA_PRFT)
|
|
3636
|
+
V(AV_PKT_DATA_ICC_PROFILE)
|
|
3637
|
+
V(AV_PKT_DATA_DOVI_CONF)
|
|
3638
|
+
V(AV_PKT_DATA_S12M_TIMECODE)
|
|
3639
|
+
V(AV_PKT_DATA_DYNAMIC_HDR10_PLUS)
|
|
3640
|
+
V(AV_PKT_DATA_IAMF_MIX_GAIN_PARAM)
|
|
3641
|
+
V(AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM)
|
|
3642
|
+
V(AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM)
|
|
3643
|
+
V(AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT)
|
|
3644
|
+
V(AV_PKT_DATA_FRAME_CROPPING)
|
|
3645
|
+
V(AV_PKT_DATA_LCEVC)
|
|
3646
|
+
V(AV_PKT_DATA_3D_REFERENCE_DISPLAYS)
|
|
3647
|
+
V(AV_PKT_DATA_RTCP_SR)
|
|
3648
|
+
V(AV_PKT_DATA_NB)
|
|
3649
|
+
|
|
3424
3650
|
#undef V
|
|
3425
3651
|
|
|
3426
3652
|
return exports;
|
package/lib/codec-context.js
CHANGED
|
@@ -107,6 +107,19 @@ module.exports = class FFmpegCodecContext {
|
|
|
107
107
|
binding.setCodecContextFlags(this._handle, value)
|
|
108
108
|
}
|
|
109
109
|
|
|
110
|
+
get extraData() {
|
|
111
|
+
return Buffer.from(binding.getCodecContextExtraData(this._handle))
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
set extraData(value) {
|
|
115
|
+
binding.setCodecContextExtraData(
|
|
116
|
+
this._handle,
|
|
117
|
+
value.buffer,
|
|
118
|
+
value.byteOffset,
|
|
119
|
+
value.byteLength
|
|
120
|
+
)
|
|
121
|
+
}
|
|
122
|
+
|
|
110
123
|
open(options) {
|
|
111
124
|
if (this._opened) return
|
|
112
125
|
this._opened = true
|
|
@@ -155,7 +168,8 @@ module.exports = class FFmpegCodecContext {
|
|
|
155
168
|
sampleRate: this.sampleRate,
|
|
156
169
|
timeBase: this.timeBase,
|
|
157
170
|
channelLayout: this.channelLayout,
|
|
158
|
-
gopSize: this.gopSize
|
|
171
|
+
gopSize: this.gopSize,
|
|
172
|
+
extraData: this.extraData
|
|
159
173
|
}
|
|
160
174
|
}
|
|
161
175
|
}
|
package/lib/codec-parameters.js
CHANGED
|
@@ -72,6 +72,14 @@ module.exports = class FFmpegCodecParameters {
|
|
|
72
72
|
)
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
get frameSize() {
|
|
76
|
+
return binding.getCodecParametersFrameSize(this._handle)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
set frameSize(size) {
|
|
80
|
+
binding.setCodecParametersFrameSize(this._handle, size)
|
|
81
|
+
}
|
|
82
|
+
|
|
75
83
|
get videoDelay() {
|
|
76
84
|
return binding.getCodecParametersVideoDelay(this._handle)
|
|
77
85
|
}
|
package/lib/constants.js
CHANGED
|
@@ -133,6 +133,57 @@ module.exports = exports = {
|
|
|
133
133
|
NOFILE: binding.AVFMT_NOFILE,
|
|
134
134
|
NEEDNUMBER: binding.AVFMT_NEEDNUMBER,
|
|
135
135
|
NOTIMESTAMPS: binding.AVFMT_NOTIMESTAMPS
|
|
136
|
+
},
|
|
137
|
+
seek: {
|
|
138
|
+
SIZE: binding.AVSEEK_SIZE,
|
|
139
|
+
FORCE: binding.AVSEEK_FORCE,
|
|
140
|
+
CUR: binding.SEEK_CUR,
|
|
141
|
+
SET: binding.SEEK_SET,
|
|
142
|
+
END: binding.SEEK_END
|
|
143
|
+
},
|
|
144
|
+
packetSideDataType: {
|
|
145
|
+
PALETTE: binding.AV_PKT_DATA_PALETTE,
|
|
146
|
+
NEW_EXTRADATA: binding.AV_PKT_DATA_NEW_EXTRADATA,
|
|
147
|
+
PARAM_CHANGE: binding.AV_PKT_DATA_PARAM_CHANGE,
|
|
148
|
+
H263_MB_INFO: binding.AV_PKT_DATA_H263_MB_INFO,
|
|
149
|
+
REPLAYGAIN: binding.AV_PKT_DATA_REPLAYGAIN,
|
|
150
|
+
DISPLAYMATRIX: binding.AV_PKT_DATA_DISPLAYMATRIX,
|
|
151
|
+
STEREO3D: binding.AV_PKT_DATA_STEREO3D,
|
|
152
|
+
AUDIO_SERVICE_TYPE: binding.AV_PKT_DATA_AUDIO_SERVICE_TYPE,
|
|
153
|
+
QUALITY_STATS: binding.AV_PKT_DATA_QUALITY_STATS,
|
|
154
|
+
FALLBACK_TRACK: binding.AV_PKT_DATA_FALLBACK_TRACK,
|
|
155
|
+
CPB_PROPERTIES: binding.AV_PKT_DATA_CPB_PROPERTIES,
|
|
156
|
+
SKIP_SAMPLES: binding.AV_PKT_DATA_SKIP_SAMPLES,
|
|
157
|
+
JP_DUALMONO: binding.AV_PKT_DATA_JP_DUALMONO,
|
|
158
|
+
STRINGS_METADATA: binding.AV_PKT_DATA_STRINGS_METADATA,
|
|
159
|
+
SUBTITLE_POSITION: binding.AV_PKT_DATA_SUBTITLE_POSITION,
|
|
160
|
+
MATROSKA_BLOCKADDITIONAL: binding.AV_PKT_DATA_MATROSKA_BLOCKADDITIONAL,
|
|
161
|
+
WEBVTT_IDENTIFIER: binding.AV_PKT_DATA_WEBVTT_IDENTIFIER,
|
|
162
|
+
WEBVTT_SETTINGS: binding.AV_PKT_DATA_WEBVTT_SETTINGS,
|
|
163
|
+
METADATA_UPDATE: binding.AV_PKT_DATA_METADATA_UPDATE,
|
|
164
|
+
MPEGTS_STREAM_ID: binding.AV_PKT_DATA_MPEGTS_STREAM_ID,
|
|
165
|
+
MASTERING_DISPLAY_METADATA: binding.AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
|
|
166
|
+
SPHERICAL: binding.AV_PKT_DATA_SPHERICAL,
|
|
167
|
+
CONTENT_LIGHT_LEVEL: binding.AV_PKT_DATA_CONTENT_LIGHT_LEVEL,
|
|
168
|
+
A53_CC: binding.AV_PKT_DATA_A53_CC,
|
|
169
|
+
ENCRYPTION_INIT_INFO: binding.AV_PKT_DATA_ENCRYPTION_INIT_INFO,
|
|
170
|
+
ENCRYPTION_INFO: binding.AV_PKT_DATA_ENCRYPTION_INFO,
|
|
171
|
+
AFD: binding.AV_PKT_DATA_AFD,
|
|
172
|
+
PRFT: binding.AV_PKT_DATA_PRFT,
|
|
173
|
+
ICC_PROFILE: binding.AV_PKT_DATA_ICC_PROFILE,
|
|
174
|
+
DOVI_CONF: binding.AV_PKT_DATA_DOVI_CONF,
|
|
175
|
+
S12M_TIMECODE: binding.AV_PKT_DATA_S12M_TIMECODE,
|
|
176
|
+
DYNAMIC_HDR10_PLUS: binding.AV_PKT_DATA_DYNAMIC_HDR10_PLUS,
|
|
177
|
+
IAMF_MIX_GAIN_PARAM: binding.AV_PKT_DATA_IAMF_MIX_GAIN_PARAM,
|
|
178
|
+
IAMF_DEMIXING_INFO_PARAM: binding.AV_PKT_DATA_IAMF_DEMIXING_INFO_PARAM,
|
|
179
|
+
IAMF_RECON_GAIN_INFO_PARAM: binding.AV_PKT_DATA_IAMF_RECON_GAIN_INFO_PARAM,
|
|
180
|
+
AMBIENT_VIEWING_ENVIRONMENT:
|
|
181
|
+
binding.AV_PKT_DATA_AMBIENT_VIEWING_ENVIRONMENT,
|
|
182
|
+
FRAME_CROPPING: binding.AV_PKT_DATA_FRAME_CROPPING,
|
|
183
|
+
LCEVC: binding.AV_PKT_DATA_LCEVC,
|
|
184
|
+
'3D_REFERENCE_DISPLAYS': binding.AV_PKT_DATA_3D_REFERENCE_DISPLAYS,
|
|
185
|
+
RTCP_SR: binding.AV_PKT_DATA_RTCP_SR,
|
|
186
|
+
NB: binding.AV_PKT_DATA_NB
|
|
136
187
|
}
|
|
137
188
|
}
|
|
138
189
|
|
|
@@ -183,3 +234,7 @@ exports.toChannelLayout = function toChannelLayout(layout) {
|
|
|
183
234
|
`Channel layout must be a number or string. Received ${typeof layout} (${layout})`
|
|
184
235
|
)
|
|
185
236
|
}
|
|
237
|
+
|
|
238
|
+
exports.getSampleFormatName = function (sampleFormat) {
|
|
239
|
+
return binding.getSampleFormatNameByID(sampleFormat)
|
|
240
|
+
}
|
package/lib/packet.js
CHANGED
|
@@ -1,6 +1,42 @@
|
|
|
1
1
|
const binding = require('../binding')
|
|
2
2
|
const Rational = require('./rational')
|
|
3
3
|
|
|
4
|
+
class SideData {
|
|
5
|
+
constructor(handle, opts = {}) {
|
|
6
|
+
this._handle = handle
|
|
7
|
+
this._type = opts.type || null
|
|
8
|
+
this._data = opts.data || null
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
static fromData(data, type) {
|
|
12
|
+
return new SideData(null, { data, type })
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
get type() {
|
|
16
|
+
if (this._type) return this._type
|
|
17
|
+
return binding.getSideDataType(this._handle)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
get name() {
|
|
21
|
+
if (!this._handle) return null
|
|
22
|
+
return binding.getSideDataName(this._handle)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
get data() {
|
|
26
|
+
if (this._data) return this._data
|
|
27
|
+
return Buffer.from(binding.getSideDataBuffer(this._handle))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
[Symbol.for('bare.inspect')]() {
|
|
31
|
+
return {
|
|
32
|
+
__proto__: { constructor: SideData },
|
|
33
|
+
type: this.type,
|
|
34
|
+
name: this.name,
|
|
35
|
+
data: this.data
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
4
40
|
module.exports = class FFmpegPacket {
|
|
5
41
|
constructor(buffer) {
|
|
6
42
|
if (buffer) {
|
|
@@ -44,10 +80,31 @@ module.exports = class FFmpegPacket {
|
|
|
44
80
|
)
|
|
45
81
|
}
|
|
46
82
|
|
|
83
|
+
get sideData() {
|
|
84
|
+
const handles = binding.getPacketSideData(this._handle)
|
|
85
|
+
return handles.map((handle) => new SideData(handle))
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
set sideData(values) {
|
|
89
|
+
binding.setPacketSideData(
|
|
90
|
+
this._handle,
|
|
91
|
+
values.map((value) => ({
|
|
92
|
+
buffer: value.data.buffer,
|
|
93
|
+
offset: value.data.byteOffset,
|
|
94
|
+
length: value.data.byteLength,
|
|
95
|
+
type: value.type
|
|
96
|
+
}))
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
47
100
|
get isKeyframe() {
|
|
48
101
|
return binding.isPacketKeyframe(this._handle)
|
|
49
102
|
}
|
|
50
103
|
|
|
104
|
+
set isKeyframe(value) {
|
|
105
|
+
binding.setPacketIsKeyFrame(this._handle, value)
|
|
106
|
+
}
|
|
107
|
+
|
|
51
108
|
get dts() {
|
|
52
109
|
return binding.getPacketDTS(this._handle)
|
|
53
110
|
}
|
|
@@ -115,3 +172,5 @@ module.exports = class FFmpegPacket {
|
|
|
115
172
|
this.destroy()
|
|
116
173
|
}
|
|
117
174
|
}
|
|
175
|
+
|
|
176
|
+
module.exports.SideData = SideData
|
package/package.json
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|