@revizly/node-av 5.2.2-beta.1
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/BUILD_LINUX.md +61 -0
- package/LICENSE.md +22 -0
- package/README.md +662 -0
- package/build_mac_local.sh +69 -0
- package/dist/api/audio-frame-buffer.d.ts +205 -0
- package/dist/api/audio-frame-buffer.js +287 -0
- package/dist/api/audio-frame-buffer.js.map +1 -0
- package/dist/api/bitstream-filter.d.ts +820 -0
- package/dist/api/bitstream-filter.js +1242 -0
- package/dist/api/bitstream-filter.js.map +1 -0
- package/dist/api/constants.d.ts +44 -0
- package/dist/api/constants.js +45 -0
- package/dist/api/constants.js.map +1 -0
- package/dist/api/data/test_av1.ivf +0 -0
- package/dist/api/data/test_h264.h264 +0 -0
- package/dist/api/data/test_hevc.h265 +0 -0
- package/dist/api/data/test_mjpeg.mjpeg +0 -0
- package/dist/api/data/test_vp8.ivf +0 -0
- package/dist/api/data/test_vp9.ivf +0 -0
- package/dist/api/decoder.d.ts +1088 -0
- package/dist/api/decoder.js +1775 -0
- package/dist/api/decoder.js.map +1 -0
- package/dist/api/demuxer.d.ts +1219 -0
- package/dist/api/demuxer.js +2081 -0
- package/dist/api/demuxer.js.map +1 -0
- package/dist/api/device.d.ts +586 -0
- package/dist/api/device.js +961 -0
- package/dist/api/device.js.map +1 -0
- package/dist/api/encoder.d.ts +1132 -0
- package/dist/api/encoder.js +1988 -0
- package/dist/api/encoder.js.map +1 -0
- package/dist/api/filter-complex.d.ts +821 -0
- package/dist/api/filter-complex.js +1604 -0
- package/dist/api/filter-complex.js.map +1 -0
- package/dist/api/filter-presets.d.ts +1286 -0
- package/dist/api/filter-presets.js +2152 -0
- package/dist/api/filter-presets.js.map +1 -0
- package/dist/api/filter.d.ts +1234 -0
- package/dist/api/filter.js +1976 -0
- package/dist/api/filter.js.map +1 -0
- package/dist/api/fmp4-stream.d.ts +426 -0
- package/dist/api/fmp4-stream.js +739 -0
- package/dist/api/fmp4-stream.js.map +1 -0
- package/dist/api/hardware.d.ts +651 -0
- package/dist/api/hardware.js +1260 -0
- package/dist/api/hardware.js.map +1 -0
- package/dist/api/index.d.ts +17 -0
- package/dist/api/index.js +32 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/io-stream.d.ts +307 -0
- package/dist/api/io-stream.js +282 -0
- package/dist/api/io-stream.js.map +1 -0
- package/dist/api/muxer.d.ts +957 -0
- package/dist/api/muxer.js +2002 -0
- package/dist/api/muxer.js.map +1 -0
- package/dist/api/pipeline.d.ts +607 -0
- package/dist/api/pipeline.js +1145 -0
- package/dist/api/pipeline.js.map +1 -0
- package/dist/api/utilities/async-queue.d.ts +120 -0
- package/dist/api/utilities/async-queue.js +211 -0
- package/dist/api/utilities/async-queue.js.map +1 -0
- package/dist/api/utilities/audio-sample.d.ts +117 -0
- package/dist/api/utilities/audio-sample.js +112 -0
- package/dist/api/utilities/audio-sample.js.map +1 -0
- package/dist/api/utilities/channel-layout.d.ts +76 -0
- package/dist/api/utilities/channel-layout.js +80 -0
- package/dist/api/utilities/channel-layout.js.map +1 -0
- package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
- package/dist/api/utilities/electron-shared-texture.js +503 -0
- package/dist/api/utilities/electron-shared-texture.js.map +1 -0
- package/dist/api/utilities/image.d.ts +207 -0
- package/dist/api/utilities/image.js +213 -0
- package/dist/api/utilities/image.js.map +1 -0
- package/dist/api/utilities/index.d.ts +12 -0
- package/dist/api/utilities/index.js +25 -0
- package/dist/api/utilities/index.js.map +1 -0
- package/dist/api/utilities/media-type.d.ts +49 -0
- package/dist/api/utilities/media-type.js +53 -0
- package/dist/api/utilities/media-type.js.map +1 -0
- package/dist/api/utilities/pixel-format.d.ts +89 -0
- package/dist/api/utilities/pixel-format.js +97 -0
- package/dist/api/utilities/pixel-format.js.map +1 -0
- package/dist/api/utilities/sample-format.d.ts +129 -0
- package/dist/api/utilities/sample-format.js +141 -0
- package/dist/api/utilities/sample-format.js.map +1 -0
- package/dist/api/utilities/scheduler.d.ts +138 -0
- package/dist/api/utilities/scheduler.js +98 -0
- package/dist/api/utilities/scheduler.js.map +1 -0
- package/dist/api/utilities/streaming.d.ts +186 -0
- package/dist/api/utilities/streaming.js +309 -0
- package/dist/api/utilities/streaming.js.map +1 -0
- package/dist/api/utilities/timestamp.d.ts +193 -0
- package/dist/api/utilities/timestamp.js +206 -0
- package/dist/api/utilities/timestamp.js.map +1 -0
- package/dist/api/utilities/whisper-model.d.ts +310 -0
- package/dist/api/utilities/whisper-model.js +528 -0
- package/dist/api/utilities/whisper-model.js.map +1 -0
- package/dist/api/utils.d.ts +19 -0
- package/dist/api/utils.js +39 -0
- package/dist/api/utils.js.map +1 -0
- package/dist/api/whisper.d.ts +324 -0
- package/dist/api/whisper.js +362 -0
- package/dist/api/whisper.js.map +1 -0
- package/dist/constants/channel-layouts.d.ts +53 -0
- package/dist/constants/channel-layouts.js +57 -0
- package/dist/constants/channel-layouts.js.map +1 -0
- package/dist/constants/constants.d.ts +2325 -0
- package/dist/constants/constants.js +1887 -0
- package/dist/constants/constants.js.map +1 -0
- package/dist/constants/decoders.d.ts +633 -0
- package/dist/constants/decoders.js +641 -0
- package/dist/constants/decoders.js.map +1 -0
- package/dist/constants/encoders.d.ts +295 -0
- package/dist/constants/encoders.js +308 -0
- package/dist/constants/encoders.js.map +1 -0
- package/dist/constants/hardware.d.ts +26 -0
- package/dist/constants/hardware.js +27 -0
- package/dist/constants/hardware.js.map +1 -0
- package/dist/constants/index.d.ts +5 -0
- package/dist/constants/index.js +6 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/ffmpeg/index.d.ts +99 -0
- package/dist/ffmpeg/index.js +115 -0
- package/dist/ffmpeg/index.js.map +1 -0
- package/dist/ffmpeg/utils.d.ts +31 -0
- package/dist/ffmpeg/utils.js +68 -0
- package/dist/ffmpeg/utils.js.map +1 -0
- package/dist/ffmpeg/version.d.ts +6 -0
- package/dist/ffmpeg/version.js +7 -0
- package/dist/ffmpeg/version.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +9 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audio-fifo.d.ts +399 -0
- package/dist/lib/audio-fifo.js +431 -0
- package/dist/lib/audio-fifo.js.map +1 -0
- package/dist/lib/binding.d.ts +228 -0
- package/dist/lib/binding.js +60 -0
- package/dist/lib/binding.js.map +1 -0
- package/dist/lib/bitstream-filter-context.d.ts +379 -0
- package/dist/lib/bitstream-filter-context.js +441 -0
- package/dist/lib/bitstream-filter-context.js.map +1 -0
- package/dist/lib/bitstream-filter.d.ts +140 -0
- package/dist/lib/bitstream-filter.js +154 -0
- package/dist/lib/bitstream-filter.js.map +1 -0
- package/dist/lib/codec-context.d.ts +1071 -0
- package/dist/lib/codec-context.js +1354 -0
- package/dist/lib/codec-context.js.map +1 -0
- package/dist/lib/codec-parameters.d.ts +616 -0
- package/dist/lib/codec-parameters.js +761 -0
- package/dist/lib/codec-parameters.js.map +1 -0
- package/dist/lib/codec-parser.d.ts +201 -0
- package/dist/lib/codec-parser.js +213 -0
- package/dist/lib/codec-parser.js.map +1 -0
- package/dist/lib/codec.d.ts +586 -0
- package/dist/lib/codec.js +713 -0
- package/dist/lib/codec.js.map +1 -0
- package/dist/lib/device.d.ts +291 -0
- package/dist/lib/device.js +324 -0
- package/dist/lib/device.js.map +1 -0
- package/dist/lib/dictionary.d.ts +333 -0
- package/dist/lib/dictionary.js +372 -0
- package/dist/lib/dictionary.js.map +1 -0
- package/dist/lib/error.d.ts +242 -0
- package/dist/lib/error.js +303 -0
- package/dist/lib/error.js.map +1 -0
- package/dist/lib/fifo.d.ts +416 -0
- package/dist/lib/fifo.js +453 -0
- package/dist/lib/fifo.js.map +1 -0
- package/dist/lib/filter-context.d.ts +712 -0
- package/dist/lib/filter-context.js +789 -0
- package/dist/lib/filter-context.js.map +1 -0
- package/dist/lib/filter-graph-segment.d.ts +160 -0
- package/dist/lib/filter-graph-segment.js +171 -0
- package/dist/lib/filter-graph-segment.js.map +1 -0
- package/dist/lib/filter-graph.d.ts +641 -0
- package/dist/lib/filter-graph.js +704 -0
- package/dist/lib/filter-graph.js.map +1 -0
- package/dist/lib/filter-inout.d.ts +198 -0
- package/dist/lib/filter-inout.js +257 -0
- package/dist/lib/filter-inout.js.map +1 -0
- package/dist/lib/filter.d.ts +243 -0
- package/dist/lib/filter.js +272 -0
- package/dist/lib/filter.js.map +1 -0
- package/dist/lib/format-context.d.ts +1254 -0
- package/dist/lib/format-context.js +1379 -0
- package/dist/lib/format-context.js.map +1 -0
- package/dist/lib/frame-utils.d.ts +116 -0
- package/dist/lib/frame-utils.js +98 -0
- package/dist/lib/frame-utils.js.map +1 -0
- package/dist/lib/frame.d.ts +1222 -0
- package/dist/lib/frame.js +1435 -0
- package/dist/lib/frame.js.map +1 -0
- package/dist/lib/hardware-device-context.d.ts +362 -0
- package/dist/lib/hardware-device-context.js +383 -0
- package/dist/lib/hardware-device-context.js.map +1 -0
- package/dist/lib/hardware-frames-context.d.ts +419 -0
- package/dist/lib/hardware-frames-context.js +477 -0
- package/dist/lib/hardware-frames-context.js.map +1 -0
- package/dist/lib/index.d.ts +35 -0
- package/dist/lib/index.js +60 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/input-format.d.ts +249 -0
- package/dist/lib/input-format.js +306 -0
- package/dist/lib/input-format.js.map +1 -0
- package/dist/lib/io-context.d.ts +696 -0
- package/dist/lib/io-context.js +769 -0
- package/dist/lib/io-context.js.map +1 -0
- package/dist/lib/log.d.ts +174 -0
- package/dist/lib/log.js +184 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/native-types.d.ts +946 -0
- package/dist/lib/native-types.js +2 -0
- package/dist/lib/native-types.js.map +1 -0
- package/dist/lib/option.d.ts +927 -0
- package/dist/lib/option.js +1583 -0
- package/dist/lib/option.js.map +1 -0
- package/dist/lib/output-format.d.ts +180 -0
- package/dist/lib/output-format.js +213 -0
- package/dist/lib/output-format.js.map +1 -0
- package/dist/lib/packet.d.ts +501 -0
- package/dist/lib/packet.js +590 -0
- package/dist/lib/packet.js.map +1 -0
- package/dist/lib/rational.d.ts +251 -0
- package/dist/lib/rational.js +278 -0
- package/dist/lib/rational.js.map +1 -0
- package/dist/lib/software-resample-context.d.ts +552 -0
- package/dist/lib/software-resample-context.js +592 -0
- package/dist/lib/software-resample-context.js.map +1 -0
- package/dist/lib/software-scale-context.d.ts +344 -0
- package/dist/lib/software-scale-context.js +366 -0
- package/dist/lib/software-scale-context.js.map +1 -0
- package/dist/lib/stream.d.ts +379 -0
- package/dist/lib/stream.js +526 -0
- package/dist/lib/stream.js.map +1 -0
- package/dist/lib/sync-queue.d.ts +179 -0
- package/dist/lib/sync-queue.js +197 -0
- package/dist/lib/sync-queue.js.map +1 -0
- package/dist/lib/types.d.ts +34 -0
- package/dist/lib/types.js +2 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utilities.d.ts +1127 -0
- package/dist/lib/utilities.js +1225 -0
- package/dist/lib/utilities.js.map +1 -0
- package/dist/utils/electron.d.ts +49 -0
- package/dist/utils/electron.js +63 -0
- package/dist/utils/electron.js.map +1 -0
- package/dist/utils/index.d.ts +4 -0
- package/dist/utils/index.js +5 -0
- package/dist/utils/index.js.map +1 -0
- package/install/check.js +121 -0
- package/install/ffmpeg.js +66 -0
- package/jellyfin-ffmpeg.patch +181 -0
- package/package.json +129 -0
|
@@ -0,0 +1,1088 @@
|
|
|
1
|
+
import { CodecContext } from '../lib/codec-context.js';
|
|
2
|
+
import { Codec } from '../lib/codec.js';
|
|
3
|
+
import { Frame } from '../lib/frame.js';
|
|
4
|
+
import { Packet } from '../lib/packet.js';
|
|
5
|
+
import { Scheduler } from './utilities/scheduler.js';
|
|
6
|
+
import type { AVCodecID, AVPixelFormat, AVThreadType, EOFSignal, FFDecoderCodec } from '../constants/index.js';
|
|
7
|
+
import type { Stream } from '../lib/stream.js';
|
|
8
|
+
import type { IRational } from '../lib/types.js';
|
|
9
|
+
import type { Encoder } from './encoder.js';
|
|
10
|
+
import type { FilterAPI } from './filter.js';
|
|
11
|
+
import type { HardwareContext } from './hardware.js';
|
|
12
|
+
/**
|
|
13
|
+
* Options for decoder creation.
|
|
14
|
+
*/
|
|
15
|
+
export interface DecoderOptions {
|
|
16
|
+
/**
|
|
17
|
+
* Exit immediately on first decode error.
|
|
18
|
+
*
|
|
19
|
+
* When enabled, the decoder will terminate on the first decode error.
|
|
20
|
+
* When disabled, errors are logged but decoding continues with next packet.
|
|
21
|
+
*
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
exitOnError?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Hardware acceleration context.
|
|
27
|
+
*
|
|
28
|
+
* Pass a HardwareContext instance to enable hardware-accelerated decoding.
|
|
29
|
+
* Set to null to disable hardware acceleration.
|
|
30
|
+
*/
|
|
31
|
+
hardware?: HardwareContext | null;
|
|
32
|
+
/**
|
|
33
|
+
* Number of extra hardware frames to allocate.
|
|
34
|
+
*
|
|
35
|
+
* Useful for hardware decoders requiring additional frame buffering.
|
|
36
|
+
* Some hardware decoders need extra frames for reference or look-ahead.
|
|
37
|
+
*/
|
|
38
|
+
extraHWFrames?: number;
|
|
39
|
+
/**
|
|
40
|
+
* Hardware frame output format.
|
|
41
|
+
*
|
|
42
|
+
* When set, hardware frames will be automatically transferred to this software pixel format.
|
|
43
|
+
* Useful when you need software frames for further processing but want to use hardware decoding.
|
|
44
|
+
*/
|
|
45
|
+
hwaccelOutputFormat?: AVPixelFormat;
|
|
46
|
+
/**
|
|
47
|
+
* Force constant framerate mode.
|
|
48
|
+
*
|
|
49
|
+
* When set, ignores all timestamps and generates frames at a constant rate.
|
|
50
|
+
* Sets frame PTS to AV_NOPTS_VALUE, duration to 1, and time_base to 1/framerate.
|
|
51
|
+
* Matches FFmpeg CLI's DECODER_FLAG_FRAMERATE_FORCED behavior.
|
|
52
|
+
*/
|
|
53
|
+
forcedFramerate?: IRational;
|
|
54
|
+
/**
|
|
55
|
+
* Override sample aspect ratio.
|
|
56
|
+
*
|
|
57
|
+
* When set, overrides the frame's sample_aspect_ratio with this value.
|
|
58
|
+
* Useful for fixing incorrect SAR in source material.
|
|
59
|
+
*/
|
|
60
|
+
sarOverride?: IRational;
|
|
61
|
+
/**
|
|
62
|
+
* Apply cropping from frame metadata.
|
|
63
|
+
*
|
|
64
|
+
* When true, automatically crops frames based on their crop metadata.
|
|
65
|
+
* Uses av_frame_apply_cropping() with AV_FRAME_CROP_UNALIGNED flag.
|
|
66
|
+
* Useful for streams with letterboxing/pillarboxing metadata.
|
|
67
|
+
*
|
|
68
|
+
* @default false
|
|
69
|
+
*/
|
|
70
|
+
applyCropping?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Number of threads to use for decoding.
|
|
73
|
+
*
|
|
74
|
+
* Set to 0 to auto-detect based on CPU cores.
|
|
75
|
+
*
|
|
76
|
+
* @default 1
|
|
77
|
+
*/
|
|
78
|
+
threadCount?: number;
|
|
79
|
+
/**
|
|
80
|
+
* Type of threading to use for decoding.
|
|
81
|
+
*
|
|
82
|
+
* - `FF_THREAD_FRAME` (1): Decode multiple frames in parallel.
|
|
83
|
+
* Higher throughput but adds latency (1 frame delay per thread).
|
|
84
|
+
* Not recommended for live streaming where future frames are unavailable.
|
|
85
|
+
*
|
|
86
|
+
* - `FF_THREAD_SLICE` (2): Decode parts of a single frame in parallel.
|
|
87
|
+
* No additional latency, suitable for real-time/live streaming.
|
|
88
|
+
*
|
|
89
|
+
* @default FFmpeg default (both methods, codec chooses best)
|
|
90
|
+
*/
|
|
91
|
+
threadType?: AVThreadType;
|
|
92
|
+
/**
|
|
93
|
+
* Additional codec-specific options.
|
|
94
|
+
*
|
|
95
|
+
* Key-value pairs of FFmpeg AVCodecContext options.
|
|
96
|
+
* These are passed directly to the decoder.
|
|
97
|
+
*/
|
|
98
|
+
options?: Record<string, string | number | boolean | undefined | null>;
|
|
99
|
+
/**
|
|
100
|
+
* AbortSignal for cancellation.
|
|
101
|
+
*
|
|
102
|
+
* When aborted, async generators stop yielding and async methods throw AbortError.
|
|
103
|
+
*/
|
|
104
|
+
signal?: AbortSignal;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* High-level decoder for audio and video streams.
|
|
108
|
+
*
|
|
109
|
+
* Provides a simplified interface for decoding media streams from packets to frames.
|
|
110
|
+
* Handles codec initialization, hardware acceleration setup, and frame management.
|
|
111
|
+
* Supports both synchronous packet-by-packet decoding and async iteration over frames.
|
|
112
|
+
* Essential component in media processing pipelines for converting compressed data to raw frames.
|
|
113
|
+
*
|
|
114
|
+
* @example
|
|
115
|
+
* ```typescript
|
|
116
|
+
* import { Demuxer, Decoder } from 'node-av/api';
|
|
117
|
+
*
|
|
118
|
+
* // Open media and create decoder
|
|
119
|
+
* await using input = await Demuxer.open('video.mp4');
|
|
120
|
+
* using decoder = await Decoder.create(input.video());
|
|
121
|
+
*
|
|
122
|
+
* // Decode frames
|
|
123
|
+
* for await (const frame of decoder.frames(input.packets())) {
|
|
124
|
+
* console.log(`Decoded frame: ${frame.width}x${frame.height}`);
|
|
125
|
+
* frame.free();
|
|
126
|
+
* }
|
|
127
|
+
* ```
|
|
128
|
+
*
|
|
129
|
+
* @example
|
|
130
|
+
* ```typescript
|
|
131
|
+
* import { HardwareContext } from 'node-av/api';
|
|
132
|
+
* import { AV_HWDEVICE_TYPE_CUDA } from 'node-av/constants';
|
|
133
|
+
*
|
|
134
|
+
* // Setup hardware acceleration
|
|
135
|
+
* const hw = HardwareContext.create(AV_HWDEVICE_TYPE_CUDA);
|
|
136
|
+
* using decoder = await Decoder.create(stream, { hardware: hw });
|
|
137
|
+
*
|
|
138
|
+
* // Frames will be decoded on GPU
|
|
139
|
+
* for await (const frame of decoder.frames(packets)) {
|
|
140
|
+
* // frame.hwFramesCtx contains GPU memory reference
|
|
141
|
+
* }
|
|
142
|
+
* ```
|
|
143
|
+
*
|
|
144
|
+
* @see {@link Encoder} For encoding frames to packets
|
|
145
|
+
* @see {@link Demuxer} For reading media files
|
|
146
|
+
* @see {@link HardwareContext} For GPU acceleration
|
|
147
|
+
*/
|
|
148
|
+
export declare class Decoder implements Disposable {
|
|
149
|
+
private codecContext;
|
|
150
|
+
private codec;
|
|
151
|
+
private frame;
|
|
152
|
+
private stream;
|
|
153
|
+
private initialized;
|
|
154
|
+
private isClosed;
|
|
155
|
+
private options;
|
|
156
|
+
private lastFramePts;
|
|
157
|
+
private lastFrameDurationEst;
|
|
158
|
+
private lastFrameTb;
|
|
159
|
+
private lastFrameSampleRate;
|
|
160
|
+
private lastFilterInRescaleDelta;
|
|
161
|
+
private inputQueue;
|
|
162
|
+
private outputQueue;
|
|
163
|
+
private workerPromise;
|
|
164
|
+
private nextComponent;
|
|
165
|
+
private pipeToPromise;
|
|
166
|
+
private signal?;
|
|
167
|
+
/**
|
|
168
|
+
* @param codecContext - Configured codec context
|
|
169
|
+
*
|
|
170
|
+
* @param codec - Codec being used
|
|
171
|
+
*
|
|
172
|
+
* @param stream - Media stream being decoded
|
|
173
|
+
*
|
|
174
|
+
* @param options - Decoder options
|
|
175
|
+
*
|
|
176
|
+
* Use {@link create} factory method
|
|
177
|
+
*
|
|
178
|
+
* @internal
|
|
179
|
+
*/
|
|
180
|
+
private constructor();
|
|
181
|
+
/**
|
|
182
|
+
* Create a decoder for a media stream.
|
|
183
|
+
*
|
|
184
|
+
* Initializes a decoder with the appropriate codec and configuration.
|
|
185
|
+
* Automatically detects and configures hardware acceleration if provided.
|
|
186
|
+
* Applies custom codec options and threading configuration.
|
|
187
|
+
*
|
|
188
|
+
* @param stream - Media stream to decode
|
|
189
|
+
*
|
|
190
|
+
* @param options - Decoder configuration options
|
|
191
|
+
*
|
|
192
|
+
* @returns Configured decoder instance
|
|
193
|
+
*
|
|
194
|
+
* @throws {FFmpegError} If codec initialization fails
|
|
195
|
+
*
|
|
196
|
+
* @example
|
|
197
|
+
* ```typescript
|
|
198
|
+
* import { Demuxer, Decoder } from 'node-av/api';
|
|
199
|
+
*
|
|
200
|
+
* await using input = await Demuxer.open('video.mp4');
|
|
201
|
+
* using decoder = await Decoder.create(input.video());
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* @example
|
|
205
|
+
* ```typescript
|
|
206
|
+
* using decoder = await Decoder.create(stream, {
|
|
207
|
+
* threads: 4,
|
|
208
|
+
* options: {
|
|
209
|
+
* 'refcounted_frames': '1',
|
|
210
|
+
* 'skip_frame': 'nonkey' // Only decode keyframes
|
|
211
|
+
* }
|
|
212
|
+
* });
|
|
213
|
+
* ```
|
|
214
|
+
*
|
|
215
|
+
* @example
|
|
216
|
+
* ```typescript
|
|
217
|
+
* const hw = HardwareContext.auto();
|
|
218
|
+
* using decoder = await Decoder.create(stream, {
|
|
219
|
+
* hardware: hw,
|
|
220
|
+
* threads: 0 // Auto-detect thread count
|
|
221
|
+
* exitOnError: false // Continue on decode errors (default: true)
|
|
222
|
+
* });
|
|
223
|
+
* ```
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```typescript
|
|
227
|
+
* using decoder = await Decoder.create(stream, FF_DECODER_H264_AMF, {
|
|
228
|
+
* hardware: hw,
|
|
229
|
+
* threads: 2,
|
|
230
|
+
* });
|
|
231
|
+
* ```
|
|
232
|
+
*
|
|
233
|
+
* @see {@link HardwareContext} For GPU acceleration setup
|
|
234
|
+
* @see {@link DecoderOptions} For configuration options
|
|
235
|
+
* @see {@link createSync} For synchronous version
|
|
236
|
+
*/
|
|
237
|
+
static create(stream: Stream, options?: DecoderOptions): Promise<Decoder>;
|
|
238
|
+
static create(stream: Stream, decoderCodec?: FFDecoderCodec | AVCodecID | Codec, options?: DecoderOptions): Promise<Decoder>;
|
|
239
|
+
/**
|
|
240
|
+
* Create a decoder for a media stream synchronously.
|
|
241
|
+
* Synchronous version of create.
|
|
242
|
+
*
|
|
243
|
+
* Initializes a decoder with the appropriate codec and configuration.
|
|
244
|
+
* Automatically detects and configures hardware acceleration if provided.
|
|
245
|
+
* Applies custom codec options and threading configuration.
|
|
246
|
+
*
|
|
247
|
+
* @param stream - Media stream to decode
|
|
248
|
+
*
|
|
249
|
+
* @param options - Decoder configuration options
|
|
250
|
+
*
|
|
251
|
+
* @returns Configured decoder instance
|
|
252
|
+
*
|
|
253
|
+
* @throws {FFmpegError} If codec initialization fails
|
|
254
|
+
*
|
|
255
|
+
* @example
|
|
256
|
+
* ```typescript
|
|
257
|
+
* import { Demuxer, Decoder } from 'node-av/api';
|
|
258
|
+
*
|
|
259
|
+
* await using input = await Demuxer.open('video.mp4');
|
|
260
|
+
* using decoder = Decoder.createSync(input.video());
|
|
261
|
+
* ```
|
|
262
|
+
*
|
|
263
|
+
* @example
|
|
264
|
+
* ```typescript
|
|
265
|
+
* using decoder = Decoder.createSync(stream, {
|
|
266
|
+
* threads: 4,
|
|
267
|
+
* options: {
|
|
268
|
+
* 'refcounted_frames': '1',
|
|
269
|
+
* 'skip_frame': 'nonkey' // Only decode keyframes
|
|
270
|
+
* }
|
|
271
|
+
* });
|
|
272
|
+
* ```
|
|
273
|
+
*
|
|
274
|
+
* @example
|
|
275
|
+
* ```typescript
|
|
276
|
+
* const hw = HardwareContext.auto();
|
|
277
|
+
* using decoder = Decoder.createSync(stream, {
|
|
278
|
+
* hardware: hw,
|
|
279
|
+
* threads: 0 // Auto-detect thread count
|
|
280
|
+
* });
|
|
281
|
+
* ```
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```typescript
|
|
285
|
+
* using decoder = Decoder.createSync(stream, FF_DECODER_H264_NVDEC, {
|
|
286
|
+
* hardware: hw
|
|
287
|
+
* });
|
|
288
|
+
* ```
|
|
289
|
+
*
|
|
290
|
+
* @see {@link HardwareContext} For GPU acceleration setup
|
|
291
|
+
* @see {@link DecoderOptions} For configuration options
|
|
292
|
+
* @see {@link create} For async version
|
|
293
|
+
*/
|
|
294
|
+
static createSync(stream: Stream, options?: DecoderOptions): Decoder;
|
|
295
|
+
static createSync(stream: Stream, decoderCodec?: FFDecoderCodec | AVCodecID | Codec, options?: DecoderOptions): Decoder;
|
|
296
|
+
/**
|
|
297
|
+
* Check if decoder is open.
|
|
298
|
+
*
|
|
299
|
+
* @returns true if decoder is open and ready
|
|
300
|
+
*
|
|
301
|
+
* @example
|
|
302
|
+
* ```typescript
|
|
303
|
+
* if (decoder.isDecoderOpen) {
|
|
304
|
+
* const frame = await decoder.decode(packet);
|
|
305
|
+
* }
|
|
306
|
+
* ```
|
|
307
|
+
*/
|
|
308
|
+
get isDecoderOpen(): boolean;
|
|
309
|
+
/**
|
|
310
|
+
* Check if decoder has been initialized.
|
|
311
|
+
*
|
|
312
|
+
* Returns true if decoder is initialized (true by default for decoders).
|
|
313
|
+
* Decoders are pre-initialized from stream parameters.
|
|
314
|
+
*
|
|
315
|
+
* @returns true if decoder has been initialized
|
|
316
|
+
*
|
|
317
|
+
* @example
|
|
318
|
+
* ```typescript
|
|
319
|
+
* if (decoder.isDecoderInitialized) {
|
|
320
|
+
* console.log('Decoder is ready to process frames');
|
|
321
|
+
* }
|
|
322
|
+
* ```
|
|
323
|
+
*/
|
|
324
|
+
get isDecoderInitialized(): boolean;
|
|
325
|
+
/**
|
|
326
|
+
* Check if decoder uses hardware acceleration.
|
|
327
|
+
*
|
|
328
|
+
* @returns true if hardware-accelerated
|
|
329
|
+
*
|
|
330
|
+
* @example
|
|
331
|
+
* ```typescript
|
|
332
|
+
* if (decoder.isHardware()) {
|
|
333
|
+
* console.log('Using GPU acceleration');
|
|
334
|
+
* }
|
|
335
|
+
* ```
|
|
336
|
+
*
|
|
337
|
+
* @see {@link HardwareContext} For hardware setup
|
|
338
|
+
*/
|
|
339
|
+
isHardware(): boolean;
|
|
340
|
+
/**
|
|
341
|
+
* Check if decoder is ready for processing.
|
|
342
|
+
*
|
|
343
|
+
* @returns true if initialized and ready
|
|
344
|
+
*
|
|
345
|
+
* @example
|
|
346
|
+
* ```typescript
|
|
347
|
+
* if (decoder.isReady()) {
|
|
348
|
+
* const frame = await decoder.decode(packet);
|
|
349
|
+
* }
|
|
350
|
+
* ```
|
|
351
|
+
*/
|
|
352
|
+
isReady(): boolean;
|
|
353
|
+
/**
|
|
354
|
+
* Send a packet to the decoder.
|
|
355
|
+
*
|
|
356
|
+
* Sends a compressed packet to the decoder for decoding.
|
|
357
|
+
* Does not return decoded frames - use {@link receive} to retrieve frames.
|
|
358
|
+
* A single packet can produce zero, one, or multiple frames depending on codec buffering.
|
|
359
|
+
* Automatically manages decoder state and error recovery.
|
|
360
|
+
*
|
|
361
|
+
* **Important**: This method only SENDS the packet to the decoder.
|
|
362
|
+
* You must call {@link receive} separately (potentially multiple times) to get decoded frames.
|
|
363
|
+
*
|
|
364
|
+
* Direct mapping to avcodec_send_packet().
|
|
365
|
+
*
|
|
366
|
+
* @param packet - Compressed packet to send to decoder, or null to flush
|
|
367
|
+
*
|
|
368
|
+
* @throws {FFmpegError} If sending packet fails
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```typescript
|
|
372
|
+
* // Send packet and receive frames
|
|
373
|
+
* await decoder.decode(packet);
|
|
374
|
+
*
|
|
375
|
+
* // Receive all available frames
|
|
376
|
+
* while (true) {
|
|
377
|
+
* const frame = await decoder.receive();
|
|
378
|
+
* if (!frame) break;
|
|
379
|
+
* console.log(`Decoded frame with PTS: ${frame.pts}`);
|
|
380
|
+
* frame.free();
|
|
381
|
+
* }
|
|
382
|
+
* ```
|
|
383
|
+
*
|
|
384
|
+
* @example
|
|
385
|
+
* ```typescript
|
|
386
|
+
* for await (const packet of input.packets()) {
|
|
387
|
+
* // packet is null at end of stream - automatically flushes decoder
|
|
388
|
+
* await decoder.decode(packet);
|
|
389
|
+
*
|
|
390
|
+
* // Receive available frames
|
|
391
|
+
* let frame;
|
|
392
|
+
* while ((frame = await decoder.receive())) {
|
|
393
|
+
* await processFrame(frame);
|
|
394
|
+
* frame.free();
|
|
395
|
+
* }
|
|
396
|
+
* }
|
|
397
|
+
* ```
|
|
398
|
+
*
|
|
399
|
+
* @see {@link receive} For receiving decoded frames
|
|
400
|
+
* @see {@link decodeAll} For combined send+receive operation
|
|
401
|
+
* @see {@link frames} For automatic packet iteration
|
|
402
|
+
* @see {@link flush} For end-of-stream handling
|
|
403
|
+
* @see {@link decodeSync} For synchronous version
|
|
404
|
+
*/
|
|
405
|
+
decode(packet: Packet | null): Promise<void>;
|
|
406
|
+
/**
|
|
407
|
+
* Send a packet to the decoder synchronously.
|
|
408
|
+
* Synchronous version of decode.
|
|
409
|
+
*
|
|
410
|
+
* Sends a compressed packet to the decoder for decoding.
|
|
411
|
+
* Does not return decoded frames - use {@link receiveSync} to retrieve frames.
|
|
412
|
+
* A single packet can produce zero, one, or multiple frames depending on codec buffering.
|
|
413
|
+
* Automatically manages decoder state and error recovery.
|
|
414
|
+
*
|
|
415
|
+
* **Important**: This method only SENDS the packet to the decoder.
|
|
416
|
+
* You must call {@link receiveSync} separately (potentially multiple times) to get decoded frames.
|
|
417
|
+
*
|
|
418
|
+
* Direct mapping to avcodec_send_packet().
|
|
419
|
+
*
|
|
420
|
+
* @param packet - Compressed packet to send to decoder, or null to flush
|
|
421
|
+
*
|
|
422
|
+
* @throws {FFmpegError} If sending packet fails
|
|
423
|
+
*
|
|
424
|
+
* @example
|
|
425
|
+
* ```typescript
|
|
426
|
+
* // Send packet and receive frames
|
|
427
|
+
* decoder.decodeSync(packet);
|
|
428
|
+
*
|
|
429
|
+
* // Receive all available frames
|
|
430
|
+
* while (true) {
|
|
431
|
+
* const frame = decoder.receiveSync();
|
|
432
|
+
* if (!frame) break;
|
|
433
|
+
* console.log(`Decoded frame with PTS: ${frame.pts}`);
|
|
434
|
+
* frame.free();
|
|
435
|
+
* }
|
|
436
|
+
* ```
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* ```typescript
|
|
440
|
+
* for (const packet of input.packetsSync()) {
|
|
441
|
+
* // packet is null at end of stream - automatically flushes decoder
|
|
442
|
+
* decoder.decodeSync(packet);
|
|
443
|
+
*
|
|
444
|
+
* // Receive available frames
|
|
445
|
+
* let frame;
|
|
446
|
+
* while ((frame = decoder.receiveSync())) {
|
|
447
|
+
* processFrame(frame);
|
|
448
|
+
* frame.free();
|
|
449
|
+
* }
|
|
450
|
+
* }
|
|
451
|
+
* ```
|
|
452
|
+
*
|
|
453
|
+
* @see {@link receiveSync} For receiving decoded frames
|
|
454
|
+
* @see {@link decodeAllSync} For combined send+receive operation
|
|
455
|
+
* @see {@link framesSync} For automatic packet iteration
|
|
456
|
+
* @see {@link flushSync} For end-of-stream handling
|
|
457
|
+
* @see {@link decode} For async version
|
|
458
|
+
*/
|
|
459
|
+
decodeSync(packet: Packet | null): void;
|
|
460
|
+
/**
|
|
461
|
+
* Decode a packet to frames.
|
|
462
|
+
*
|
|
463
|
+
* Sends a packet to the decoder and receives all available decoded frames.
|
|
464
|
+
* Returns array of frames - may be empty if decoder needs more data.
|
|
465
|
+
* One packet can produce zero, one, or multiple frames depending on codec.
|
|
466
|
+
* Automatically manages decoder state and error recovery.
|
|
467
|
+
*
|
|
468
|
+
* Direct mapping to avcodec_send_packet() and avcodec_receive_frame().
|
|
469
|
+
*
|
|
470
|
+
* @param packet - Compressed packet to decode
|
|
471
|
+
*
|
|
472
|
+
* @returns Array of decoded frames (empty if more data needed or decoder is closed)
|
|
473
|
+
*
|
|
474
|
+
* @throws {FFmpegError} If decoding fails
|
|
475
|
+
*
|
|
476
|
+
* @example
|
|
477
|
+
* ```typescript
|
|
478
|
+
* const frames = await decoder.decodeAll(packet);
|
|
479
|
+
* for (const frame of frames) {
|
|
480
|
+
* console.log(`Decoded frame with PTS: ${frame.pts}`);
|
|
481
|
+
* frame.free();
|
|
482
|
+
* }
|
|
483
|
+
* ```
|
|
484
|
+
*
|
|
485
|
+
* @example
|
|
486
|
+
* ```typescript
|
|
487
|
+
* for await (const packet of input.packets()) {
|
|
488
|
+
* const frames = await decoder.decodeAll(packet);
|
|
489
|
+
* for (const frame of frames) {
|
|
490
|
+
* await processFrame(frame);
|
|
491
|
+
* frame.free();
|
|
492
|
+
* }
|
|
493
|
+
* packet.free();
|
|
494
|
+
* }
|
|
495
|
+
* ```
|
|
496
|
+
*
|
|
497
|
+
* @see {@link decode} For single packet decoding
|
|
498
|
+
* @see {@link frames} For automatic packet iteration
|
|
499
|
+
* @see {@link flush} For end-of-stream handling
|
|
500
|
+
* @see {@link decodeAllSync} For synchronous version
|
|
501
|
+
*/
|
|
502
|
+
decodeAll(packet: Packet | null): Promise<Frame[]>;
|
|
503
|
+
/**
|
|
504
|
+
* Decode a packet to frames synchronously.
|
|
505
|
+
* Synchronous version of decodeAll.
|
|
506
|
+
*
|
|
507
|
+
* Sends packet to decoder and receives all available decoded frames.
|
|
508
|
+
* Returns array of frames - may be empty if decoder needs more data.
|
|
509
|
+
* One packet can produce zero, one, or multiple frames depending on codec.
|
|
510
|
+
*
|
|
511
|
+
* @param packet - Compressed packet to decode
|
|
512
|
+
*
|
|
513
|
+
* @returns Array of decoded frames (empty if more data needed or decoder is closed)
|
|
514
|
+
*
|
|
515
|
+
* @throws {FFmpegError} If decoding fails
|
|
516
|
+
*
|
|
517
|
+
* @example
|
|
518
|
+
* ```typescript
|
|
519
|
+
* const frames = decoder.decodeAllSync(packet);
|
|
520
|
+
* for (const frame of frames) {
|
|
521
|
+
* console.log(`Decoded: ${frame.width}x${frame.height}`);
|
|
522
|
+
* frame.free();
|
|
523
|
+
* }
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* for (const packet of input.packetsSync()) {
|
|
528
|
+
* const frames = await decoder.decodeAllSync(packet);
|
|
529
|
+
* for (const frame of frames) {
|
|
530
|
+
* processFrame(frame);
|
|
531
|
+
* frame.free();
|
|
532
|
+
* }
|
|
533
|
+
* packet.free();
|
|
534
|
+
* }
|
|
535
|
+
* ```
|
|
536
|
+
*
|
|
537
|
+
* @see {@link decodeSync} For single packet decoding
|
|
538
|
+
* @see {@link framesSync} For automatic packet iteration
|
|
539
|
+
* @see {@link flushSync} For end-of-stream handling
|
|
540
|
+
* @see {@link decodeAll} For async version
|
|
541
|
+
*/
|
|
542
|
+
decodeAllSync(packet: Packet | null): Frame[];
|
|
543
|
+
/**
|
|
544
|
+
* Decode packet stream to frame stream.
|
|
545
|
+
*
|
|
546
|
+
* High-level async generator for complete decoding pipeline.
|
|
547
|
+
* Decoder is only flushed when EOF (null) signal is explicitly received.
|
|
548
|
+
* Primary interface for stream-based decoding.
|
|
549
|
+
*
|
|
550
|
+
* **EOF Handling:**
|
|
551
|
+
* - Send null to flush decoder and get remaining buffered frames
|
|
552
|
+
* - Generator yields null after flushing when null is received
|
|
553
|
+
* - No automatic flushing - decoder stays open until EOF or close()
|
|
554
|
+
*
|
|
555
|
+
* @param packets - Async iterable of packets, single packet, or null to flush
|
|
556
|
+
*
|
|
557
|
+
* @yields {Frame | null} Decoded frames, followed by null when explicitly flushed
|
|
558
|
+
*
|
|
559
|
+
* @throws {Error} If decoder is closed
|
|
560
|
+
*
|
|
561
|
+
* @throws {FFmpegError} If decoding fails
|
|
562
|
+
*
|
|
563
|
+
* @example
|
|
564
|
+
* ```typescript
|
|
565
|
+
* // Stream of packets with automatic EOF propagation
|
|
566
|
+
* await using input = await Demuxer.open('video.mp4');
|
|
567
|
+
* using decoder = await Decoder.create(input.video());
|
|
568
|
+
*
|
|
569
|
+
* for await (const frame of decoder.frames(input.packets())) {
|
|
570
|
+
* if (frame === null) {
|
|
571
|
+
* console.log('Decoding complete');
|
|
572
|
+
* break;
|
|
573
|
+
* }
|
|
574
|
+
* console.log(`Frame: ${frame.width}x${frame.height}`);
|
|
575
|
+
* frame.free();
|
|
576
|
+
* }
|
|
577
|
+
* ```
|
|
578
|
+
*
|
|
579
|
+
* @example
|
|
580
|
+
* ```typescript
|
|
581
|
+
* // Single packet (no automatic flush)
|
|
582
|
+
* for await (const frame of decoder.frames(singlePacket)) {
|
|
583
|
+
* await encoder.encode(frame);
|
|
584
|
+
* frame.free();
|
|
585
|
+
* }
|
|
586
|
+
* // Decoder still has buffered frames - send null to flush
|
|
587
|
+
* for await (const frame of decoder.frames(null)) {
|
|
588
|
+
* if (frame === null) break;
|
|
589
|
+
* await encoder.encode(frame);
|
|
590
|
+
* frame.free();
|
|
591
|
+
* }
|
|
592
|
+
* ```
|
|
593
|
+
*
|
|
594
|
+
* @example
|
|
595
|
+
* ```typescript
|
|
596
|
+
* // Explicit flush with EOF
|
|
597
|
+
* for await (const frame of decoder.frames(null)) {
|
|
598
|
+
* if (frame === null) {
|
|
599
|
+
* console.log('All buffered frames flushed');
|
|
600
|
+
* break;
|
|
601
|
+
* }
|
|
602
|
+
* console.log('Buffered frame:', frame.pts);
|
|
603
|
+
* frame.free();
|
|
604
|
+
* }
|
|
605
|
+
* ```
|
|
606
|
+
*
|
|
607
|
+
* @see {@link decode} For single packet decoding
|
|
608
|
+
* @see {@link Demuxer.packets} For packet source
|
|
609
|
+
* @see {@link framesSync} For sync version
|
|
610
|
+
*/
|
|
611
|
+
frames(packets: AsyncIterable<Packet | null> | Packet | null): AsyncGenerator<Frame | null>;
|
|
612
|
+
/**
|
|
613
|
+
* Decode packet stream to frame stream synchronously.
|
|
614
|
+
* Synchronous version of frames.
|
|
615
|
+
*
|
|
616
|
+
* High-level async generator for complete decoding pipeline.
|
|
617
|
+
* Decoder is only flushed when EOF (null) signal is explicitly received.
|
|
618
|
+
* Primary interface for stream-based decoding.
|
|
619
|
+
*
|
|
620
|
+
* **EOF Handling:**
|
|
621
|
+
* - Send null to flush decoder and get remaining buffered frames
|
|
622
|
+
* - Generator yields null after flushing when null is received
|
|
623
|
+
* - No automatic flushing - decoder stays open until EOF or close()
|
|
624
|
+
*
|
|
625
|
+
* @param packets - Iterable of packets, single packet, or null to flush
|
|
626
|
+
*
|
|
627
|
+
* @yields {Frame | null} Decoded frames, followed by null when explicitly flushed
|
|
628
|
+
*
|
|
629
|
+
* @throws {Error} If decoder is closed
|
|
630
|
+
*
|
|
631
|
+
* @throws {FFmpegError} If decoding fails
|
|
632
|
+
*
|
|
633
|
+
* @example
|
|
634
|
+
* ```typescript
|
|
635
|
+
* // Stream of packets with automatic EOF propagation
|
|
636
|
+
* await using input = await Demuxer.open('video.mp4');
|
|
637
|
+
* using decoder = await Decoder.create(input.video());
|
|
638
|
+
*
|
|
639
|
+
* for (const frame of decoder.framesSync(input.packetsSync())) {
|
|
640
|
+
* if (frame === null) {
|
|
641
|
+
* console.log('Decoding complete');
|
|
642
|
+
* break;
|
|
643
|
+
* }
|
|
644
|
+
* console.log(`Frame: ${frame.width}x${frame.height}`);
|
|
645
|
+
* frame.free();
|
|
646
|
+
* }
|
|
647
|
+
* ```
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* ```typescript
|
|
651
|
+
* // Single packet (no automatic flush)
|
|
652
|
+
* for (const frame of decoder.framesSync(singlePacket)) {
|
|
653
|
+
* encoder.encodeSync(frame);
|
|
654
|
+
* frame.free();
|
|
655
|
+
* }
|
|
656
|
+
* // Decoder still has buffered frames - send null to flush
|
|
657
|
+
* for (const frame of decoder.framesSync(null)) {
|
|
658
|
+
* if (frame === null) break;
|
|
659
|
+
* encoder.encodeSync(frame);
|
|
660
|
+
* frame.free();
|
|
661
|
+
* }
|
|
662
|
+
* ```
|
|
663
|
+
*
|
|
664
|
+
* @example
|
|
665
|
+
* ```typescript
|
|
666
|
+
* // Explicit flush with EOF
|
|
667
|
+
* for (const frame of decoder.framesSync(null)) {
|
|
668
|
+
* if (frame === null) {
|
|
669
|
+
* console.log('All buffered frames flushed');
|
|
670
|
+
* break;
|
|
671
|
+
* }
|
|
672
|
+
* console.log('Buffered frame:', frame.pts);
|
|
673
|
+
* frame.free();
|
|
674
|
+
* }
|
|
675
|
+
* ```
|
|
676
|
+
*/
|
|
677
|
+
framesSync(packets: Iterable<Packet | null> | Packet | null): Generator<Frame | null>;
|
|
678
|
+
/**
|
|
679
|
+
* Flush decoder and signal end-of-stream.
|
|
680
|
+
*
|
|
681
|
+
* Sends null packet to decoder to signal end-of-stream.
|
|
682
|
+
* Does nothing if decoder is closed.
|
|
683
|
+
* Must use receive() or flushFrames() to get remaining buffered frames.
|
|
684
|
+
*
|
|
685
|
+
* Direct mapping to avcodec_send_packet(NULL).
|
|
686
|
+
*
|
|
687
|
+
* @throws {FFmpegError} If flush fails
|
|
688
|
+
*
|
|
689
|
+
* @example
|
|
690
|
+
* ```typescript
|
|
691
|
+
* // Signal end of stream
|
|
692
|
+
* await decoder.flush();
|
|
693
|
+
*
|
|
694
|
+
* // Then get remaining frames
|
|
695
|
+
* let frame;
|
|
696
|
+
* while ((frame = await decoder.receive()) !== null) {
|
|
697
|
+
* console.log('Got buffered frame');
|
|
698
|
+
* frame.free();
|
|
699
|
+
* }
|
|
700
|
+
* ```
|
|
701
|
+
*
|
|
702
|
+
* @see {@link flushFrames} For convenient async iteration
|
|
703
|
+
* @see {@link receive} For getting buffered frames
|
|
704
|
+
* @see {@link flushSync} For synchronous version
|
|
705
|
+
*/
|
|
706
|
+
flush(): Promise<void>;
|
|
707
|
+
/**
|
|
708
|
+
* Flush decoder and signal end-of-stream synchronously.
|
|
709
|
+
* Synchronous version of flush.
|
|
710
|
+
*
|
|
711
|
+
* Send null packet to signal end of input stream.
|
|
712
|
+
* Decoder may still have buffered frames.
|
|
713
|
+
* Call receiveSync() repeatedly to get remaining frames.
|
|
714
|
+
*
|
|
715
|
+
* @throws {FFmpegError} If flush fails
|
|
716
|
+
*
|
|
717
|
+
* @example
|
|
718
|
+
* ```typescript
|
|
719
|
+
* decoder.flushSync();
|
|
720
|
+
* // Get remaining frames
|
|
721
|
+
* let frame;
|
|
722
|
+
* while ((frame = decoder.receiveSync()) !== null) {
|
|
723
|
+
* console.log('Buffered frame');
|
|
724
|
+
* }
|
|
725
|
+
* ```
|
|
726
|
+
*
|
|
727
|
+
* @see {@link flushFramesSync} For convenient sync iteration
|
|
728
|
+
* @see {@link receiveSync} For getting buffered frames
|
|
729
|
+
* @see {@link flush} For async version
|
|
730
|
+
*/
|
|
731
|
+
flushSync(): void;
|
|
732
|
+
/**
|
|
733
|
+
* Flush all buffered frames as async generator.
|
|
734
|
+
*
|
|
735
|
+
* Convenient async iteration over remaining frames.
|
|
736
|
+
* Automatically sends flush signal and retrieves buffered frames.
|
|
737
|
+
* Useful for end-of-stream processing.
|
|
738
|
+
*
|
|
739
|
+
* @yields {Frame} Buffered frames
|
|
740
|
+
*
|
|
741
|
+
* @example
|
|
742
|
+
* ```typescript
|
|
743
|
+
* // Flush at end of decoding
|
|
744
|
+
* for await (const frame of decoder.flushFrames()) {
|
|
745
|
+
* console.log('Processing buffered frame');
|
|
746
|
+
* await encoder.encode(frame);
|
|
747
|
+
* frame.free();
|
|
748
|
+
* }
|
|
749
|
+
* ```
|
|
750
|
+
*
|
|
751
|
+
* @see {@link decode} For sending packets and receiving frames
|
|
752
|
+
* @see {@link flush} For signaling end-of-stream
|
|
753
|
+
* @see {@link flushFramesSync} For synchronous version
|
|
754
|
+
*/
|
|
755
|
+
flushFrames(): AsyncGenerator<Frame>;
|
|
756
|
+
/**
|
|
757
|
+
* Flush all buffered frames as generator synchronously.
|
|
758
|
+
* Synchronous version of flushFrames.
|
|
759
|
+
*
|
|
760
|
+
* Convenient sync iteration over remaining frames.
|
|
761
|
+
* Automatically sends flush signal and retrieves buffered frames.
|
|
762
|
+
* Useful for end-of-stream processing.
|
|
763
|
+
*
|
|
764
|
+
* @yields {Frame} Buffered frames
|
|
765
|
+
*
|
|
766
|
+
* @example
|
|
767
|
+
* ```typescript
|
|
768
|
+
* // Flush at end of decoding
|
|
769
|
+
* for (const frame of decoder.flushFramesSync()) {
|
|
770
|
+
* console.log('Processing buffered frame');
|
|
771
|
+
* encoder.encodeSync(frame);
|
|
772
|
+
* frame.free();
|
|
773
|
+
* }
|
|
774
|
+
* ```
|
|
775
|
+
*
|
|
776
|
+
* @see {@link decodeSync} For sending packets and receiving frames
|
|
777
|
+
* @see {@link flushSync} For signaling end-of-stream
|
|
778
|
+
* @see {@link flushFrames} For async version
|
|
779
|
+
*/
|
|
780
|
+
flushFramesSync(): Generator<Frame>;
|
|
781
|
+
/**
|
|
782
|
+
* Receive frame from decoder.
|
|
783
|
+
*
|
|
784
|
+
* Gets decoded frames from the codec's internal buffer.
|
|
785
|
+
* Handles frame cloning and error checking.
|
|
786
|
+
* Hardware frames include hw_frames_ctx reference.
|
|
787
|
+
* Call repeatedly to drain all buffered frames.
|
|
788
|
+
*
|
|
789
|
+
* **Return Values:**
|
|
790
|
+
* - `Frame` - Successfully decoded frame
|
|
791
|
+
* - `null` - No frame available (AVERROR_EAGAIN), send more packets
|
|
792
|
+
* - `undefined` - End of stream reached (AVERROR_EOF), decoder flushed
|
|
793
|
+
*
|
|
794
|
+
* Direct mapping to avcodec_receive_frame().
|
|
795
|
+
*
|
|
796
|
+
* @returns Decoded frame, null (need more data), or undefined (end of stream)
|
|
797
|
+
*
|
|
798
|
+
* @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
|
|
799
|
+
*
|
|
800
|
+
* @throws {Error} If frame cloning fails (out of memory)
|
|
801
|
+
*
|
|
802
|
+
* @example
|
|
803
|
+
* ```typescript
|
|
804
|
+
* const frame = await decoder.receive();
|
|
805
|
+
* if (frame === EOF) {
|
|
806
|
+
* console.log('Decoder flushed, no more frames');
|
|
807
|
+
* } else if (frame) {
|
|
808
|
+
* console.log('Got decoded frame');
|
|
809
|
+
* frame.free();
|
|
810
|
+
* } else {
|
|
811
|
+
* console.log('Need more packets');
|
|
812
|
+
* }
|
|
813
|
+
* ```
|
|
814
|
+
*
|
|
815
|
+
* @example
|
|
816
|
+
* ```typescript
|
|
817
|
+
* // Drain all buffered frames (stop on null or EOF)
|
|
818
|
+
* let frame;
|
|
819
|
+
* while ((frame = await decoder.receive()) && frame !== EOF) {
|
|
820
|
+
* console.log(`Frame PTS: ${frame.pts}`);
|
|
821
|
+
* frame.free();
|
|
822
|
+
* }
|
|
823
|
+
* ```
|
|
824
|
+
*
|
|
825
|
+
* @see {@link decode} For sending packets
|
|
826
|
+
* @see {@link flush} For signaling end-of-stream
|
|
827
|
+
* @see {@link receiveSync} For synchronous version
|
|
828
|
+
* @see {@link EOF} For end-of-stream signal
|
|
829
|
+
*/
|
|
830
|
+
receive(): Promise<Frame | EOFSignal | null>;
|
|
831
|
+
/**
|
|
832
|
+
* Receive frame from decoder synchronously.
|
|
833
|
+
* Synchronous version of receive.
|
|
834
|
+
*
|
|
835
|
+
* Gets decoded frames from the codec's internal buffer.
|
|
836
|
+
* Handles frame cloning and error checking.
|
|
837
|
+
* Hardware frames include hw_frames_ctx reference.
|
|
838
|
+
* Call repeatedly to drain all buffered frames.
|
|
839
|
+
*
|
|
840
|
+
* **Return Values:**
|
|
841
|
+
* - `Frame` - Successfully decoded frame
|
|
842
|
+
* - `null` - No frame available (AVERROR_EAGAIN), send more packets
|
|
843
|
+
* - `undefined` - End of stream reached (AVERROR_EOF), decoder flushed
|
|
844
|
+
*
|
|
845
|
+
* Direct mapping to avcodec_receive_frame().
|
|
846
|
+
*
|
|
847
|
+
* @returns Decoded frame, null (need more data), or undefined (end of stream)
|
|
848
|
+
*
|
|
849
|
+
* @throws {FFmpegError} If receive fails with error other than AVERROR_EAGAIN or AVERROR_EOF
|
|
850
|
+
*
|
|
851
|
+
* @throws {Error} If frame cloning fails (out of memory)
|
|
852
|
+
*
|
|
853
|
+
* @example
|
|
854
|
+
* ```typescript
|
|
855
|
+
* const frame = decoder.receiveSync();
|
|
856
|
+
* if (frame === EOF) {
|
|
857
|
+
* console.log('Decoder flushed, no more frames');
|
|
858
|
+
* } else if (frame) {
|
|
859
|
+
* console.log('Got decoded frame');
|
|
860
|
+
* frame.free();
|
|
861
|
+
* } else {
|
|
862
|
+
* console.log('Need more packets');
|
|
863
|
+
* }
|
|
864
|
+
* ```
|
|
865
|
+
*
|
|
866
|
+
* @example
|
|
867
|
+
* ```typescript
|
|
868
|
+
* // Drain all buffered frames (stop on null or EOF)
|
|
869
|
+
* let frame;
|
|
870
|
+
* while ((frame = decoder.receiveSync()) && frame !== EOF) {
|
|
871
|
+
* console.log(`Frame PTS: ${frame.pts}`);
|
|
872
|
+
* frame.free();
|
|
873
|
+
* }
|
|
874
|
+
* ```
|
|
875
|
+
*
|
|
876
|
+
* @see {@link decodeSync} For sending packets
|
|
877
|
+
* @see {@link flushSync} For signaling end-of-stream
|
|
878
|
+
* @see {@link receive} For async version
|
|
879
|
+
* @see {@link EOF} For end-of-stream signal
|
|
880
|
+
*/
|
|
881
|
+
receiveSync(): Frame | EOFSignal | null;
|
|
882
|
+
/**
|
|
883
|
+
* Pipe decoded frames to a filter component or encoder.
|
|
884
|
+
*
|
|
885
|
+
* @param target - Filter to receive frames or encoder to encode frames
|
|
886
|
+
*
|
|
887
|
+
* @returns Scheduler for continued chaining
|
|
888
|
+
*
|
|
889
|
+
* @example
|
|
890
|
+
* ```typescript
|
|
891
|
+
* decoder.pipeTo(filter).pipeTo(encoder)
|
|
892
|
+
* ```
|
|
893
|
+
*/
|
|
894
|
+
pipeTo(target: FilterAPI): Scheduler<Packet>;
|
|
895
|
+
pipeTo(target: Encoder): Scheduler<Packet>;
|
|
896
|
+
/**
|
|
897
|
+
* Close decoder and free resources.
|
|
898
|
+
*
|
|
899
|
+
* Releases codec context and internal frame buffer.
|
|
900
|
+
* Safe to call multiple times.
|
|
901
|
+
* Automatically called by Symbol.dispose.
|
|
902
|
+
*
|
|
903
|
+
* @example
|
|
904
|
+
* ```typescript
|
|
905
|
+
* const decoder = await Decoder.create(stream);
|
|
906
|
+
* try {
|
|
907
|
+
* // Use decoder
|
|
908
|
+
* } finally {
|
|
909
|
+
* decoder.close();
|
|
910
|
+
* }
|
|
911
|
+
* ```
|
|
912
|
+
*
|
|
913
|
+
* @see {@link Symbol.dispose} For automatic cleanup
|
|
914
|
+
*/
|
|
915
|
+
close(): void;
|
|
916
|
+
/**
|
|
917
|
+
* Get stream object.
|
|
918
|
+
*
|
|
919
|
+
* Returns the underlying stream being decoded.
|
|
920
|
+
* Provides access to stream metadata and parameters.
|
|
921
|
+
*
|
|
922
|
+
* @returns Stream object
|
|
923
|
+
*
|
|
924
|
+
* @internal
|
|
925
|
+
*
|
|
926
|
+
* @see {@link Stream} For stream details
|
|
927
|
+
*/
|
|
928
|
+
getStream(): Stream;
|
|
929
|
+
/**
|
|
930
|
+
* Get decoder codec.
|
|
931
|
+
*
|
|
932
|
+
* Returns the codec used by this decoder.
|
|
933
|
+
* Useful for checking codec capabilities and properties.
|
|
934
|
+
*
|
|
935
|
+
* @returns Codec instance
|
|
936
|
+
*
|
|
937
|
+
* @internal
|
|
938
|
+
*
|
|
939
|
+
* @see {@link Codec} For codec details
|
|
940
|
+
*/
|
|
941
|
+
getCodec(): Codec;
|
|
942
|
+
/**
|
|
943
|
+
* Get underlying codec context.
|
|
944
|
+
*
|
|
945
|
+
* Returns the codec context for advanced operations.
|
|
946
|
+
* Useful for accessing low-level codec properties and settings.
|
|
947
|
+
* Returns null if decoder is closed.
|
|
948
|
+
*
|
|
949
|
+
* @returns Codec context or null if closed
|
|
950
|
+
*
|
|
951
|
+
* @internal
|
|
952
|
+
*
|
|
953
|
+
* @see {@link CodecContext} For context details
|
|
954
|
+
*/
|
|
955
|
+
getCodecContext(): CodecContext | null;
|
|
956
|
+
/**
|
|
957
|
+
* Worker loop for push-based processing.
|
|
958
|
+
*
|
|
959
|
+
* @internal
|
|
960
|
+
*/
|
|
961
|
+
private runWorker;
|
|
962
|
+
/**
|
|
963
|
+
* Send packet to input queue or flush the pipeline.
|
|
964
|
+
*
|
|
965
|
+
* When packet is provided, queues it for processing.
|
|
966
|
+
* When null is provided, triggers flush sequence:
|
|
967
|
+
* - Closes input queue
|
|
968
|
+
* - Waits for worker completion
|
|
969
|
+
* - Flushes decoder and sends remaining frames to output queue
|
|
970
|
+
* - Closes output queue
|
|
971
|
+
* - Waits for pipeTo task completion
|
|
972
|
+
* - Propagates flush to next component (if any)
|
|
973
|
+
*
|
|
974
|
+
* Used by scheduler system for pipeline control.
|
|
975
|
+
*
|
|
976
|
+
* @param packet - Packet to send, or null to flush
|
|
977
|
+
*
|
|
978
|
+
* @internal
|
|
979
|
+
*/
|
|
980
|
+
private sendToQueue;
|
|
981
|
+
/**
|
|
982
|
+
* Receive frame from output queue.
|
|
983
|
+
*
|
|
984
|
+
* @returns Frame from output queue or null if closed
|
|
985
|
+
*
|
|
986
|
+
* @internal
|
|
987
|
+
*/
|
|
988
|
+
private receiveFromQueue;
|
|
989
|
+
/**
|
|
990
|
+
* Estimate video frame duration.
|
|
991
|
+
*
|
|
992
|
+
* Implements FFmpeg CLI's video_duration_estimate() logic.
|
|
993
|
+
* Uses multiple heuristics to determine frame duration when not explicitly available:
|
|
994
|
+
* 1. Frame duration from container (if reliable)
|
|
995
|
+
* 2. Duration from codec framerate
|
|
996
|
+
* 3. PTS difference between frames
|
|
997
|
+
* 4. Stream framerate
|
|
998
|
+
* 5. Last frame's estimated duration
|
|
999
|
+
*
|
|
1000
|
+
* @param frame - Frame to estimate duration for
|
|
1001
|
+
*
|
|
1002
|
+
* @returns Estimated duration in frame's timebase units
|
|
1003
|
+
*
|
|
1004
|
+
* @internal
|
|
1005
|
+
*/
|
|
1006
|
+
private estimateVideoDuration;
|
|
1007
|
+
/**
|
|
1008
|
+
* Process video frame after decoding.
|
|
1009
|
+
*
|
|
1010
|
+
* Implements FFmpeg CLI's video_frame_process() logic.
|
|
1011
|
+
* Handles:
|
|
1012
|
+
* - Hardware frame transfer to software format
|
|
1013
|
+
* - PTS assignment from best_effort_timestamp
|
|
1014
|
+
* - PTS extrapolation when missing
|
|
1015
|
+
* - Duration estimation
|
|
1016
|
+
* - Frame tracking for next frame
|
|
1017
|
+
*
|
|
1018
|
+
* @param frame - Decoded frame to process
|
|
1019
|
+
*
|
|
1020
|
+
* @internal
|
|
1021
|
+
*/
|
|
1022
|
+
private processVideoFrame;
|
|
1023
|
+
/**
|
|
1024
|
+
* Audio samplerate update - handles sample rate changes.
|
|
1025
|
+
*
|
|
1026
|
+
* Based on FFmpeg's audio_samplerate_update().
|
|
1027
|
+
*
|
|
1028
|
+
* On sample rate change, chooses a new internal timebase that can represent
|
|
1029
|
+
* timestamps from all sample rates seen so far. Uses GCD to find minimal
|
|
1030
|
+
* common timebase, with fallback to LCM of common sample rates (28224000).
|
|
1031
|
+
*
|
|
1032
|
+
* Handles:
|
|
1033
|
+
* - Sample rate change detection
|
|
1034
|
+
* - Timebase calculation via GCD
|
|
1035
|
+
* - Overflow detection and fallback
|
|
1036
|
+
* - Frame timebase optimization
|
|
1037
|
+
* - Rescaling existing timestamps
|
|
1038
|
+
*
|
|
1039
|
+
* @param frame - Audio frame to process
|
|
1040
|
+
*
|
|
1041
|
+
* @returns Timebase to use for this frame
|
|
1042
|
+
*
|
|
1043
|
+
* @internal
|
|
1044
|
+
*/
|
|
1045
|
+
private audioSamplerateUpdate;
|
|
1046
|
+
/**
|
|
1047
|
+
* Audio timestamp processing - handles audio frame timestamps.
|
|
1048
|
+
*
|
|
1049
|
+
* Based on FFmpeg's audio_ts_process().
|
|
1050
|
+
*
|
|
1051
|
+
* Processes audio frame timestamps with:
|
|
1052
|
+
* - Sample rate change handling via audioSamplerateUpdate()
|
|
1053
|
+
* - PTS extrapolation when missing (pts_pred)
|
|
1054
|
+
* - Gap detection (resets av_rescale_delta state)
|
|
1055
|
+
* - Smooth timestamp conversion via av_rescale_delta
|
|
1056
|
+
* - Duration calculation from nb_samples
|
|
1057
|
+
* - Conversion to filtering timebase {1, sample_rate}
|
|
1058
|
+
*
|
|
1059
|
+
* Handles:
|
|
1060
|
+
* - Dynamic sample rate changes
|
|
1061
|
+
* - Missing timestamps (AV_NOPTS_VALUE)
|
|
1062
|
+
* - Timestamp gaps/discontinuities
|
|
1063
|
+
* - Sample-accurate timestamp generation
|
|
1064
|
+
* - Frame duration calculation
|
|
1065
|
+
*
|
|
1066
|
+
* @param frame - Decoded audio frame to process
|
|
1067
|
+
*
|
|
1068
|
+
* @internal
|
|
1069
|
+
*/
|
|
1070
|
+
private processAudioFrame;
|
|
1071
|
+
/**
|
|
1072
|
+
* Dispose of decoder.
|
|
1073
|
+
*
|
|
1074
|
+
* Implements Disposable interface for automatic cleanup.
|
|
1075
|
+
* Equivalent to calling close().
|
|
1076
|
+
*
|
|
1077
|
+
* @example
|
|
1078
|
+
* ```typescript
|
|
1079
|
+
* {
|
|
1080
|
+
* using decoder = await Decoder.create(stream);
|
|
1081
|
+
* // Decode frames...
|
|
1082
|
+
* } // Automatically closed
|
|
1083
|
+
* ```
|
|
1084
|
+
*
|
|
1085
|
+
* @see {@link close} For manual cleanup
|
|
1086
|
+
*/
|
|
1087
|
+
[Symbol.dispose](): void;
|
|
1088
|
+
}
|