node-av 1.3.0 → 2.0.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.
- package/README.md +37 -38
- package/dist/api/bitstream-filter.d.ts +2 -2
- package/dist/api/bitstream-filter.js +2 -2
- package/dist/api/decoder.d.ts +131 -120
- package/dist/api/decoder.js +191 -203
- package/dist/api/decoder.js.map +1 -1
- package/dist/api/encoder.d.ts +135 -77
- package/dist/api/encoder.js +235 -192
- package/dist/api/encoder.js.map +1 -1
- package/dist/api/filter-presets.d.ts +408 -1534
- package/dist/api/filter-presets.js +1005 -2058
- package/dist/api/filter-presets.js.map +1 -1
- package/dist/api/filter.d.ts +160 -165
- package/dist/api/filter.js +294 -374
- package/dist/api/filter.js.map +1 -1
- package/dist/api/hardware.d.ts +8 -31
- package/dist/api/hardware.js +19 -70
- package/dist/api/hardware.js.map +1 -1
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/media-input.d.ts +1 -1
- package/dist/api/media-input.js +3 -8
- package/dist/api/media-input.js.map +1 -1
- package/dist/api/media-output.d.ts +35 -128
- package/dist/api/media-output.js +136 -208
- package/dist/api/media-output.js.map +1 -1
- package/dist/api/pipeline.d.ts +17 -17
- package/dist/api/pipeline.js +19 -42
- package/dist/api/pipeline.js.map +1 -1
- package/dist/api/types.d.ts +17 -57
- package/dist/lib/dictionary.d.ts +2 -2
- package/dist/lib/dictionary.js +2 -2
- package/dist/lib/dictionary.js.map +1 -1
- package/dist/lib/filter-context.d.ts +19 -2
- package/dist/lib/filter-context.js +15 -0
- package/dist/lib/filter-context.js.map +1 -1
- package/dist/lib/format-context.d.ts +18 -18
- package/dist/lib/format-context.js +20 -20
- package/dist/lib/format-context.js.map +1 -1
- package/dist/lib/frame.d.ts +43 -1
- package/dist/lib/frame.js +53 -0
- package/dist/lib/frame.js.map +1 -1
- package/package.json +17 -17
- package/release_notes.md +0 -29
package/dist/api/decoder.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { AVERROR_EAGAIN, AVERROR_EOF
|
|
2
|
-
import { Codec, CodecContext, FFmpegError, Frame } from '../lib/index.js';
|
|
1
|
+
import { AVERROR_EAGAIN, AVERROR_EOF } from '../constants/constants.js';
|
|
2
|
+
import { Codec, CodecContext, Dictionary, FFmpegError, Frame } from '../lib/index.js';
|
|
3
3
|
/**
|
|
4
4
|
* High-level decoder for audio and video streams.
|
|
5
5
|
*
|
|
@@ -44,23 +44,25 @@ import { Codec, CodecContext, FFmpegError, Frame } from '../lib/index.js';
|
|
|
44
44
|
*/
|
|
45
45
|
export class Decoder {
|
|
46
46
|
codecContext;
|
|
47
|
+
codec;
|
|
47
48
|
frame;
|
|
48
|
-
streamIndex;
|
|
49
49
|
stream;
|
|
50
|
-
|
|
50
|
+
initialized = true;
|
|
51
|
+
isClosed = false;
|
|
51
52
|
hardware;
|
|
52
53
|
/**
|
|
53
54
|
* @param codecContext - Configured codec context
|
|
55
|
+
* @param codec - Codec being used
|
|
54
56
|
* @param stream - Media stream being decoded
|
|
55
57
|
* @param hardware - Optional hardware context
|
|
56
58
|
* Use {@link create} factory method
|
|
57
59
|
*
|
|
58
60
|
* @internal
|
|
59
61
|
*/
|
|
60
|
-
constructor(codecContext, stream, hardware) {
|
|
62
|
+
constructor(codecContext, codec, stream, hardware) {
|
|
61
63
|
this.codecContext = codecContext;
|
|
64
|
+
this.codec = codec;
|
|
62
65
|
this.stream = stream;
|
|
63
|
-
this.streamIndex = stream.index;
|
|
64
66
|
this.hardware = hardware;
|
|
65
67
|
this.frame = new Frame();
|
|
66
68
|
this.frame.alloc();
|
|
@@ -142,20 +144,14 @@ export class Decoder {
|
|
|
142
144
|
if (isHWDecoder && options.hardware) {
|
|
143
145
|
codecContext.hwDeviceCtx = options.hardware.deviceContext;
|
|
144
146
|
}
|
|
145
|
-
|
|
146
|
-
if (options.options) {
|
|
147
|
-
for (const [key, value] of Object.entries(options.options)) {
|
|
148
|
-
codecContext.setOption(key, value.toString());
|
|
149
|
-
}
|
|
150
|
-
}
|
|
147
|
+
const opts = options.options ? Dictionary.fromObject(options.options) : undefined;
|
|
151
148
|
// Open codec
|
|
152
|
-
const openRet = await codecContext.open2(codec,
|
|
149
|
+
const openRet = await codecContext.open2(codec, opts);
|
|
153
150
|
if (openRet < 0) {
|
|
154
151
|
codecContext.freeContext();
|
|
155
152
|
FFmpegError.throwIfError(openRet, 'Failed to open codec');
|
|
156
153
|
}
|
|
157
|
-
|
|
158
|
-
return decoder;
|
|
154
|
+
return new Decoder(codecContext, codec, stream, isHWDecoder ? options.hardware : undefined);
|
|
159
155
|
}
|
|
160
156
|
/**
|
|
161
157
|
* Check if decoder is open.
|
|
@@ -170,59 +166,25 @@ export class Decoder {
|
|
|
170
166
|
* ```
|
|
171
167
|
*/
|
|
172
168
|
get isDecoderOpen() {
|
|
173
|
-
return this.
|
|
169
|
+
return !this.isClosed;
|
|
174
170
|
}
|
|
175
171
|
/**
|
|
176
|
-
*
|
|
172
|
+
* Check if decoder has been initialized.
|
|
177
173
|
*
|
|
178
|
-
* Returns
|
|
179
|
-
*
|
|
180
|
-
* Essential for configuring downstream components like encoders or filters.
|
|
174
|
+
* Returns true if decoder is initialized (true by default for decoders).
|
|
175
|
+
* Decoders are pre-initialized from stream parameters.
|
|
181
176
|
*
|
|
182
|
-
* @returns
|
|
183
|
-
*
|
|
184
|
-
* @example
|
|
185
|
-
* ```typescript
|
|
186
|
-
* const info = decoder.getOutputStreamInfo();
|
|
187
|
-
* if (info.type === 'video') {
|
|
188
|
-
* console.log(`Video: ${info.width}x${info.height} @ ${info.pixelFormat}`);
|
|
189
|
-
* console.log(`Frame rate: ${info.frameRate.num}/${info.frameRate.den}`);
|
|
190
|
-
* }
|
|
191
|
-
* ```
|
|
177
|
+
* @returns true if decoder has been initialized
|
|
192
178
|
*
|
|
193
179
|
* @example
|
|
194
180
|
* ```typescript
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* console.log(`Audio: ${info.sampleRate}Hz ${info.sampleFormat}`);
|
|
198
|
-
* console.log(`Channels: ${info.channelLayout}`);
|
|
181
|
+
* if (decoder.isDecoderInitialized) {
|
|
182
|
+
* console.log('Decoder is ready to process frames');
|
|
199
183
|
* }
|
|
200
184
|
* ```
|
|
201
|
-
*
|
|
202
|
-
* @see {@link StreamInfo} For format details
|
|
203
|
-
* @see {@link Encoder.create} For matching encoder configuration
|
|
204
185
|
*/
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
return {
|
|
208
|
-
type: 'video',
|
|
209
|
-
width: this.codecContext.width,
|
|
210
|
-
height: this.codecContext.height,
|
|
211
|
-
pixelFormat: this.hardware?.devicePixelFormat ?? this.codecContext.pixelFormat,
|
|
212
|
-
timeBase: this.stream.timeBase,
|
|
213
|
-
frameRate: this.stream.rFrameRate,
|
|
214
|
-
sampleAspectRatio: this.codecContext.sampleAspectRatio,
|
|
215
|
-
};
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
return {
|
|
219
|
-
type: 'audio',
|
|
220
|
-
sampleRate: this.codecContext.sampleRate,
|
|
221
|
-
sampleFormat: this.codecContext.sampleFormat,
|
|
222
|
-
channelLayout: this.codecContext.channelLayout,
|
|
223
|
-
timeBase: this.stream.timeBase,
|
|
224
|
-
};
|
|
225
|
-
}
|
|
186
|
+
get isDecoderInitialized() {
|
|
187
|
+
return this.initialized;
|
|
226
188
|
}
|
|
227
189
|
/**
|
|
228
190
|
* Check if decoder uses hardware acceleration.
|
|
@@ -239,7 +201,22 @@ export class Decoder {
|
|
|
239
201
|
* @see {@link HardwareContext} For hardware setup
|
|
240
202
|
*/
|
|
241
203
|
isHardware() {
|
|
242
|
-
return !!this.hardware;
|
|
204
|
+
return !!this.hardware && this.codec.isHardwareAcceleratedDecoder();
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Check if decoder is ready for processing.
|
|
208
|
+
*
|
|
209
|
+
* @returns true if initialized and ready
|
|
210
|
+
*
|
|
211
|
+
* @example
|
|
212
|
+
* ```typescript
|
|
213
|
+
* if (decoder.isReady()) {
|
|
214
|
+
* const frame = await decoder.decode(packet);
|
|
215
|
+
* }
|
|
216
|
+
* ```
|
|
217
|
+
*/
|
|
218
|
+
isReady() {
|
|
219
|
+
return this.initialized && !this.isClosed;
|
|
243
220
|
}
|
|
244
221
|
/**
|
|
245
222
|
* Decode a packet to a frame.
|
|
@@ -269,7 +246,7 @@ export class Decoder {
|
|
|
269
246
|
* @example
|
|
270
247
|
* ```typescript
|
|
271
248
|
* for await (const packet of input.packets()) {
|
|
272
|
-
* if (packet.streamIndex === decoder.
|
|
249
|
+
* if (packet.streamIndex === decoder.getStream().index) {
|
|
273
250
|
* const frame = await decoder.decode(packet);
|
|
274
251
|
* if (frame) {
|
|
275
252
|
* await processFrame(frame);
|
|
@@ -284,14 +261,14 @@ export class Decoder {
|
|
|
284
261
|
* @see {@link flush} For end-of-stream handling
|
|
285
262
|
*/
|
|
286
263
|
async decode(packet) {
|
|
287
|
-
if (
|
|
264
|
+
if (this.isClosed) {
|
|
288
265
|
throw new Error('Decoder is closed');
|
|
289
266
|
}
|
|
290
267
|
// Send packet to decoder
|
|
291
268
|
const sendRet = await this.codecContext.sendPacket(packet);
|
|
292
269
|
if (sendRet < 0 && sendRet !== AVERROR_EOF) {
|
|
293
270
|
// Decoder might be full, try to receive first
|
|
294
|
-
const frame = await this.
|
|
271
|
+
const frame = await this.receive();
|
|
295
272
|
if (frame) {
|
|
296
273
|
return frame;
|
|
297
274
|
}
|
|
@@ -301,78 +278,9 @@ export class Decoder {
|
|
|
301
278
|
}
|
|
302
279
|
}
|
|
303
280
|
// Try to receive frame
|
|
304
|
-
const frame = await this.
|
|
305
|
-
return frame;
|
|
306
|
-
}
|
|
307
|
-
/**
|
|
308
|
-
* Flush decoder and get buffered frame.
|
|
309
|
-
*
|
|
310
|
-
* Signals end-of-stream and retrieves remaining frames.
|
|
311
|
-
* Call repeatedly until null to get all buffered frames.
|
|
312
|
-
* Essential for ensuring all frames are decoded.
|
|
313
|
-
*
|
|
314
|
-
* Direct mapping to avcodec_send_packet(NULL).
|
|
315
|
-
*
|
|
316
|
-
* @returns Buffered frame or null if none remaining
|
|
317
|
-
*
|
|
318
|
-
* @throws {Error} If decoder is closed
|
|
319
|
-
*
|
|
320
|
-
* @example
|
|
321
|
-
* ```typescript
|
|
322
|
-
* // After all packets processed
|
|
323
|
-
* let frame;
|
|
324
|
-
* while ((frame = await decoder.flush()) !== null) {
|
|
325
|
-
* console.log('Got buffered frame');
|
|
326
|
-
* await processFrame(frame);
|
|
327
|
-
* frame.free();
|
|
328
|
-
* }
|
|
329
|
-
* ```
|
|
330
|
-
*
|
|
331
|
-
* @see {@link flushFrames} For async iteration
|
|
332
|
-
* @see {@link frames} For complete decoding pipeline
|
|
333
|
-
*/
|
|
334
|
-
async flush() {
|
|
335
|
-
if (!this.isOpen) {
|
|
336
|
-
throw new Error('Decoder is closed');
|
|
337
|
-
}
|
|
338
|
-
// Send flush packet (null)
|
|
339
|
-
await this.codecContext.sendPacket(null);
|
|
340
|
-
// Receive frame
|
|
341
|
-
const frame = await this.receiveFrameInternal();
|
|
281
|
+
const frame = await this.receive();
|
|
342
282
|
return frame;
|
|
343
283
|
}
|
|
344
|
-
/**
|
|
345
|
-
* Flush all buffered frames as async generator.
|
|
346
|
-
*
|
|
347
|
-
* Convenient async iteration over remaining frames.
|
|
348
|
-
* Automatically handles repeated flush calls.
|
|
349
|
-
* Useful for end-of-stream processing.
|
|
350
|
-
*
|
|
351
|
-
* @yields Buffered frames
|
|
352
|
-
* @throws {Error} If decoder is closed
|
|
353
|
-
*
|
|
354
|
-
* @example
|
|
355
|
-
* ```typescript
|
|
356
|
-
* // Flush at end of decoding
|
|
357
|
-
* for await (const frame of decoder.flushFrames()) {
|
|
358
|
-
* console.log('Processing buffered frame');
|
|
359
|
-
* await encoder.encode(frame);
|
|
360
|
-
* frame.free();
|
|
361
|
-
* }
|
|
362
|
-
* ```
|
|
363
|
-
*
|
|
364
|
-
* @see {@link flush} For single frame flush
|
|
365
|
-
* @see {@link frames} For complete pipeline
|
|
366
|
-
*/
|
|
367
|
-
async *flushFrames() {
|
|
368
|
-
if (!this.isOpen) {
|
|
369
|
-
throw new Error('Decoder is closed');
|
|
370
|
-
}
|
|
371
|
-
let frame;
|
|
372
|
-
while ((frame = await this.flush()) !== null) {
|
|
373
|
-
yield frame;
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
284
|
/**
|
|
377
285
|
* Decode packet stream to frame stream.
|
|
378
286
|
*
|
|
@@ -382,7 +290,7 @@ export class Decoder {
|
|
|
382
290
|
* Primary interface for stream-based decoding.
|
|
383
291
|
*
|
|
384
292
|
* @param packets - Async iterable of packets
|
|
385
|
-
* @yields Decoded frames
|
|
293
|
+
* @yields {Frame} Decoded frames
|
|
386
294
|
* @throws {Error} If decoder is closed
|
|
387
295
|
*
|
|
388
296
|
* @throws {FFmpegError} If decoding fails
|
|
@@ -402,7 +310,7 @@ export class Decoder {
|
|
|
402
310
|
* ```typescript
|
|
403
311
|
* for await (const frame of decoder.frames(input.packets())) {
|
|
404
312
|
* // Process frame
|
|
405
|
-
* await filter.
|
|
313
|
+
* await filter.process(frame);
|
|
406
314
|
*
|
|
407
315
|
* // Frame automatically freed
|
|
408
316
|
* frame.free();
|
|
@@ -426,14 +334,11 @@ export class Decoder {
|
|
|
426
334
|
* @see {@link MediaInput.packets} For packet source
|
|
427
335
|
*/
|
|
428
336
|
async *frames(packets) {
|
|
429
|
-
if (!this.isOpen) {
|
|
430
|
-
throw new Error('Decoder is closed');
|
|
431
|
-
}
|
|
432
337
|
// Process packets
|
|
433
338
|
for await (const packet of packets) {
|
|
434
339
|
try {
|
|
435
340
|
// Only process packets for our stream
|
|
436
|
-
if (packet.streamIndex === this.
|
|
341
|
+
if (packet.streamIndex === this.stream.index) {
|
|
437
342
|
const frame = await this.decode(packet);
|
|
438
343
|
if (frame) {
|
|
439
344
|
yield frame;
|
|
@@ -446,11 +351,137 @@ export class Decoder {
|
|
|
446
351
|
}
|
|
447
352
|
}
|
|
448
353
|
// Flush decoder after all packets
|
|
354
|
+
await this.flush();
|
|
355
|
+
while (true) {
|
|
356
|
+
const remaining = await this.receive();
|
|
357
|
+
if (!remaining)
|
|
358
|
+
break;
|
|
359
|
+
yield remaining;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* Flush decoder and signal end-of-stream.
|
|
364
|
+
*
|
|
365
|
+
* Sends null packet to decoder to signal end-of-stream.
|
|
366
|
+
* Does nothing if decoder is closed.
|
|
367
|
+
* Must use receive() or flushFrames() to get remaining buffered frames.
|
|
368
|
+
*
|
|
369
|
+
* Direct mapping to avcodec_send_packet(NULL).
|
|
370
|
+
*
|
|
371
|
+
* @throws {FFmpegError} If flush fails
|
|
372
|
+
*
|
|
373
|
+
* @example
|
|
374
|
+
* ```typescript
|
|
375
|
+
* // Signal end of stream
|
|
376
|
+
* await decoder.flush();
|
|
377
|
+
*
|
|
378
|
+
* // Then get remaining frames
|
|
379
|
+
* let frame;
|
|
380
|
+
* while ((frame = await decoder.receive()) !== null) {
|
|
381
|
+
* console.log('Got buffered frame');
|
|
382
|
+
* frame.free();
|
|
383
|
+
* }
|
|
384
|
+
* ```
|
|
385
|
+
*
|
|
386
|
+
* @see {@link flushFrames} For convenient async iteration
|
|
387
|
+
* @see {@link receive} For getting buffered frames
|
|
388
|
+
*/
|
|
389
|
+
async flush() {
|
|
390
|
+
if (this.isClosed) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
// Send flush packet (null)
|
|
394
|
+
const ret = await this.codecContext.sendPacket(null);
|
|
395
|
+
if (ret < 0 && ret !== AVERROR_EOF) {
|
|
396
|
+
if (ret !== AVERROR_EAGAIN) {
|
|
397
|
+
FFmpegError.throwIfError(ret, 'Failed to flush decoder');
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Flush all buffered frames as async generator.
|
|
403
|
+
*
|
|
404
|
+
* Convenient async iteration over remaining frames.
|
|
405
|
+
* Automatically sends flush signal and retrieves buffered frames.
|
|
406
|
+
* Useful for end-of-stream processing.
|
|
407
|
+
*
|
|
408
|
+
* @yields {Frame} Buffered frames
|
|
409
|
+
*
|
|
410
|
+
* @example
|
|
411
|
+
* ```typescript
|
|
412
|
+
* // Flush at end of decoding
|
|
413
|
+
* for await (const frame of decoder.flushFrames()) {
|
|
414
|
+
* console.log('Processing buffered frame');
|
|
415
|
+
* await encoder.encode(frame);
|
|
416
|
+
* frame.free();
|
|
417
|
+
* }
|
|
418
|
+
* ```
|
|
419
|
+
*
|
|
420
|
+
* @see {@link flush} For signaling end-of-stream
|
|
421
|
+
* @see {@link frames} For complete pipeline
|
|
422
|
+
*/
|
|
423
|
+
async *flushFrames() {
|
|
424
|
+
// Send flush signal
|
|
425
|
+
await this.flush();
|
|
449
426
|
let frame;
|
|
450
|
-
while ((frame = await this.
|
|
427
|
+
while ((frame = await this.receive()) !== null) {
|
|
451
428
|
yield frame;
|
|
452
429
|
}
|
|
453
430
|
}
|
|
431
|
+
/**
|
|
432
|
+
* Receive frame from decoder.
|
|
433
|
+
*
|
|
434
|
+
* Gets decoded frames from the codec's internal buffer.
|
|
435
|
+
* Handles frame cloning and error checking.
|
|
436
|
+
* Hardware frames include hw_frames_ctx reference.
|
|
437
|
+
* Call repeatedly until null to drain all buffered frames.
|
|
438
|
+
*
|
|
439
|
+
* Direct mapping to avcodec_receive_frame().
|
|
440
|
+
*
|
|
441
|
+
* @returns Cloned frame or null if no frames available
|
|
442
|
+
*
|
|
443
|
+
* @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
|
|
444
|
+
*
|
|
445
|
+
* @example
|
|
446
|
+
* ```typescript
|
|
447
|
+
* const frame = await decoder.receive();
|
|
448
|
+
* if (frame) {
|
|
449
|
+
* console.log('Got decoded frame');
|
|
450
|
+
* frame.free();
|
|
451
|
+
* }
|
|
452
|
+
* ```
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* ```typescript
|
|
456
|
+
* // Drain all buffered frames
|
|
457
|
+
* let frame;
|
|
458
|
+
* while ((frame = await decoder.receive()) !== null) {
|
|
459
|
+
* console.log(`Frame PTS: ${frame.pts}`);
|
|
460
|
+
* frame.free();
|
|
461
|
+
* }
|
|
462
|
+
* ```
|
|
463
|
+
*
|
|
464
|
+
* @see {@link decode} For sending packets and receiving frames
|
|
465
|
+
* @see {@link flush} For signaling end-of-stream
|
|
466
|
+
*/
|
|
467
|
+
async receive() {
|
|
468
|
+
// Clear previous frame data
|
|
469
|
+
this.frame.unref();
|
|
470
|
+
const ret = await this.codecContext.receiveFrame(this.frame);
|
|
471
|
+
if (ret === 0) {
|
|
472
|
+
// Got a frame, clone it for the user
|
|
473
|
+
return this.frame.clone();
|
|
474
|
+
}
|
|
475
|
+
else if (ret === AVERROR_EAGAIN || ret === AVERROR_EOF) {
|
|
476
|
+
// Need more data or end of stream
|
|
477
|
+
return null;
|
|
478
|
+
}
|
|
479
|
+
else {
|
|
480
|
+
// Error
|
|
481
|
+
FFmpegError.throwIfError(ret, 'Failed to receive frame');
|
|
482
|
+
return null;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
454
485
|
/**
|
|
455
486
|
* Close decoder and free resources.
|
|
456
487
|
*
|
|
@@ -471,32 +502,13 @@ export class Decoder {
|
|
|
471
502
|
* @see {@link Symbol.dispose} For automatic cleanup
|
|
472
503
|
*/
|
|
473
504
|
close() {
|
|
474
|
-
if (
|
|
505
|
+
if (this.isClosed) {
|
|
475
506
|
return;
|
|
476
507
|
}
|
|
508
|
+
this.isClosed = true;
|
|
477
509
|
this.frame.free();
|
|
478
510
|
this.codecContext.freeContext();
|
|
479
|
-
this.
|
|
480
|
-
}
|
|
481
|
-
/**
|
|
482
|
-
* Get stream index.
|
|
483
|
-
*
|
|
484
|
-
* Returns the index of the stream being decoded.
|
|
485
|
-
* Used for packet filtering in multi-stream files.
|
|
486
|
-
*
|
|
487
|
-
* @returns Stream index
|
|
488
|
-
*
|
|
489
|
-
* @example
|
|
490
|
-
* ```typescript
|
|
491
|
-
* if (packet.streamIndex === decoder.getStreamIndex()) {
|
|
492
|
-
* const frame = await decoder.decode(packet);
|
|
493
|
-
* }
|
|
494
|
-
* ```
|
|
495
|
-
*
|
|
496
|
-
* @see {@link getStream} For full stream object
|
|
497
|
-
*/
|
|
498
|
-
getStreamIndex() {
|
|
499
|
-
return this.streamIndex;
|
|
511
|
+
this.initialized = false;
|
|
500
512
|
}
|
|
501
513
|
/**
|
|
502
514
|
* Get stream object.
|
|
@@ -506,67 +518,43 @@ export class Decoder {
|
|
|
506
518
|
*
|
|
507
519
|
* @returns Stream object
|
|
508
520
|
*
|
|
509
|
-
* @
|
|
510
|
-
* ```typescript
|
|
511
|
-
* const stream = decoder.getStream();
|
|
512
|
-
* console.log(`Duration: ${stream.duration}`);
|
|
513
|
-
* console.log(`Time base: ${stream.timeBase.num}/${stream.timeBase.den}`);
|
|
514
|
-
* ```
|
|
521
|
+
* @internal
|
|
515
522
|
*
|
|
516
|
-
* @see {@link Stream} For stream
|
|
517
|
-
* @see {@link getStreamIndex} For index only
|
|
523
|
+
* @see {@link Stream} For stream details
|
|
518
524
|
*/
|
|
519
525
|
getStream() {
|
|
520
526
|
return this.stream;
|
|
521
527
|
}
|
|
522
528
|
/**
|
|
523
|
-
* Get
|
|
529
|
+
* Get decoder codec.
|
|
524
530
|
*
|
|
525
|
-
* Returns the
|
|
526
|
-
*
|
|
531
|
+
* Returns the codec used by this decoder.
|
|
532
|
+
* Useful for checking codec capabilities and properties.
|
|
527
533
|
*
|
|
528
|
-
* @returns Codec
|
|
534
|
+
* @returns Codec instance
|
|
529
535
|
*
|
|
530
536
|
* @internal
|
|
537
|
+
*
|
|
538
|
+
* @see {@link Codec} For codec details
|
|
531
539
|
*/
|
|
532
|
-
|
|
533
|
-
return this.
|
|
540
|
+
getCodec() {
|
|
541
|
+
return this.codec;
|
|
534
542
|
}
|
|
535
543
|
/**
|
|
536
|
-
*
|
|
537
|
-
*
|
|
538
|
-
* Internal method to get decoded frames from codec.
|
|
539
|
-
* Handles frame cloning and error checking.
|
|
540
|
-
* Hardware frames include hw_frames_ctx reference.
|
|
544
|
+
* Get underlying codec context.
|
|
541
545
|
*
|
|
542
|
-
*
|
|
546
|
+
* Returns the codec context for advanced operations.
|
|
547
|
+
* Useful for accessing low-level codec properties and settings.
|
|
548
|
+
* Returns null if decoder is closed.
|
|
543
549
|
*
|
|
544
|
-
* @returns
|
|
545
|
-
*
|
|
546
|
-
* @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
|
|
550
|
+
* @returns Codec context or null if closed
|
|
547
551
|
*
|
|
548
552
|
* @internal
|
|
549
553
|
*
|
|
554
|
+
* @see {@link CodecContext} For context details
|
|
550
555
|
*/
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
this.frame.unref();
|
|
554
|
-
const ret = await this.codecContext.receiveFrame(this.frame);
|
|
555
|
-
if (ret === 0) {
|
|
556
|
-
// Note: hw_frames_ctx is now available in the frame
|
|
557
|
-
// Other components should get it directly from frames, not from HardwareContext
|
|
558
|
-
// Got a frame, clone it for the user
|
|
559
|
-
return this.frame.clone();
|
|
560
|
-
}
|
|
561
|
-
else if (ret === AVERROR_EAGAIN || ret === AVERROR_EOF) {
|
|
562
|
-
// Need more data or end of stream
|
|
563
|
-
return null;
|
|
564
|
-
}
|
|
565
|
-
else {
|
|
566
|
-
// Error
|
|
567
|
-
FFmpegError.throwIfError(ret, 'Failed to receive frame');
|
|
568
|
-
return null;
|
|
569
|
-
}
|
|
556
|
+
getCodecContext() {
|
|
557
|
+
return !this.isClosed && this.initialized ? this.codecContext : null;
|
|
570
558
|
}
|
|
571
559
|
/**
|
|
572
560
|
* Dispose of decoder.
|
package/dist/api/decoder.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../src/api/decoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"decoder.js","sourceRoot":"","sources":["../../src/api/decoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAMtF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,OAAO,OAAO;IACV,YAAY,CAAe;IAC3B,KAAK,CAAQ;IACb,KAAK,CAAQ;IACb,MAAM,CAAS;IACf,WAAW,GAAG,IAAI,CAAC;IACnB,QAAQ,GAAG,KAAK,CAAC;IACjB,QAAQ,CAA0B;IAE1C;;;;;;;;OAQG;IACH,YAAoB,YAA0B,EAAE,KAAY,EAAE,MAAc,EAAE,QAAiC;QAC7G,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6CG;IACH,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,MAAc,EAAE,UAA0B,EAAE;QAC9D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACxC,CAAC;QAED,8BAA8B;QAC9B,MAAM,KAAK,GAAG,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,+BAA+B,MAAM,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;QAED,uCAAuC;QACvC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC;QACxC,YAAY,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;QAElC,mCAAmC;QACnC,MAAM,GAAG,GAAG,YAAY,CAAC,mBAAmB,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC9D,IAAI,GAAG,GAAG,CAAC,EAAE,CAAC;YACZ,YAAY,CAAC,WAAW,EAAE,CAAC;YAC3B,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,iCAAiC,CAAC,CAAC;QACnE,CAAC;QAED,uBAAuB;QACvB,YAAY,CAAC,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC;QAE3C,gBAAgB;QAChB,IAAI,OAAO,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;YAClC,YAAY,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC;QAC7C,CAAC;QAED,uDAAuD;QACvD,8DAA8D;QAC9D,iDAAiD;QACjD,MAAM,WAAW,GAAG,KAAK,CAAC,4BAA4B,EAAE,CAAC;QACzD,IAAI,WAAW,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YACpC,YAAY,CAAC,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC;QAC5D,CAAC;QAED,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QAElF,aAAa;QACb,MAAM,OAAO,GAAG,MAAM,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QACtD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;YAChB,YAAY,CAAC,WAAW,EAAE,CAAC;YAC3B,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,sBAAsB,CAAC,CAAC;QAC5D,CAAC;QAED,OAAO,IAAI,OAAO,CAAC,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAC9F,CAAC;IAED;;;;;;;;;;;OAWG;IACH,IAAI,aAAa;QACf,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;IACxB,CAAC;IAED;;;;;;;;;;;;;;OAcG;IACH,IAAI,oBAAoB;QACtB,OAAO,IAAI,CAAC,WAAW,CAAC;IAC1B,CAAC;IAED;;;;;;;;;;;;;OAaG;IACH,UAAU;QACR,OAAO,CAAC,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,4BAA4B,EAAE,CAAC;IACtE,CAAC;IAED;;;;;;;;;;;OAWG;IACH,OAAO;QACL,OAAO,IAAI,CAAC,WAAW,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;IAC5C,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAyCG;IACH,KAAK,CAAC,MAAM,CAAC,MAAc;QACzB,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;QACvC,CAAC;QAED,yBAAyB;QACzB,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;QAC3D,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,KAAK,WAAW,EAAE,CAAC;YAC3C,8CAA8C;YAC9C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,KAAK,CAAC;YACf,CAAC;YAED,kCAAkC;YAClC,IAAI,OAAO,KAAK,cAAc,EAAE,CAAC;gBAC/B,WAAW,CAAC,YAAY,CAAC,OAAO,EAAE,uBAAuB,CAAC,CAAC;YAC7D,CAAC;QACH,CAAC;QAED,uBAAuB;QACvB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACnC,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmDG;IACH,KAAK,CAAC,CAAC,MAAM,CAAC,OAA8B;QAC1C,kBAAkB;QAClB,IAAI,KAAK,EAAE,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC;gBACH,sCAAsC;gBACtC,IAAI,MAAM,CAAC,WAAW,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;oBAC7C,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;oBACxC,IAAI,KAAK,EAAE,CAAC;wBACV,MAAM,KAAK,CAAC;oBACd,CAAC;gBACH,CAAC;YACH,CAAC;oBAAS,CAAC;gBACT,yCAAyC;gBACzC,MAAM,CAAC,IAAI,EAAE,CAAC;YAChB,CAAC;QACH,CAAC;QAED,kCAAkC;QAClC,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,EAAE,CAAC;YACZ,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACvC,IAAI,CAAC,SAAS;gBAAE,MAAM;YACtB,MAAM,SAAS,CAAC;QAClB,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,2BAA2B;QAC3B,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACrD,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACnC,IAAI,GAAG,KAAK,cAAc,EAAE,CAAC;gBAC3B,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,KAAK,CAAC,CAAC,WAAW;QAChB,oBAAoB;QACpB,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QAEnB,IAAI,KAAK,CAAC;QACV,OAAO,CAAC,KAAK,GAAG,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;YAC/C,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAmCG;IACH,KAAK,CAAC,OAAO;QACX,4BAA4B;QAC5B,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAEnB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE7D,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC;YACd,qCAAqC;YACrC,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAC5B,CAAC;aAAM,IAAI,GAAG,KAAK,cAAc,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;YACzD,kCAAkC;YAClC,OAAO,IAAI,CAAC;QACd,CAAC;aAAM,CAAC;YACN,QAAQ;YACR,WAAW,CAAC,YAAY,CAAC,GAAG,EAAE,yBAAyB,CAAC,CAAC;YACzD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QAED,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QAErB,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,CAAC;QAEhC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IAC3B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,SAAS;QACP,OAAO,IAAI,CAAC,MAAM,CAAC;IACrB,CAAC;IAED;;;;;;;;;;;OAWG;IACH,QAAQ;QACN,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED;;;;;;;;;;;;OAYG;IACH,eAAe;QACb,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC;IACvE,CAAC;IAED;;;;;;;;;;;;;;;OAeG;IACH,CAAC,MAAM,CAAC,OAAO,CAAC;QACd,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF"}
|