node-av 1.3.0 → 2.1.0

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 (127) hide show
  1. package/README.md +47 -40
  2. package/binding.gyp +12 -0
  3. package/dist/api/bitstream-filter.d.ts +134 -2
  4. package/dist/api/bitstream-filter.js +200 -2
  5. package/dist/api/bitstream-filter.js.map +1 -1
  6. package/dist/api/decoder.d.ts +261 -105
  7. package/dist/api/decoder.js +384 -171
  8. package/dist/api/decoder.js.map +1 -1
  9. package/dist/api/encoder.d.ts +338 -74
  10. package/dist/api/encoder.js +546 -188
  11. package/dist/api/encoder.js.map +1 -1
  12. package/dist/api/filter-presets.d.ts +479 -1513
  13. package/dist/api/filter-presets.js +1044 -2005
  14. package/dist/api/filter-presets.js.map +1 -1
  15. package/dist/api/filter.d.ts +370 -150
  16. package/dist/api/filter.js +647 -364
  17. package/dist/api/filter.js.map +1 -1
  18. package/dist/api/hardware.d.ts +25 -31
  19. package/dist/api/hardware.js +36 -70
  20. package/dist/api/hardware.js.map +1 -1
  21. package/dist/api/index.d.ts +1 -1
  22. package/dist/api/index.js +1 -1
  23. package/dist/api/index.js.map +1 -1
  24. package/dist/api/io-stream.d.ts +6 -0
  25. package/dist/api/io-stream.js +2 -0
  26. package/dist/api/io-stream.js.map +1 -1
  27. package/dist/api/media-input.d.ts +208 -2
  28. package/dist/api/media-input.js +356 -8
  29. package/dist/api/media-input.js.map +1 -1
  30. package/dist/api/media-output.d.ts +142 -104
  31. package/dist/api/media-output.js +446 -179
  32. package/dist/api/media-output.js.map +1 -1
  33. package/dist/api/pipeline.d.ts +82 -17
  34. package/dist/api/pipeline.js +80 -42
  35. package/dist/api/pipeline.js.map +1 -1
  36. package/dist/api/types.d.ts +24 -57
  37. package/dist/api/utils.js +2 -0
  38. package/dist/api/utils.js.map +1 -1
  39. package/dist/lib/audio-fifo.d.ts +103 -0
  40. package/dist/lib/audio-fifo.js +109 -0
  41. package/dist/lib/audio-fifo.js.map +1 -1
  42. package/dist/lib/binding.d.ts +1 -0
  43. package/dist/lib/binding.js.map +1 -1
  44. package/dist/lib/bitstream-filter-context.d.ts +79 -0
  45. package/dist/lib/bitstream-filter-context.js +83 -0
  46. package/dist/lib/bitstream-filter-context.js.map +1 -1
  47. package/dist/lib/bitstream-filter.d.ts +2 -0
  48. package/dist/lib/bitstream-filter.js +2 -0
  49. package/dist/lib/bitstream-filter.js.map +1 -1
  50. package/dist/lib/codec-context.d.ts +168 -0
  51. package/dist/lib/codec-context.js +178 -0
  52. package/dist/lib/codec-context.js.map +1 -1
  53. package/dist/lib/codec-parameters.d.ts +3 -0
  54. package/dist/lib/codec-parameters.js +3 -0
  55. package/dist/lib/codec-parameters.js.map +1 -1
  56. package/dist/lib/codec-parser.d.ts +6 -0
  57. package/dist/lib/codec-parser.js +6 -0
  58. package/dist/lib/codec-parser.js.map +1 -1
  59. package/dist/lib/codec.d.ts +12 -0
  60. package/dist/lib/codec.js +12 -0
  61. package/dist/lib/codec.js.map +1 -1
  62. package/dist/lib/dictionary.d.ts +18 -2
  63. package/dist/lib/dictionary.js +18 -2
  64. package/dist/lib/dictionary.js.map +1 -1
  65. package/dist/lib/error.d.ts +8 -0
  66. package/dist/lib/error.js +9 -0
  67. package/dist/lib/error.js.map +1 -1
  68. package/dist/lib/filter-context.d.ts +119 -2
  69. package/dist/lib/filter-context.js +119 -0
  70. package/dist/lib/filter-context.js.map +1 -1
  71. package/dist/lib/filter-graph.d.ts +80 -0
  72. package/dist/lib/filter-graph.js +84 -0
  73. package/dist/lib/filter-graph.js.map +1 -1
  74. package/dist/lib/filter-inout.d.ts +1 -0
  75. package/dist/lib/filter-inout.js +1 -0
  76. package/dist/lib/filter-inout.js.map +1 -1
  77. package/dist/lib/filter.d.ts +2 -0
  78. package/dist/lib/filter.js +2 -0
  79. package/dist/lib/filter.js.map +1 -1
  80. package/dist/lib/format-context.d.ts +356 -20
  81. package/dist/lib/format-context.js +375 -23
  82. package/dist/lib/format-context.js.map +1 -1
  83. package/dist/lib/frame.d.ts +84 -1
  84. package/dist/lib/frame.js +96 -0
  85. package/dist/lib/frame.js.map +1 -1
  86. package/dist/lib/hardware-device-context.d.ts +8 -0
  87. package/dist/lib/hardware-device-context.js +8 -0
  88. package/dist/lib/hardware-device-context.js.map +1 -1
  89. package/dist/lib/hardware-frames-context.d.ts +55 -0
  90. package/dist/lib/hardware-frames-context.js +57 -0
  91. package/dist/lib/hardware-frames-context.js.map +1 -1
  92. package/dist/lib/input-format.d.ts +43 -3
  93. package/dist/lib/input-format.js +48 -0
  94. package/dist/lib/input-format.js.map +1 -1
  95. package/dist/lib/io-context.d.ts +212 -0
  96. package/dist/lib/io-context.js +228 -0
  97. package/dist/lib/io-context.js.map +1 -1
  98. package/dist/lib/log.d.ts +2 -0
  99. package/dist/lib/log.js +2 -0
  100. package/dist/lib/log.js.map +1 -1
  101. package/dist/lib/native-types.d.ts +39 -1
  102. package/dist/lib/option.d.ts +90 -0
  103. package/dist/lib/option.js +97 -0
  104. package/dist/lib/option.js.map +1 -1
  105. package/dist/lib/output-format.d.ts +4 -0
  106. package/dist/lib/output-format.js +4 -0
  107. package/dist/lib/output-format.js.map +1 -1
  108. package/dist/lib/packet.d.ts +7 -0
  109. package/dist/lib/packet.js +7 -0
  110. package/dist/lib/packet.js.map +1 -1
  111. package/dist/lib/rational.d.ts +1 -0
  112. package/dist/lib/rational.js +1 -0
  113. package/dist/lib/rational.js.map +1 -1
  114. package/dist/lib/software-resample-context.d.ts +64 -0
  115. package/dist/lib/software-resample-context.js +66 -0
  116. package/dist/lib/software-resample-context.js.map +1 -1
  117. package/dist/lib/software-scale-context.d.ts +98 -0
  118. package/dist/lib/software-scale-context.js +102 -0
  119. package/dist/lib/software-scale-context.js.map +1 -1
  120. package/dist/lib/stream.d.ts +1 -0
  121. package/dist/lib/stream.js +1 -0
  122. package/dist/lib/stream.js.map +1 -1
  123. package/dist/lib/utilities.d.ts +60 -0
  124. package/dist/lib/utilities.js +60 -0
  125. package/dist/lib/utilities.js.map +1 -1
  126. package/package.json +18 -18
  127. package/release_notes.md +0 -29
package/README.md CHANGED
@@ -34,46 +34,45 @@ await using input = await MediaInput.open('input.mp4');
34
34
  await using output = await MediaOutput.open('output.mp4');
35
35
 
36
36
  // Get video stream
37
- const videoStream = input.video();
37
+ const videoStream = input.video()!;
38
38
 
39
- // Create decoder/encoder
40
- using decoder = await Decoder.create(videoStream!);
41
- using encoder = await Encoder.create(FF_ENCODER_LIBX264, decoder.getOutputStreamInfo(), {
42
- bitrate: '2M',
43
- gopSize: 60,
39
+ // Create decoder
40
+ using decoder = await Decoder.create(videoStream);
41
+
42
+ // Create encoder
43
+ using encoder = await Encoder.create(FF_ENCODER_LIBX264, {
44
+ timeBase: videoStream.timeBase,
45
+ frameRate: videoStream.avgFrameRate,
44
46
  });
45
47
 
46
48
  // Add stream to output
47
49
  const outputIndex = output.addStream(encoder);
48
- await output.writeHeader();
49
50
 
50
51
  // Process packets
51
- for await (const packet of input.packets()) {
52
- if (packet.streamIndex === videoStream!.index) {
53
- using frame = await decoder.decode(packet);
54
- if (frame) {
55
- using encoded = await encoder.encode(frame);
56
- if (encoded) {
57
- await output.writePacket(encoded, outputIndex);
58
- }
52
+ for await (using packet of input.packets(videoStream.index)) {
53
+ using frame = await decoder.decode(packet);
54
+ if (frame) {
55
+ using encoded = await encoder.encode(frame);
56
+ if (encoded) {
57
+ await output.writePacket(encoded, outputIndex);
59
58
  }
60
59
  }
61
60
  }
62
61
 
63
- // Flush decoder/encoder
64
- for await (const frame of decoder.flushFrames()) {
62
+ // Flush decoder
63
+ for await (using frame of decoder.flushFrames()) {
65
64
  using encoded = await encoder.encode(frame);
66
65
  if (encoded) {
67
66
  await output.writePacket(encoded, outputIndex);
68
67
  }
69
68
  }
70
69
 
71
- for await (const packet of encoder.flushPackets()) {
70
+ // Flush encoder
71
+ for await (using packet of encoder.flushPackets()) {
72
72
  await output.writePacket(packet, outputIndex);
73
73
  }
74
74
 
75
- // End
76
- await output.writeTrailer();
75
+ // Done
77
76
  ```
78
77
 
79
78
  ### Pipeline API
@@ -85,9 +84,9 @@ import { pipeline, MediaInput, MediaOutput, Decoder, Encoder } from 'node-av/api
85
84
  const input = await MediaInput.open('input.mp4');
86
85
  const output = await MediaOutput.open('output.mp4');
87
86
  const decoder = await Decoder.create(input.video());
88
- const encoder = await Encoder.create(FF_ENCODER_LIBX264, decoder.getOutputStreamInfo(), {
89
- bitrate: '2M',
90
- gopSize: 60
87
+ const encoder = await Encoder.create(FF_ENCODER_LIBX264, {
88
+ timeBase: videoStream.timeBase,
89
+ frameRate: videoStream.avgFrameRate,
91
90
  });
92
91
 
93
92
  const control = pipeline(input, decoder, encoder, output);
@@ -102,23 +101,23 @@ The library supports all hardware acceleration methods available in FFmpeg. The
102
101
 
103
102
  ```typescript
104
103
  import { HardwareContext } from 'node-av/api';
105
- import { FF_ENCODER_H264_VIDEOTOOLBOX } from 'node-av/constants';
104
+ import { FF_ENCODER_LIBX264 } from 'node-av/constants';
106
105
 
107
106
  // Automatically detect best available hardware
108
107
  const hw = HardwareContext.auto();
109
- if (hw) {
110
- console.log(`Using hardware: ${hw.deviceTypeName}`);
111
-
112
- // Use with decoder
113
- const decoder = await Decoder.create(stream, {
114
- hardware: hw
115
- });
116
-
117
- // Use with encoder (use hardware-specific codec)
118
- const encoder = await Encoder.create(FF_ENCODER_H264_VIDEOTOOLBOX, decoder.getOutputStreamInfo(), {
119
- hardware: hw
120
- });
121
- }
108
+ console.log(`Using hardware: ${hw.deviceTypeName}`);
109
+
110
+ // Use with decoder
111
+ const decoder = await Decoder.create(stream, {
112
+ hardware: hw
113
+ });
114
+
115
+ // Use with encoder (use hardware-specific codec)
116
+ const encoderCodec = hw?.getEncoderCodec('h264') ?? FF_ENCODER_LIBX264;
117
+ const encoder = await Encoder.create(encoderCodec, {
118
+ timeBase: videoStream.timeBase,
119
+ frameRate: videoStream.avgFrameRate,
120
+ });
122
121
  ```
123
122
 
124
123
  ### Specific Hardware
@@ -223,9 +222,17 @@ try {
223
222
 
224
223
  ## Performance
225
224
 
226
- NodeAV executes all media operations directly through FFmpeg's native C libraries. The Node.js bindings add minimal overhead - mostly just the JavaScript-to-C boundary crossings. During typical operations like transcoding or filtering, most processing time is spent in FFmpeg's optimized C code. You get full access to hardware acceleration, SIMD optimizations, and multi-threading capabilities.
225
+ NodeAV executes all media operations directly through FFmpeg's native C libraries. The Node.js bindings add minimal overhead - mostly just the JavaScript-to-C boundary crossings. During typical operations like transcoding or filtering, most processing time is spent in FFmpeg's optimized C code.
226
+
227
+ ### Sync vs Async Operations
228
+
229
+ Every async method in NodeAV has a corresponding synchronous variant with the `Sync` suffix:
230
+
231
+ - **Async methods** (default) - Non-blocking operations using N-API's AsyncWorker. Methods like `decode()`, `encode()`, `read()`, `packets()` return Promises or AsyncGenerators.
232
+
233
+ - **Sync methods** - Direct FFmpeg calls without AsyncWorker overhead. Same methods with `Sync` suffix: `decodeSync()`, `encodeSync()`, `readSync()`, `packetsSync()`.
227
234
 
228
- Heavy and I/O operations are executed asynchronously using N-API's AsyncWorker, preventing FFmpeg calls from blocking the Node.js event loop.
235
+ The key difference: Async methods don't block the Node.js event loop, allowing other operations to run concurrently. Sync methods block until completion but avoid AsyncWorker overhead, making them faster for sequential processing.
229
236
 
230
237
  ## Memory Safety Considerations
231
238
 
@@ -288,7 +295,7 @@ This project is licensed under the MIT License. See the LICENSE file for details
288
295
 
289
296
  ## Contributing
290
297
 
291
- Contributions are welcome! Please read [CONTRIBUTION.md](https://github.com/seydx/av/tree/main/CONTRIBUTION.md) for development setup, code standards, and contribution guidelines before submitting pull requests.
298
+ Contributions are welcome! Please read [CONTRIBUTING.md](https://github.com/seydx/av/tree/main/CONTRIBUTING.md) for development setup, code standards, and contribution guidelines before submitting pull requests.
292
299
 
293
300
  ## Support
294
301
 
package/binding.gyp CHANGED
@@ -7,41 +7,53 @@
7
7
  "src/bindings/packet.cc",
8
8
  "src/bindings/frame.cc",
9
9
  "src/bindings/frame_async.cc",
10
+ "src/bindings/frame_sync.cc",
10
11
  "src/bindings/codec.cc",
11
12
  "src/bindings/codec_context.cc",
12
13
  "src/bindings/codec_context_async.cc",
14
+ "src/bindings/codec_context_sync.cc",
13
15
  "src/bindings/codec_parameters.cc",
14
16
  "src/bindings/codec_parser.cc",
15
17
  "src/bindings/format_context.cc",
16
18
  "src/bindings/format_context_async.cc",
19
+ "src/bindings/format_context_sync.cc",
17
20
  "src/bindings/stream.cc",
18
21
  "src/bindings/dictionary.cc",
19
22
  "src/bindings/input_format.cc",
20
23
  "src/bindings/input_format_async.cc",
24
+ "src/bindings/input_format_sync.cc",
21
25
  "src/bindings/output_format.cc",
22
26
  "src/bindings/io_context.cc",
23
27
  "src/bindings/io_context_async.cc",
28
+ "src/bindings/io_context_sync.cc",
24
29
  "src/bindings/error.cc",
25
30
  "src/bindings/software_scale_context.cc",
26
31
  "src/bindings/software_scale_context_async.cc",
32
+ "src/bindings/software_scale_context_sync.cc",
27
33
  "src/bindings/software_resample_context.cc",
28
34
  "src/bindings/software_resample_context_async.cc",
35
+ "src/bindings/software_resample_context_sync.cc",
29
36
  "src/bindings/filter.cc",
30
37
  "src/bindings/filter_context.cc",
31
38
  "src/bindings/filter_context_async.cc",
39
+ "src/bindings/filter_context_sync.cc",
32
40
  "src/bindings/filter_graph.cc",
33
41
  "src/bindings/filter_graph_async.cc",
42
+ "src/bindings/filter_graph_sync.cc",
34
43
  "src/bindings/filter_inout.cc",
35
44
  "src/bindings/hardware_device_context.cc",
36
45
  "src/bindings/hardware_frames_context.cc",
37
46
  "src/bindings/hardware_frames_context_async.cc",
47
+ "src/bindings/hardware_frames_context_sync.cc",
38
48
  "src/bindings/log.cc",
39
49
  "src/bindings/utilities.cc",
40
50
  "src/bindings/audio_fifo.cc",
41
51
  "src/bindings/audio_fifo_async.cc",
52
+ "src/bindings/audio_fifo_sync.cc",
42
53
  "src/bindings/bitstream_filter.cc",
43
54
  "src/bindings/bitstream_filter_context.cc",
44
55
  "src/bindings/bitstream_filter_context_async.cc",
56
+ "src/bindings/bitstream_filter_context_sync.cc",
45
57
  "src/bindings/option.cc"
46
58
  ],
47
59
  "include_dirs": [
@@ -45,8 +45,11 @@ export declare class BitStreamFilterAPI implements Disposable {
45
45
  private isDisposed;
46
46
  /**
47
47
  * @param filter - Bitstream filter instance
48
+ *
48
49
  * @param ctx - Filter context
50
+ *
49
51
  * @param stream - Associated stream
52
+ *
50
53
  * @internal
51
54
  */
52
55
  private constructor();
@@ -59,7 +62,9 @@ export declare class BitStreamFilterAPI implements Disposable {
59
62
  * Direct mapping to av_bsf_get_by_name() and av_bsf_alloc().
60
63
  *
61
64
  * @param filterName - Name of the bitstream filter
65
+ *
62
66
  * @param stream - Stream to apply filter to
67
+ *
63
68
  * @returns Configured bitstream filter
64
69
  *
65
70
  * @throws {Error} If filter not found or initialization fails
@@ -131,6 +136,7 @@ export declare class BitStreamFilterAPI implements Disposable {
131
136
  * Direct mapping to av_bsf_send_packet() and av_bsf_receive_packet().
132
137
  *
133
138
  * @param packet - Packet to filter or null for EOF
139
+ *
134
140
  * @returns Array of filtered packets
135
141
  *
136
142
  * @throws {Error} If filter is disposed
@@ -156,6 +162,42 @@ export declare class BitStreamFilterAPI implements Disposable {
156
162
  * @see {@link packets} For stream processing
157
163
  */
158
164
  process(packet: Packet | null): Promise<Packet[]>;
165
+ /**
166
+ * Process a packet through the filter synchronously.
167
+ * Synchronous version of process.
168
+ *
169
+ * Applies bitstream filter to packet.
170
+ * May produce zero, one, or multiple output packets.
171
+ * Pass null to signal end-of-stream.
172
+ *
173
+ * Direct mapping to av_bsf_send_packet() and av_bsf_receive_packet().
174
+ *
175
+ * @param packet - Packet to filter or null for EOF
176
+ *
177
+ * @returns Array of filtered packets
178
+ *
179
+ * @throws {Error} If filter is disposed
180
+ *
181
+ * @throws {FFmpegError} If filtering fails
182
+ *
183
+ * @example
184
+ * ```typescript
185
+ * const outputPackets = filter.processSync(inputPacket);
186
+ * for (const packet of outputPackets) {
187
+ * console.log(`Filtered packet: pts=${packet.pts}`);
188
+ * packet.free();
189
+ * }
190
+ * ```
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * // Flush filter
195
+ * const remaining = filter.processSync(null);
196
+ * ```
197
+ *
198
+ * @see {@link process} For async version
199
+ */
200
+ processSync(packet: Packet | null): Packet[];
159
201
  /**
160
202
  * Process packet stream through filter.
161
203
  *
@@ -164,7 +206,9 @@ export declare class BitStreamFilterAPI implements Disposable {
164
206
  * Yields filtered packets ready for output.
165
207
  *
166
208
  * @param packets - Async iterable of packets
167
- * @yields Filtered packets
209
+ *
210
+ * @yields {Packet} Filtered packets
211
+ *
168
212
  * @throws {Error} If filter is disposed
169
213
  *
170
214
  * @throws {FFmpegError} If filtering fails
@@ -194,6 +238,46 @@ export declare class BitStreamFilterAPI implements Disposable {
194
238
  * @see {@link flush} For end-of-stream handling
195
239
  */
196
240
  packets(packets: AsyncIterable<Packet>): AsyncGenerator<Packet>;
241
+ /**
242
+ * Process packet stream through filter synchronously.
243
+ * Synchronous version of packets.
244
+ *
245
+ * High-level sync generator for filtering packet streams.
246
+ * Automatically handles flushing at end of stream.
247
+ * Yields filtered packets ready for output.
248
+ *
249
+ * @param packets - Iterable of packets
250
+ *
251
+ * @yields {Packet} Filtered packets
252
+ *
253
+ * @throws {Error} If filter is disposed
254
+ *
255
+ * @throws {FFmpegError} If filtering fails
256
+ *
257
+ * @example
258
+ * ```typescript
259
+ * // Filter entire stream
260
+ * for (const packet of filter.packetsSync(packets)) {
261
+ * output.writePacketSync(packet);
262
+ * packet.free();
263
+ * }
264
+ * ```
265
+ *
266
+ * @example
267
+ * ```typescript
268
+ * // Chain with decoder
269
+ * const decoder = await Decoder.create(stream);
270
+ * const filter = BitStreamFilterAPI.create('h264_mp4toannexb', stream);
271
+ *
272
+ * for (const frame of decoder.framesSync(filter.packetsSync(packets))) {
273
+ * // Process frames
274
+ * frame.free();
275
+ * }
276
+ * ```
277
+ *
278
+ * @see {@link packets} For async version
279
+ */
280
+ packetsSync(packets: Iterable<Packet>): Generator<Packet>;
197
281
  /**
198
282
  * Flush filter and get remaining packets.
199
283
  *
@@ -219,13 +303,39 @@ export declare class BitStreamFilterAPI implements Disposable {
219
303
  * @see {@link reset} For state reset only
220
304
  */
221
305
  flush(): Promise<Packet[]>;
306
+ /**
307
+ * Flush filter and get remaining packets synchronously.
308
+ * Synchronous version of flush.
309
+ *
310
+ * Signals end-of-stream and retrieves buffered packets.
311
+ * Also resets internal filter state.
312
+ *
313
+ * Direct mapping to av_bsf_flush().
314
+ *
315
+ * @returns Array of remaining packets
316
+ *
317
+ * @throws {Error} If filter is disposed
318
+ *
319
+ * @example
320
+ * ```typescript
321
+ * const remaining = filter.flushSync();
322
+ * for (const packet of remaining) {
323
+ * output.writePacketSync(packet);
324
+ * packet.free();
325
+ * }
326
+ * ```
327
+ *
328
+ * @see {@link flush} For async version
329
+ */
330
+ flushSync(): Packet[];
222
331
  /**
223
332
  * Flush filter as async generator.
224
333
  *
225
334
  * Convenient async iteration over remaining packets.
226
335
  * Combines flush and iteration.
227
336
  *
228
- * @yields Remaining packets
337
+ * @yields {Packet} Remaining packets
338
+ *
229
339
  * @throws {Error} If filter is disposed
230
340
  *
231
341
  * @example
@@ -239,6 +349,28 @@ export declare class BitStreamFilterAPI implements Disposable {
239
349
  * @see {@link flush} For array return
240
350
  */
241
351
  flushPackets(): AsyncGenerator<Packet>;
352
+ /**
353
+ * Flush filter as generator synchronously.
354
+ * Synchronous version of flushPackets.
355
+ *
356
+ * Convenient sync iteration over remaining packets.
357
+ * Combines flush and iteration.
358
+ *
359
+ * @yields {Packet} Remaining packets
360
+ *
361
+ * @throws {Error} If filter is disposed
362
+ *
363
+ * @example
364
+ * ```typescript
365
+ * for (const packet of filter.flushPacketsSync()) {
366
+ * output.writePacketSync(packet);
367
+ * packet.free();
368
+ * }
369
+ * ```
370
+ *
371
+ * @see {@link flushPackets} For async version
372
+ */
373
+ flushPacketsSync(): Generator<Packet>;
242
374
  /**
243
375
  * Get associated stream.
244
376
  *
@@ -45,8 +45,11 @@ export class BitStreamFilterAPI {
45
45
  isDisposed = false;
46
46
  /**
47
47
  * @param filter - Bitstream filter instance
48
+ *
48
49
  * @param ctx - Filter context
50
+ *
49
51
  * @param stream - Associated stream
52
+ *
50
53
  * @internal
51
54
  */
52
55
  constructor(filter, ctx, stream) {
@@ -63,7 +66,9 @@ export class BitStreamFilterAPI {
63
66
  * Direct mapping to av_bsf_get_by_name() and av_bsf_alloc().
64
67
  *
65
68
  * @param filterName - Name of the bitstream filter
69
+ *
66
70
  * @param stream - Stream to apply filter to
71
+ *
67
72
  * @returns Configured bitstream filter
68
73
  *
69
74
  * @throws {Error} If filter not found or initialization fails
@@ -172,6 +177,7 @@ export class BitStreamFilterAPI {
172
177
  * Direct mapping to av_bsf_send_packet() and av_bsf_receive_packet().
173
178
  *
174
179
  * @param packet - Packet to filter or null for EOF
180
+ *
175
181
  * @returns Array of filtered packets
176
182
  *
177
183
  * @throws {Error} If filter is disposed
@@ -223,6 +229,68 @@ export class BitStreamFilterAPI {
223
229
  }
224
230
  return outputPackets;
225
231
  }
232
+ /**
233
+ * Process a packet through the filter synchronously.
234
+ * Synchronous version of process.
235
+ *
236
+ * Applies bitstream filter to packet.
237
+ * May produce zero, one, or multiple output packets.
238
+ * Pass null to signal end-of-stream.
239
+ *
240
+ * Direct mapping to av_bsf_send_packet() and av_bsf_receive_packet().
241
+ *
242
+ * @param packet - Packet to filter or null for EOF
243
+ *
244
+ * @returns Array of filtered packets
245
+ *
246
+ * @throws {Error} If filter is disposed
247
+ *
248
+ * @throws {FFmpegError} If filtering fails
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * const outputPackets = filter.processSync(inputPacket);
253
+ * for (const packet of outputPackets) {
254
+ * console.log(`Filtered packet: pts=${packet.pts}`);
255
+ * packet.free();
256
+ * }
257
+ * ```
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * // Flush filter
262
+ * const remaining = filter.processSync(null);
263
+ * ```
264
+ *
265
+ * @see {@link process} For async version
266
+ */
267
+ processSync(packet) {
268
+ if (this.isDisposed) {
269
+ throw new Error('BitStreamFilterAPI is disposed');
270
+ }
271
+ const outputPackets = [];
272
+ // Send packet to filter
273
+ const sendRet = this.ctx.sendPacketSync(packet);
274
+ if (sendRet < 0 && sendRet !== AVERROR_EAGAIN) {
275
+ FFmpegError.throwIfError(sendRet, 'Failed to send packet to bitstream filter');
276
+ }
277
+ // Receive all output packets
278
+ while (true) {
279
+ const outPacket = new Packet();
280
+ outPacket.alloc();
281
+ const recvRet = this.ctx.receivePacketSync(outPacket);
282
+ if (recvRet === AVERROR_EAGAIN || recvRet === AVERROR_EOF) {
283
+ outPacket.unref();
284
+ break;
285
+ }
286
+ if (recvRet < 0) {
287
+ outPacket.unref();
288
+ FFmpegError.throwIfError(recvRet, 'Failed to receive packet from bitstream filter');
289
+ }
290
+ outputPackets.push(outPacket);
291
+ }
292
+ return outputPackets;
293
+ }
226
294
  /**
227
295
  * Process packet stream through filter.
228
296
  *
@@ -231,7 +299,9 @@ export class BitStreamFilterAPI {
231
299
  * Yields filtered packets ready for output.
232
300
  *
233
301
  * @param packets - Async iterable of packets
234
- * @yields Filtered packets
302
+ *
303
+ * @yields {Packet} Filtered packets
304
+ *
235
305
  * @throws {Error} If filter is disposed
236
306
  *
237
307
  * @throws {FFmpegError} If filtering fails
@@ -284,6 +354,69 @@ export class BitStreamFilterAPI {
284
354
  throw error;
285
355
  }
286
356
  }
357
+ /**
358
+ * Process packet stream through filter synchronously.
359
+ * Synchronous version of packets.
360
+ *
361
+ * High-level sync generator for filtering packet streams.
362
+ * Automatically handles flushing at end of stream.
363
+ * Yields filtered packets ready for output.
364
+ *
365
+ * @param packets - Iterable of packets
366
+ *
367
+ * @yields {Packet} Filtered packets
368
+ *
369
+ * @throws {Error} If filter is disposed
370
+ *
371
+ * @throws {FFmpegError} If filtering fails
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * // Filter entire stream
376
+ * for (const packet of filter.packetsSync(packets)) {
377
+ * output.writePacketSync(packet);
378
+ * packet.free();
379
+ * }
380
+ * ```
381
+ *
382
+ * @example
383
+ * ```typescript
384
+ * // Chain with decoder
385
+ * const decoder = await Decoder.create(stream);
386
+ * const filter = BitStreamFilterAPI.create('h264_mp4toannexb', stream);
387
+ *
388
+ * for (const frame of decoder.framesSync(filter.packetsSync(packets))) {
389
+ * // Process frames
390
+ * frame.free();
391
+ * }
392
+ * ```
393
+ *
394
+ * @see {@link packets} For async version
395
+ */
396
+ *packetsSync(packets) {
397
+ if (this.isDisposed) {
398
+ throw new Error('BitStreamFilterAPI is disposed');
399
+ }
400
+ try {
401
+ // Process all input packets
402
+ for (const packet of packets) {
403
+ const filtered = this.processSync(packet);
404
+ for (const outPacket of filtered) {
405
+ yield outPacket;
406
+ }
407
+ }
408
+ // Send EOF and get remaining packets
409
+ const remaining = this.flushSync();
410
+ for (const packet of remaining) {
411
+ yield packet;
412
+ }
413
+ }
414
+ catch (error) {
415
+ // Ensure cleanup on error
416
+ this.ctx.flush();
417
+ throw error;
418
+ }
419
+ }
287
420
  /**
288
421
  * Flush filter and get remaining packets.
289
422
  *
@@ -318,13 +451,48 @@ export class BitStreamFilterAPI {
318
451
  this.ctx.flush();
319
452
  return filtered;
320
453
  }
454
+ /**
455
+ * Flush filter and get remaining packets synchronously.
456
+ * Synchronous version of flush.
457
+ *
458
+ * Signals end-of-stream and retrieves buffered packets.
459
+ * Also resets internal filter state.
460
+ *
461
+ * Direct mapping to av_bsf_flush().
462
+ *
463
+ * @returns Array of remaining packets
464
+ *
465
+ * @throws {Error} If filter is disposed
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * const remaining = filter.flushSync();
470
+ * for (const packet of remaining) {
471
+ * output.writePacketSync(packet);
472
+ * packet.free();
473
+ * }
474
+ * ```
475
+ *
476
+ * @see {@link flush} For async version
477
+ */
478
+ flushSync() {
479
+ if (this.isDisposed) {
480
+ throw new Error('BitStreamFilterAPI is disposed');
481
+ }
482
+ // Send EOF
483
+ const filtered = this.processSync(null);
484
+ // Also flush the context to reset internal state
485
+ this.ctx.flush();
486
+ return filtered;
487
+ }
321
488
  /**
322
489
  * Flush filter as async generator.
323
490
  *
324
491
  * Convenient async iteration over remaining packets.
325
492
  * Combines flush and iteration.
326
493
  *
327
- * @yields Remaining packets
494
+ * @yields {Packet} Remaining packets
495
+ *
328
496
  * @throws {Error} If filter is disposed
329
497
  *
330
498
  * @example
@@ -346,6 +514,36 @@ export class BitStreamFilterAPI {
346
514
  yield packet;
347
515
  }
348
516
  }
517
+ /**
518
+ * Flush filter as generator synchronously.
519
+ * Synchronous version of flushPackets.
520
+ *
521
+ * Convenient sync iteration over remaining packets.
522
+ * Combines flush and iteration.
523
+ *
524
+ * @yields {Packet} Remaining packets
525
+ *
526
+ * @throws {Error} If filter is disposed
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * for (const packet of filter.flushPacketsSync()) {
531
+ * output.writePacketSync(packet);
532
+ * packet.free();
533
+ * }
534
+ * ```
535
+ *
536
+ * @see {@link flushPackets} For async version
537
+ */
538
+ *flushPacketsSync() {
539
+ if (this.isDisposed) {
540
+ throw new Error('BitStreamFilterAPI is disposed');
541
+ }
542
+ const remaining = this.flushSync();
543
+ for (const packet of remaining) {
544
+ yield packet;
545
+ }
546
+ }
349
547
  /**
350
548
  * Get associated stream.
351
549
  *
@@ -1 +1 @@
1
- {"version":3,"file":"bitstream-filter.js","sourceRoot":"","sources":["../../src/api/bitstream-filter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bitstream-filter.js","sourceRoot":"","sources":["../../src/api/bitstream-filter.ts"],"names":[],"mappings":"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"}