bare-ffmpeg 1.0.0-23 → 1.0.0-25
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 +81 -4
- package/binding.cc +27 -40
- package/cmake/ports/ffmpeg/port.cmake +1 -1
- package/lib/constants.js +7 -0
- package/lib/io-context.js +10 -2
- 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()`
|
package/binding.cc
CHANGED
|
@@ -33,9 +33,9 @@ extern "C" {
|
|
|
33
33
|
#include <libswscale/swscale.h>
|
|
34
34
|
}
|
|
35
35
|
|
|
36
|
-
using bare_ffmpeg_io_context_write_cb_t = js_function_t<void,
|
|
37
|
-
using bare_ffmpeg_io_context_read_cb_t = js_function_t<int32_t,
|
|
38
|
-
using bare_ffmpeg_io_context_seek_cb_t = js_function_t<int64_t, int64_t,
|
|
36
|
+
using bare_ffmpeg_io_context_write_cb_t = js_function_t<void, js_arraybuffer_t>;
|
|
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, int>;
|
|
39
39
|
|
|
40
40
|
typedef struct {
|
|
41
41
|
AVIOContext *handle;
|
|
@@ -144,13 +144,9 @@ bare_ffmpeg__on_io_context_write(void *opaque, const uint8_t *buf, int len) {
|
|
|
144
144
|
err = js_create_arraybuffer(env, buf, static_cast<size_t>(len), data);
|
|
145
145
|
assert(err == 0);
|
|
146
146
|
|
|
147
|
-
|
|
148
|
-
err = js_create_typedarray(env, static_cast<size_t>(len), data, view);
|
|
149
|
-
assert(err == 0);
|
|
150
|
-
|
|
147
|
+
err = js_call_function(env, callback, data);
|
|
151
148
|
|
|
152
|
-
err
|
|
153
|
-
assert(err == 0);
|
|
149
|
+
if (err < 0) return AVERROR(EIO);
|
|
154
150
|
|
|
155
151
|
return 0;
|
|
156
152
|
}
|
|
@@ -171,12 +167,8 @@ bare_ffmpeg__on_io_context_read(void *opaque, uint8_t *buf, int len) {
|
|
|
171
167
|
err = js_create_external_arraybuffer(env, buf, static_cast<size_t>(len), arraybuffer);
|
|
172
168
|
assert(err == 0);
|
|
173
169
|
|
|
174
|
-
js_typedarray_t<uint8_t> view;
|
|
175
|
-
err = js_create_typedarray(env, static_cast<size_t>(len), arraybuffer, view);
|
|
176
|
-
assert(err == 0);
|
|
177
|
-
|
|
178
170
|
int32_t result;
|
|
179
|
-
int call_status = js_call_function<js_type_options_t{}, int32_t,
|
|
171
|
+
int call_status = js_call_function<js_type_options_t{}, int32_t, js_arraybuffer_t, int32_t>(env, callback, arraybuffer, len, result);
|
|
180
172
|
|
|
181
173
|
err = js_detach_arraybuffer(env, arraybuffer);
|
|
182
174
|
assert(err == 0);
|
|
@@ -190,39 +182,21 @@ bare_ffmpeg__on_io_context_read(void *opaque, uint8_t *buf, int len) {
|
|
|
190
182
|
|
|
191
183
|
static int64_t
|
|
192
184
|
bare_ffmpeg__on_io_context_seek(void *opaque, int64_t offset, int whence) {
|
|
193
|
-
int err;
|
|
194
|
-
|
|
195
185
|
auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
|
|
196
|
-
|
|
197
186
|
auto env = context->env;
|
|
198
187
|
|
|
199
188
|
int64_t result;
|
|
200
|
-
std::string whence_str;
|
|
201
|
-
switch (whence) {
|
|
202
|
-
case AVSEEK_SIZE:
|
|
203
|
-
whence_str = "avseek_size";
|
|
204
|
-
break;
|
|
205
|
-
case AVSEEK_FORCE:
|
|
206
|
-
whence_str = "avseek_force";
|
|
207
|
-
break;
|
|
208
|
-
case SEEK_SET:
|
|
209
|
-
whence_str = "seek_set";
|
|
210
|
-
break;
|
|
211
|
-
case SEEK_CUR:
|
|
212
|
-
whence_str = "seek_cur";
|
|
213
|
-
break;
|
|
214
|
-
case SEEK_END:
|
|
215
|
-
whence_str = "seek_end";
|
|
216
|
-
break;
|
|
217
|
-
default:
|
|
218
|
-
whence_str = "unknown:" + std::to_string(whence);
|
|
219
|
-
}
|
|
220
|
-
|
|
221
189
|
bare_ffmpeg_io_context_seek_cb_t callback;
|
|
222
|
-
err = js_get_reference_value(env, context->on_seek, callback);
|
|
190
|
+
int err = js_get_reference_value(env, context->on_seek, callback);
|
|
223
191
|
assert(err == 0);
|
|
224
192
|
|
|
225
|
-
err = js_call_function<
|
|
193
|
+
err = js_call_function<
|
|
194
|
+
js_type_options_t{},
|
|
195
|
+
int64_t,
|
|
196
|
+
int64_t,
|
|
197
|
+
int>(
|
|
198
|
+
env, callback, offset, whence, result
|
|
199
|
+
);
|
|
226
200
|
if (err < 0) return AVERROR(EIO); // read-error
|
|
227
201
|
|
|
228
202
|
if (result == -1) {
|
|
@@ -400,6 +374,12 @@ bare_ffmpeg_format_context_open_input_with_io(
|
|
|
400
374
|
if (err < 0) {
|
|
401
375
|
avformat_free_context(context->handle);
|
|
402
376
|
|
|
377
|
+
bool is_exception_pending;
|
|
378
|
+
err = js_is_exception_pending(env, &is_exception_pending);
|
|
379
|
+
assert(err == 0);
|
|
380
|
+
|
|
381
|
+
if (is_exception_pending) throw js_pending_exception;
|
|
382
|
+
|
|
403
383
|
err = js_throw_error(env, NULL, av_err2str(err));
|
|
404
384
|
assert(err == 0);
|
|
405
385
|
|
|
@@ -3430,6 +3410,13 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
|
|
|
3430
3410
|
|
|
3431
3411
|
// Levels
|
|
3432
3412
|
V(AV_LEVEL_UNKNOWN)
|
|
3413
|
+
|
|
3414
|
+
// SEEK
|
|
3415
|
+
V(AVSEEK_SIZE)
|
|
3416
|
+
V(AVSEEK_FORCE)
|
|
3417
|
+
V(SEEK_CUR)
|
|
3418
|
+
V(SEEK_SET)
|
|
3419
|
+
V(SEEK_END)
|
|
3433
3420
|
#undef V
|
|
3434
3421
|
|
|
3435
3422
|
return exports;
|
package/lib/constants.js
CHANGED
|
@@ -133,6 +133,13 @@ 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
|
|
136
143
|
}
|
|
137
144
|
}
|
|
138
145
|
|
package/lib/io-context.js
CHANGED
|
@@ -20,8 +20,8 @@ module.exports = class FFmpegIOContext {
|
|
|
20
20
|
buffer,
|
|
21
21
|
offset,
|
|
22
22
|
len,
|
|
23
|
-
opts.onwrite,
|
|
24
|
-
opts.onread,
|
|
23
|
+
opts.onwrite && onwriteWrapper.bind(null, opts.onwrite),
|
|
24
|
+
opts.onread && onreadWrapper.bind(null, opts.onread),
|
|
25
25
|
opts.onseek
|
|
26
26
|
)
|
|
27
27
|
}
|
|
@@ -35,3 +35,11 @@ module.exports = class FFmpegIOContext {
|
|
|
35
35
|
this.destroy()
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
|
+
|
|
39
|
+
function onwriteWrapper(target, arraybuffer) {
|
|
40
|
+
return target(Buffer.from(arraybuffer))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function onreadWrapper(target, arraybuffer, requestedLen) {
|
|
44
|
+
return target(Buffer.from(arraybuffer), requestedLen)
|
|
45
|
+
}
|
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
|