bare-ffmpeg 1.0.0-24 → 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 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
- Example:
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
@@ -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, std::string>;
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;
@@ -145,7 +145,8 @@ bare_ffmpeg__on_io_context_write(void *opaque, const uint8_t *buf, int len) {
145
145
  assert(err == 0);
146
146
 
147
147
  err = js_call_function(env, callback, data);
148
- assert(err == 0);
148
+
149
+ if (err < 0) return AVERROR(EIO);
149
150
 
150
151
  return 0;
151
152
  }
@@ -181,39 +182,21 @@ bare_ffmpeg__on_io_context_read(void *opaque, uint8_t *buf, int len) {
181
182
 
182
183
  static int64_t
183
184
  bare_ffmpeg__on_io_context_seek(void *opaque, int64_t offset, int whence) {
184
- int err;
185
-
186
185
  auto context = reinterpret_cast<bare_ffmpeg_io_context_t *>(opaque);
187
-
188
186
  auto env = context->env;
189
187
 
190
188
  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
189
  bare_ffmpeg_io_context_seek_cb_t callback;
213
- err = js_get_reference_value(env, context->on_seek, callback);
190
+ int err = js_get_reference_value(env, context->on_seek, callback);
214
191
  assert(err == 0);
215
192
 
216
- err = js_call_function<js_type_options_t{}, int64_t, int64_t, std::string>(env, callback, offset, whence_str, result);
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
+ );
217
200
  if (err < 0) return AVERROR(EIO); // read-error
218
201
 
219
202
  if (result == -1) {
@@ -391,6 +374,12 @@ bare_ffmpeg_format_context_open_input_with_io(
391
374
  if (err < 0) {
392
375
  avformat_free_context(context->handle);
393
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
+
394
383
  err = js_throw_error(env, NULL, av_err2str(err));
395
384
  assert(err == 0);
396
385
 
@@ -3421,6 +3410,13 @@ bare_ffmpeg_exports(js_env_t *env, js_value_t *exports) {
3421
3410
 
3422
3411
  // Levels
3423
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)
3424
3420
  #undef V
3425
3421
 
3426
3422
  return exports;
@@ -332,7 +332,7 @@ list(APPEND env
332
332
  )
333
333
 
334
334
  declare_port(
335
- "github:FFmpeg/FFmpeg#n7.1.1"
335
+ "github:FFmpeg/FFmpeg#n8.0"
336
336
  ffmpeg
337
337
  AUTOTOOLS
338
338
  DEPENDS ${depends}
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bare-ffmpeg",
3
- "version": "1.0.0-24",
3
+ "version": "1.0.0-25",
4
4
  "description": "Low-level FFmpeg bindings for Bare",
5
5
  "exports": {
6
6
  ".": "./index.js",