node-av 1.1.0 → 1.2.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 +51 -38
- package/dist/api/bitstream-filter.d.ts +180 -123
- package/dist/api/bitstream-filter.js +180 -125
- package/dist/api/bitstream-filter.js.map +1 -1
- package/dist/api/decoder.d.ts +279 -132
- package/dist/api/decoder.js +285 -142
- package/dist/api/decoder.js.map +1 -1
- package/dist/api/encoder.d.ts +246 -162
- package/dist/api/encoder.js +272 -208
- package/dist/api/encoder.js.map +1 -1
- package/dist/api/filter-presets.d.ts +690 -94
- package/dist/api/filter-presets.js +686 -102
- package/dist/api/filter-presets.js.map +1 -1
- package/dist/api/filter.d.ts +249 -213
- package/dist/api/filter.js +252 -242
- package/dist/api/filter.js.map +1 -1
- package/dist/api/hardware.d.ts +224 -117
- package/dist/api/hardware.js +380 -214
- package/dist/api/hardware.js.map +1 -1
- package/dist/api/index.d.ts +3 -3
- package/dist/api/index.js +1 -1
- package/dist/api/index.js.map +1 -1
- package/dist/api/io-stream.d.ts +65 -61
- package/dist/api/io-stream.js +43 -46
- package/dist/api/io-stream.js.map +1 -1
- package/dist/api/media-input.d.ts +242 -140
- package/dist/api/media-input.js +205 -103
- package/dist/api/media-input.js.map +1 -1
- package/dist/api/media-output.d.ts +206 -128
- package/dist/api/media-output.js +210 -128
- package/dist/api/media-output.js.map +1 -1
- package/dist/api/pipeline.d.ts +168 -38
- package/dist/api/pipeline.js +238 -14
- package/dist/api/pipeline.js.map +1 -1
- package/dist/api/types.d.ts +21 -187
- package/dist/api/utils.d.ts +1 -2
- package/dist/api/utils.js +9 -0
- package/dist/api/utils.js.map +1 -1
- package/dist/lib/audio-fifo.d.ts +127 -170
- package/dist/lib/audio-fifo.js +130 -173
- package/dist/lib/audio-fifo.js.map +1 -1
- package/dist/lib/binding.js +5 -0
- package/dist/lib/binding.js.map +1 -1
- package/dist/lib/bitstream-filter-context.d.ts +139 -184
- package/dist/lib/bitstream-filter-context.js +139 -188
- package/dist/lib/bitstream-filter-context.js.map +1 -1
- package/dist/lib/bitstream-filter.d.ts +68 -54
- package/dist/lib/bitstream-filter.js +68 -54
- package/dist/lib/bitstream-filter.js.map +1 -1
- package/dist/lib/codec-context.d.ts +316 -380
- package/dist/lib/codec-context.js +316 -381
- package/dist/lib/codec-context.js.map +1 -1
- package/dist/lib/codec-parameters.d.ts +160 -170
- package/dist/lib/codec-parameters.js +162 -172
- package/dist/lib/codec-parameters.js.map +1 -1
- package/dist/lib/codec-parser.d.ts +91 -104
- package/dist/lib/codec-parser.js +92 -103
- package/dist/lib/codec-parser.js.map +1 -1
- package/dist/lib/codec.d.ts +264 -281
- package/dist/lib/codec.js +268 -285
- package/dist/lib/codec.js.map +1 -1
- package/dist/lib/dictionary.d.ts +149 -203
- package/dist/lib/dictionary.js +158 -212
- package/dist/lib/dictionary.js.map +1 -1
- package/dist/lib/error.d.ts +96 -130
- package/dist/lib/error.js +98 -128
- package/dist/lib/error.js.map +1 -1
- package/dist/lib/filter-context.d.ts +284 -218
- package/dist/lib/filter-context.js +290 -227
- package/dist/lib/filter-context.js.map +1 -1
- package/dist/lib/filter-graph.d.ts +251 -292
- package/dist/lib/filter-graph.js +253 -294
- package/dist/lib/filter-graph.js.map +1 -1
- package/dist/lib/filter-inout.d.ts +87 -95
- package/dist/lib/filter-inout.js +87 -95
- package/dist/lib/filter-inout.js.map +1 -1
- package/dist/lib/filter.d.ts +93 -111
- package/dist/lib/filter.js +93 -111
- package/dist/lib/filter.js.map +1 -1
- package/dist/lib/format-context.d.ts +320 -428
- package/dist/lib/format-context.js +313 -385
- package/dist/lib/format-context.js.map +1 -1
- package/dist/lib/frame.d.ts +262 -405
- package/dist/lib/frame.js +263 -408
- package/dist/lib/frame.js.map +1 -1
- package/dist/lib/hardware-device-context.d.ts +149 -203
- package/dist/lib/hardware-device-context.js +149 -203
- package/dist/lib/hardware-device-context.js.map +1 -1
- package/dist/lib/hardware-frames-context.d.ts +170 -180
- package/dist/lib/hardware-frames-context.js +171 -181
- package/dist/lib/hardware-frames-context.js.map +1 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +2 -2
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/input-format.d.ts +89 -117
- package/dist/lib/input-format.js +89 -117
- package/dist/lib/input-format.js.map +1 -1
- package/dist/lib/io-context.d.ts +209 -241
- package/dist/lib/io-context.js +220 -252
- package/dist/lib/io-context.js.map +1 -1
- package/dist/lib/log.d.ts +85 -119
- package/dist/lib/log.js +85 -122
- package/dist/lib/log.js.map +1 -1
- package/dist/lib/native-types.d.ts +117 -106
- package/dist/lib/native-types.js +0 -7
- package/dist/lib/native-types.js.map +1 -1
- package/dist/lib/option.d.ts +284 -241
- package/dist/lib/option.js +309 -249
- package/dist/lib/option.js.map +1 -1
- package/dist/lib/output-format.d.ts +77 -101
- package/dist/lib/output-format.js +77 -101
- package/dist/lib/output-format.js.map +1 -1
- package/dist/lib/packet.d.ts +172 -240
- package/dist/lib/packet.js +172 -241
- package/dist/lib/packet.js.map +1 -1
- package/dist/lib/rational.d.ts +0 -2
- package/dist/lib/rational.js +0 -2
- package/dist/lib/rational.js.map +1 -1
- package/dist/lib/software-resample-context.d.ts +241 -325
- package/dist/lib/software-resample-context.js +242 -326
- package/dist/lib/software-resample-context.js.map +1 -1
- package/dist/lib/software-scale-context.d.ts +129 -173
- package/dist/lib/software-scale-context.js +131 -175
- package/dist/lib/software-scale-context.js.map +1 -1
- package/dist/lib/stream.d.ts +87 -197
- package/dist/lib/stream.js +87 -197
- package/dist/lib/stream.js.map +1 -1
- package/dist/lib/utilities.d.ts +372 -181
- package/dist/lib/utilities.js +373 -182
- package/dist/lib/utilities.js.map +1 -1
- package/install/check.js +0 -1
- package/package.json +21 -12
- package/release_notes.md +43 -59
- package/CHANGELOG.md +0 -8
|
@@ -7,104 +7,65 @@ import { OptionMember } from './option.js';
|
|
|
7
7
|
import { OutputFormat } from './output-format.js';
|
|
8
8
|
import { Stream } from './stream.js';
|
|
9
9
|
/**
|
|
10
|
-
*
|
|
10
|
+
* Container format context for reading/writing multimedia files.
|
|
11
11
|
*
|
|
12
|
-
* Central structure for
|
|
13
|
-
*
|
|
14
|
-
*
|
|
12
|
+
* Central structure for demuxing (reading) and muxing (writing) media files.
|
|
13
|
+
* Manages streams, packets, metadata, and format-specific operations.
|
|
14
|
+
* Supports both file-based and custom I/O through IOContext.
|
|
15
|
+
* Essential for all file-based media operations.
|
|
15
16
|
*
|
|
16
17
|
* Direct mapping to FFmpeg's AVFormatContext.
|
|
17
18
|
*
|
|
18
19
|
* @example
|
|
19
20
|
* ```typescript
|
|
20
|
-
* import { FormatContext,
|
|
21
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
22
|
+
* import { AVMEDIA_TYPE_VIDEO } from 'node-av/constants';
|
|
21
23
|
*
|
|
22
|
-
* //
|
|
24
|
+
* // Open input file
|
|
23
25
|
* const ctx = new FormatContext();
|
|
24
|
-
* ctx.
|
|
25
|
-
*
|
|
26
|
-
* const ret = await ctx.openInput('video.mp4', null, null);
|
|
26
|
+
* let ret = await ctx.openInput('input.mp4');
|
|
27
27
|
* FFmpegError.throwIfError(ret, 'openInput');
|
|
28
28
|
*
|
|
29
|
-
*
|
|
30
|
-
* FFmpegError.throwIfError(
|
|
29
|
+
* ret = await ctx.findStreamInfo();
|
|
30
|
+
* FFmpegError.throwIfError(ret, 'findStreamInfo');
|
|
31
|
+
*
|
|
32
|
+
* // Find video stream
|
|
33
|
+
* const videoIndex = ctx.findBestStream(AVMEDIA_TYPE_VIDEO);
|
|
34
|
+
* if (videoIndex < 0) {
|
|
35
|
+
* throw new Error('No video stream found');
|
|
36
|
+
* }
|
|
31
37
|
*
|
|
38
|
+
* // Read packets
|
|
32
39
|
* const packet = new Packet();
|
|
33
40
|
* packet.alloc();
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* // Process packet
|
|
41
|
+
* while ((ret = await ctx.readFrame(packet)) >= 0) {
|
|
42
|
+
* if (packet.streamIndex === videoIndex) {
|
|
43
|
+
* // Process video packet
|
|
44
|
+
* }
|
|
39
45
|
* packet.unref();
|
|
40
46
|
* }
|
|
41
47
|
*
|
|
48
|
+
* // Cleanup
|
|
42
49
|
* await ctx.closeInput();
|
|
43
|
-
* ctx.freeContext();
|
|
44
50
|
* ```
|
|
45
51
|
*
|
|
46
|
-
* @
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
*
|
|
50
|
-
* // Muxing - explicit control
|
|
51
|
-
* const ctx = new FormatContext();
|
|
52
|
-
* const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4');
|
|
53
|
-
* FFmpegError.throwIfError(ret, 'allocOutputContext2');
|
|
54
|
-
*
|
|
55
|
-
* // Add streams
|
|
56
|
-
* const stream = ctx.newStream(null);
|
|
57
|
-
*
|
|
58
|
-
* // Write header
|
|
59
|
-
* const headerRet = await ctx.writeHeader(null);
|
|
60
|
-
* FFmpegError.throwIfError(headerRet, 'writeHeader');
|
|
61
|
-
*
|
|
62
|
-
* // Write packets
|
|
63
|
-
* const writeRet = await ctx.interleavedWriteFrame(packet);
|
|
64
|
-
* FFmpegError.throwIfError(writeRet, 'interleavedWriteFrame');
|
|
65
|
-
*
|
|
66
|
-
* // Finalize
|
|
67
|
-
* const trailerRet = await ctx.writeTrailer();
|
|
68
|
-
* FFmpegError.throwIfError(trailerRet, 'writeTrailer');
|
|
69
|
-
* ctx.freeContext();
|
|
70
|
-
* ```
|
|
71
|
-
*
|
|
72
|
-
* @see {@link InputFormat} For input format handling
|
|
73
|
-
* @see {@link OutputFormat} For output format handling
|
|
52
|
+
* @see [AVFormatContext](https://ffmpeg.org/doxygen/trunk/structAVFormatContext.html) - FFmpeg Doxygen
|
|
53
|
+
* @see {@link InputFormat} For supported input formats
|
|
54
|
+
* @see {@link OutputFormat} For supported output formats
|
|
74
55
|
* @see {@link Stream} For stream management
|
|
75
|
-
* @see {@link Packet} For packet handling
|
|
76
56
|
*/
|
|
77
57
|
export class FormatContext extends OptionMember {
|
|
78
58
|
_ioContext = null;
|
|
79
|
-
/**
|
|
80
|
-
* Create a new format context.
|
|
81
|
-
*
|
|
82
|
-
* The context is uninitialized - you must call allocContext() or allocOutputContext2() before use.
|
|
83
|
-
* No FFmpeg resources are allocated until initialization.
|
|
84
|
-
*
|
|
85
|
-
* Direct wrapper around AVFormatContext.
|
|
86
|
-
*
|
|
87
|
-
* @example
|
|
88
|
-
* ```typescript
|
|
89
|
-
* import { FormatContext, FFmpegError } from 'node-av';
|
|
90
|
-
*
|
|
91
|
-
* const ctx = new FormatContext();
|
|
92
|
-
* ctx.allocContext(); // For demuxing
|
|
93
|
-
* // OR
|
|
94
|
-
* const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4'); // For muxing
|
|
95
|
-
* FFmpegError.throwIfError(ret, 'allocOutputContext2');
|
|
96
|
-
* ```
|
|
97
|
-
*/
|
|
98
59
|
constructor() {
|
|
99
60
|
super(new bindings.FormatContext());
|
|
100
61
|
}
|
|
101
62
|
/**
|
|
102
|
-
*
|
|
63
|
+
* URL or filename of the media.
|
|
103
64
|
*
|
|
104
|
-
*
|
|
65
|
+
* For input: the opened file path.
|
|
66
|
+
* For output: the target file path.
|
|
105
67
|
*
|
|
106
|
-
*
|
|
107
|
-
* - demuxing: Set by avformat_open_input
|
|
68
|
+
* Direct mapping to AVFormatContext->url.
|
|
108
69
|
*/
|
|
109
70
|
get url() {
|
|
110
71
|
return this.native.url;
|
|
@@ -113,46 +74,45 @@ export class FormatContext extends OptionMember {
|
|
|
113
74
|
this.native.url = value;
|
|
114
75
|
}
|
|
115
76
|
/**
|
|
116
|
-
*
|
|
77
|
+
* Start time of the stream.
|
|
117
78
|
*
|
|
118
|
-
*
|
|
79
|
+
* Position of the first frame in microseconds.
|
|
80
|
+
* AV_NOPTS_VALUE if unknown.
|
|
119
81
|
*
|
|
120
|
-
*
|
|
121
|
-
* - demuxing: Set by libavformat
|
|
82
|
+
* Direct mapping to AVFormatContext->start_time.
|
|
122
83
|
*/
|
|
123
84
|
get startTime() {
|
|
124
85
|
return this.native.startTime;
|
|
125
86
|
}
|
|
126
87
|
/**
|
|
127
|
-
* Duration of the stream
|
|
88
|
+
* Duration of the stream.
|
|
128
89
|
*
|
|
129
|
-
*
|
|
90
|
+
* Total stream duration in microseconds.
|
|
91
|
+
* AV_NOPTS_VALUE if unknown.
|
|
130
92
|
*
|
|
131
|
-
*
|
|
132
|
-
* - demuxing: Set by libavformat
|
|
133
|
-
* - muxing: May be set by user
|
|
93
|
+
* Direct mapping to AVFormatContext->duration.
|
|
134
94
|
*/
|
|
135
95
|
get duration() {
|
|
136
96
|
return this.native.duration;
|
|
137
97
|
}
|
|
138
98
|
/**
|
|
139
|
-
* Total stream bitrate
|
|
99
|
+
* Total stream bitrate.
|
|
140
100
|
*
|
|
141
|
-
*
|
|
101
|
+
* Bitrate in bits per second.
|
|
102
|
+
* 0 if unknown.
|
|
142
103
|
*
|
|
143
|
-
*
|
|
104
|
+
* Direct mapping to AVFormatContext->bit_rate.
|
|
144
105
|
*/
|
|
145
106
|
get bitRate() {
|
|
146
107
|
return this.native.bitRate;
|
|
147
108
|
}
|
|
148
109
|
/**
|
|
149
|
-
*
|
|
110
|
+
* Format-specific flags.
|
|
150
111
|
*
|
|
151
|
-
*
|
|
112
|
+
* Combination of AVFMT_FLAG_* values controlling
|
|
113
|
+
* format behavior (e.g., AVFMT_FLAG_GENPTS).
|
|
152
114
|
*
|
|
153
|
-
*
|
|
154
|
-
* - encoding: Set by user
|
|
155
|
-
* - decoding: Set by user
|
|
115
|
+
* Direct mapping to AVFormatContext->flags.
|
|
156
116
|
*/
|
|
157
117
|
get flags() {
|
|
158
118
|
return this.native.flags;
|
|
@@ -161,12 +121,12 @@ export class FormatContext extends OptionMember {
|
|
|
161
121
|
this.native.flags = value;
|
|
162
122
|
}
|
|
163
123
|
/**
|
|
164
|
-
* Maximum
|
|
124
|
+
* Maximum bytes to probe for format detection.
|
|
165
125
|
*
|
|
166
|
-
*
|
|
126
|
+
* Larger values improve format detection accuracy
|
|
127
|
+
* but increase startup time.
|
|
167
128
|
*
|
|
168
|
-
*
|
|
169
|
-
* - decoding: Set by user
|
|
129
|
+
* Direct mapping to AVFormatContext->probesize.
|
|
170
130
|
*/
|
|
171
131
|
get probesize() {
|
|
172
132
|
return this.native.probesize;
|
|
@@ -175,12 +135,12 @@ export class FormatContext extends OptionMember {
|
|
|
175
135
|
this.native.probesize = value;
|
|
176
136
|
}
|
|
177
137
|
/**
|
|
178
|
-
* Maximum duration
|
|
138
|
+
* Maximum duration to analyze streams.
|
|
179
139
|
*
|
|
180
|
-
*
|
|
140
|
+
* Time in microseconds to spend analyzing streams.
|
|
141
|
+
* Larger values improve stream detection accuracy.
|
|
181
142
|
*
|
|
182
|
-
*
|
|
183
|
-
* - decoding: Set by user
|
|
143
|
+
* Direct mapping to AVFormatContext->max_analyze_duration.
|
|
184
144
|
*/
|
|
185
145
|
get maxAnalyzeDuration() {
|
|
186
146
|
return this.native.maxAnalyzeDuration;
|
|
@@ -189,12 +149,11 @@ export class FormatContext extends OptionMember {
|
|
|
189
149
|
this.native.maxAnalyzeDuration = value;
|
|
190
150
|
}
|
|
191
151
|
/**
|
|
192
|
-
*
|
|
152
|
+
* Container metadata.
|
|
193
153
|
*
|
|
194
|
-
*
|
|
154
|
+
* Key-value pairs of metadata (title, author, etc.).
|
|
195
155
|
*
|
|
196
|
-
*
|
|
197
|
-
* - muxing: May be set by user
|
|
156
|
+
* Direct mapping to AVFormatContext->metadata.
|
|
198
157
|
*/
|
|
199
158
|
get metadata() {
|
|
200
159
|
const nativeDict = this.native.metadata;
|
|
@@ -207,11 +166,11 @@ export class FormatContext extends OptionMember {
|
|
|
207
166
|
this.native.metadata = value?.getNative() ?? null;
|
|
208
167
|
}
|
|
209
168
|
/**
|
|
210
|
-
* Input format
|
|
169
|
+
* Input format descriptor.
|
|
211
170
|
*
|
|
212
|
-
*
|
|
171
|
+
* Format used for demuxing. Null for output contexts.
|
|
213
172
|
*
|
|
214
|
-
*
|
|
173
|
+
* Direct mapping to AVFormatContext->iformat.
|
|
215
174
|
*/
|
|
216
175
|
get iformat() {
|
|
217
176
|
const nativeFormat = this.native.iformat;
|
|
@@ -221,11 +180,11 @@ export class FormatContext extends OptionMember {
|
|
|
221
180
|
return new InputFormat(nativeFormat);
|
|
222
181
|
}
|
|
223
182
|
/**
|
|
224
|
-
* Output format
|
|
183
|
+
* Output format descriptor.
|
|
225
184
|
*
|
|
226
|
-
*
|
|
185
|
+
* Format used for muxing. Null for input contexts.
|
|
227
186
|
*
|
|
228
|
-
*
|
|
187
|
+
* Direct mapping to AVFormatContext->oformat.
|
|
229
188
|
*/
|
|
230
189
|
get oformat() {
|
|
231
190
|
const nativeFormat = this.native.oformat;
|
|
@@ -238,15 +197,11 @@ export class FormatContext extends OptionMember {
|
|
|
238
197
|
this.native.oformat = value?.getNative() ?? null;
|
|
239
198
|
}
|
|
240
199
|
/**
|
|
241
|
-
* I/O context.
|
|
200
|
+
* Custom I/O context.
|
|
242
201
|
*
|
|
243
|
-
*
|
|
202
|
+
* For custom I/O operations instead of file I/O.
|
|
244
203
|
*
|
|
245
|
-
*
|
|
246
|
-
* - muxing: Set by user for custom I/O. Otherwise internal
|
|
247
|
-
*
|
|
248
|
-
* The FormatContext keeps track of the IOContext set by the user.
|
|
249
|
-
* This prevents ownership confusion.
|
|
204
|
+
* Direct mapping to AVFormatContext->pb.
|
|
250
205
|
*/
|
|
251
206
|
get pb() {
|
|
252
207
|
return this._ioContext;
|
|
@@ -256,17 +211,19 @@ export class FormatContext extends OptionMember {
|
|
|
256
211
|
this.native.pb = value?.getNative() ?? null;
|
|
257
212
|
}
|
|
258
213
|
/**
|
|
259
|
-
* Number of streams in the
|
|
214
|
+
* Number of streams in the container.
|
|
260
215
|
*
|
|
261
|
-
* Direct mapping to AVFormatContext->nb_streams
|
|
216
|
+
* Direct mapping to AVFormatContext->nb_streams.
|
|
262
217
|
*/
|
|
263
218
|
get nbStreams() {
|
|
264
219
|
return this.native.nbStreams;
|
|
265
220
|
}
|
|
266
221
|
/**
|
|
267
|
-
* Array of streams in the
|
|
222
|
+
* Array of streams in the container.
|
|
223
|
+
*
|
|
224
|
+
* All audio, video, subtitle, and data streams.
|
|
268
225
|
*
|
|
269
|
-
* Direct mapping to AVFormatContext->streams
|
|
226
|
+
* Direct mapping to AVFormatContext->streams.
|
|
270
227
|
*/
|
|
271
228
|
get streams() {
|
|
272
229
|
const nativeStreams = this.native.streams;
|
|
@@ -276,11 +233,12 @@ export class FormatContext extends OptionMember {
|
|
|
276
233
|
return nativeStreams.map((nativeStream) => new Stream(nativeStream));
|
|
277
234
|
}
|
|
278
235
|
/**
|
|
279
|
-
*
|
|
236
|
+
* Strictness level for standards compliance.
|
|
280
237
|
*
|
|
281
|
-
*
|
|
238
|
+
* FF_COMPLIANCE_* value controlling how strictly
|
|
239
|
+
* to follow specifications.
|
|
282
240
|
*
|
|
283
|
-
*
|
|
241
|
+
* Direct mapping to AVFormatContext->strict_std_compliance.
|
|
284
242
|
*/
|
|
285
243
|
get strictStdCompliance() {
|
|
286
244
|
return this.native.strictStdCompliance;
|
|
@@ -291,10 +249,9 @@ export class FormatContext extends OptionMember {
|
|
|
291
249
|
/**
|
|
292
250
|
* Maximum number of streams.
|
|
293
251
|
*
|
|
294
|
-
*
|
|
252
|
+
* Limit on stream count for security/resource reasons.
|
|
295
253
|
*
|
|
296
|
-
*
|
|
297
|
-
* - decoding: Set by user
|
|
254
|
+
* Direct mapping to AVFormatContext->max_streams.
|
|
298
255
|
*/
|
|
299
256
|
get maxStreams() {
|
|
300
257
|
return this.native.maxStreams;
|
|
@@ -303,77 +260,78 @@ export class FormatContext extends OptionMember {
|
|
|
303
260
|
this.native.maxStreams = value;
|
|
304
261
|
}
|
|
305
262
|
/**
|
|
306
|
-
* Number of programs
|
|
263
|
+
* Number of programs.
|
|
307
264
|
*
|
|
308
|
-
*
|
|
265
|
+
* For containers with multiple programs (e.g., MPEG-TS).
|
|
309
266
|
*
|
|
310
|
-
*
|
|
267
|
+
* Direct mapping to AVFormatContext->nb_programs.
|
|
311
268
|
*/
|
|
312
269
|
get nbPrograms() {
|
|
313
270
|
return this.native.nbPrograms;
|
|
314
271
|
}
|
|
315
272
|
/**
|
|
316
|
-
*
|
|
317
|
-
*
|
|
318
|
-
* Direct mapping to avio_tell(AVFormatContext->pb)
|
|
273
|
+
* Number of bytes read/written through I/O context.
|
|
319
274
|
*
|
|
320
|
-
*
|
|
321
|
-
* - demuxing: Current read position
|
|
322
|
-
* - muxing: Current write position
|
|
275
|
+
* Direct mapping to avio_tell(AVFormatContext->pb).
|
|
323
276
|
*/
|
|
324
277
|
get pbBytes() {
|
|
325
278
|
return this.native.pbBytes;
|
|
326
279
|
}
|
|
327
280
|
/**
|
|
328
|
-
* Format
|
|
281
|
+
* Format probe score.
|
|
329
282
|
*
|
|
330
|
-
*
|
|
283
|
+
* Confidence score from format detection (0-100).
|
|
284
|
+
* Higher values indicate more confident detection.
|
|
331
285
|
*
|
|
332
|
-
*
|
|
333
|
-
* - demuxing: Set by format probing
|
|
286
|
+
* Direct mapping to AVFormatContext->probe_score.
|
|
334
287
|
*/
|
|
335
288
|
get probeScore() {
|
|
336
289
|
return this.native.probeScore;
|
|
337
290
|
}
|
|
338
291
|
/**
|
|
339
|
-
* Allocate
|
|
292
|
+
* Allocate a format context.
|
|
340
293
|
*
|
|
341
|
-
*
|
|
294
|
+
* Allocates the context structure. Usually not needed
|
|
295
|
+
* as openInput/allocOutputContext2 handle this.
|
|
296
|
+
*
|
|
297
|
+
* Direct mapping to avformat_alloc_context().
|
|
342
298
|
*
|
|
343
299
|
* @example
|
|
344
300
|
* ```typescript
|
|
345
301
|
* const ctx = new FormatContext();
|
|
346
302
|
* ctx.allocContext();
|
|
347
|
-
* // Context is now allocated
|
|
303
|
+
* // Context is now allocated
|
|
348
304
|
* ```
|
|
349
|
-
*
|
|
350
|
-
* @throws {Error} If allocation fails (ENOMEM)
|
|
351
305
|
*/
|
|
352
306
|
allocContext() {
|
|
353
|
-
|
|
307
|
+
this.native.allocContext();
|
|
354
308
|
}
|
|
355
309
|
/**
|
|
356
|
-
* Allocate an
|
|
310
|
+
* Allocate an output format context.
|
|
357
311
|
*
|
|
358
|
-
*
|
|
312
|
+
* Allocates and configures context for writing.
|
|
313
|
+
* Format is determined by parameters in priority order.
|
|
359
314
|
*
|
|
360
|
-
*
|
|
361
|
-
* @param formatName - Format name. May be null to auto-detect
|
|
362
|
-
* @param filename - Filename for output. Used to guess format if not specified
|
|
315
|
+
* Direct mapping to avformat_alloc_output_context2().
|
|
363
316
|
*
|
|
317
|
+
* @param oformat - Specific output format to use
|
|
318
|
+
* @param formatName - Format name (e.g., 'mp4', 'mkv')
|
|
319
|
+
* @param filename - Filename to guess format from extension
|
|
364
320
|
* @returns 0 on success, negative AVERROR on error:
|
|
365
|
-
* -
|
|
366
|
-
* -
|
|
367
|
-
* - AVERROR(ENOMEM): Memory allocation failure
|
|
321
|
+
* - AVERROR_ENOMEM: Memory allocation failure
|
|
322
|
+
* - AVERROR_EINVAL: Invalid parameters
|
|
368
323
|
*
|
|
369
324
|
* @example
|
|
370
325
|
* ```typescript
|
|
326
|
+
* import { FFmpegError } from 'node-av';
|
|
327
|
+
*
|
|
371
328
|
* const ctx = new FormatContext();
|
|
372
329
|
* const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4');
|
|
373
|
-
*
|
|
374
|
-
* throw new FFmpegError(ret);
|
|
375
|
-
* }
|
|
330
|
+
* FFmpegError.throwIfError(ret, 'allocOutputContext2');
|
|
376
331
|
* ```
|
|
332
|
+
*
|
|
333
|
+
* @see {@link openOutput} To open output file
|
|
334
|
+
* @see {@link writeHeader} To write file header
|
|
377
335
|
*/
|
|
378
336
|
allocOutputContext2(oformat, formatName, filename) {
|
|
379
337
|
if (!oformat && !formatName && !filename) {
|
|
@@ -382,415 +340,392 @@ export class FormatContext extends OptionMember {
|
|
|
382
340
|
return this.native.allocOutputContext2(oformat?.getNative() ?? null, formatName, filename);
|
|
383
341
|
}
|
|
384
342
|
/**
|
|
385
|
-
* Free
|
|
343
|
+
* Free the format context.
|
|
344
|
+
*
|
|
345
|
+
* Releases all resources. The context becomes invalid.
|
|
386
346
|
*
|
|
387
|
-
* Direct mapping to avformat_free_context()
|
|
347
|
+
* Direct mapping to avformat_free_context().
|
|
388
348
|
*
|
|
389
349
|
* @example
|
|
390
350
|
* ```typescript
|
|
391
351
|
* ctx.freeContext();
|
|
392
|
-
* //
|
|
352
|
+
* // Context is now invalid
|
|
393
353
|
* ```
|
|
354
|
+
*
|
|
355
|
+
* @see {@link Symbol.asyncDispose} For automatic cleanup
|
|
394
356
|
*/
|
|
395
357
|
freeContext() {
|
|
396
|
-
|
|
358
|
+
this.native.freeContext();
|
|
397
359
|
}
|
|
398
360
|
/**
|
|
399
|
-
* Close an
|
|
361
|
+
* Close an input format context.
|
|
362
|
+
*
|
|
363
|
+
* Closes input file and releases resources.
|
|
364
|
+
*
|
|
365
|
+
* Direct mapping to avformat_close_input().
|
|
400
366
|
*
|
|
401
|
-
*
|
|
367
|
+
* @returns Promise that resolves when closed
|
|
402
368
|
*
|
|
403
369
|
* @example
|
|
404
370
|
* ```typescript
|
|
405
371
|
* await ctx.closeInput();
|
|
406
|
-
* // Input
|
|
372
|
+
* // Input closed and context freed
|
|
407
373
|
* ```
|
|
374
|
+
*
|
|
375
|
+
* @see {@link openInput} To open input
|
|
408
376
|
*/
|
|
409
377
|
async closeInput() {
|
|
410
|
-
return this.native.closeInput();
|
|
378
|
+
return await this.native.closeInput();
|
|
411
379
|
}
|
|
412
380
|
/**
|
|
413
|
-
* Open
|
|
381
|
+
* Open output file for writing.
|
|
414
382
|
*
|
|
415
|
-
*
|
|
416
|
-
*
|
|
383
|
+
* Opens the output file specified in url.
|
|
384
|
+
* Must call allocOutputContext2 first.
|
|
417
385
|
*
|
|
418
|
-
* Direct mapping to
|
|
386
|
+
* Direct mapping to avio_open2().
|
|
419
387
|
*
|
|
420
|
-
* @returns
|
|
421
|
-
* -
|
|
422
|
-
* -
|
|
423
|
-
* -
|
|
424
|
-
* - AVERROR(EIO): I/O error
|
|
388
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
389
|
+
* - AVERROR_ENOENT: File not found
|
|
390
|
+
* - AVERROR_EACCES: Permission denied
|
|
391
|
+
* - AVERROR_EIO: I/O error
|
|
425
392
|
*
|
|
426
393
|
* @example
|
|
427
394
|
* ```typescript
|
|
428
|
-
* import {
|
|
395
|
+
* import { FFmpegError } from 'node-av';
|
|
429
396
|
*
|
|
430
|
-
* ctx.
|
|
431
|
-
* const ret = await ctx.openOutput(); // Opens the file for writing
|
|
397
|
+
* const ret = await ctx.openOutput();
|
|
432
398
|
* FFmpegError.throwIfError(ret, 'openOutput');
|
|
433
|
-
* await ctx.writeHeader(null);
|
|
434
399
|
* ```
|
|
400
|
+
*
|
|
401
|
+
* @see {@link allocOutputContext2} Must be called first
|
|
402
|
+
* @see {@link closeOutput} To close output
|
|
435
403
|
*/
|
|
436
404
|
async openOutput() {
|
|
437
|
-
return this.native.openOutput();
|
|
405
|
+
return await this.native.openOutput();
|
|
438
406
|
}
|
|
439
407
|
/**
|
|
440
|
-
* Close
|
|
408
|
+
* Close output file.
|
|
409
|
+
*
|
|
410
|
+
* Closes the output file and releases I/O resources.
|
|
441
411
|
*
|
|
442
|
-
* Direct mapping to avio_closep()
|
|
412
|
+
* Direct mapping to avio_closep().
|
|
443
413
|
*
|
|
444
|
-
*
|
|
445
|
-
* The file is automatically closed by freeContext() as well.
|
|
414
|
+
* @returns Promise that resolves when closed
|
|
446
415
|
*
|
|
447
416
|
* @example
|
|
448
417
|
* ```typescript
|
|
449
|
-
* await ctx.writeTrailer();
|
|
450
418
|
* await ctx.closeOutput();
|
|
451
|
-
*
|
|
419
|
+
* // Output file closed
|
|
452
420
|
* ```
|
|
421
|
+
*
|
|
422
|
+
* @see {@link openOutput} To open output
|
|
453
423
|
*/
|
|
454
424
|
async closeOutput() {
|
|
455
|
-
return this.native.closeOutput();
|
|
425
|
+
return await this.native.closeOutput();
|
|
456
426
|
}
|
|
457
427
|
/**
|
|
458
|
-
* Open
|
|
459
|
-
*
|
|
460
|
-
* Opens the specified URL, reads the format header, and initializes the stream information.
|
|
461
|
-
* Automatically detects the format if not specified.
|
|
428
|
+
* Open input file for reading.
|
|
462
429
|
*
|
|
463
|
-
*
|
|
430
|
+
* Opens and probes the input file, detecting format automatically
|
|
431
|
+
* unless specified.
|
|
464
432
|
*
|
|
465
|
-
*
|
|
466
|
-
* @param fmt - Input format. May be null to auto-detect
|
|
467
|
-
* @param options - Dictionary of options. May be null
|
|
433
|
+
* Direct mapping to avformat_open_input().
|
|
468
434
|
*
|
|
435
|
+
* @param url - URL or file path to open
|
|
436
|
+
* @param fmt - Force specific input format (null for auto-detect)
|
|
437
|
+
* @param options - Format-specific options
|
|
469
438
|
* @returns 0 on success, negative AVERROR on error:
|
|
470
|
-
* -
|
|
471
|
-
* -
|
|
472
|
-
* -
|
|
473
|
-
* - AVERROR(EINVAL): Invalid data found
|
|
474
|
-
* - AVERROR(ENOMEM): Memory allocation failure
|
|
475
|
-
* - <0: Other format-specific errors
|
|
439
|
+
* - AVERROR_ENOENT: File not found
|
|
440
|
+
* - AVERROR_INVALIDDATA: Invalid file format
|
|
441
|
+
* - AVERROR_EIO: I/O error
|
|
476
442
|
*
|
|
477
443
|
* @example
|
|
478
444
|
* ```typescript
|
|
479
|
-
* import {
|
|
445
|
+
* import { FFmpegError } from 'node-av';
|
|
480
446
|
*
|
|
481
|
-
* const ret = await ctx.openInput('
|
|
447
|
+
* const ret = await ctx.openInput('input.mp4');
|
|
482
448
|
* FFmpegError.throwIfError(ret, 'openInput');
|
|
483
|
-
* // Context is now open and header is read
|
|
484
449
|
* ```
|
|
450
|
+
*
|
|
451
|
+
* @see {@link findStreamInfo} To analyze streams after opening
|
|
452
|
+
* @see {@link closeInput} To close input
|
|
485
453
|
*/
|
|
486
454
|
async openInput(url, fmt = null, options = null) {
|
|
487
|
-
return this.native.openInput(url, fmt?.getNative() ?? null, options?.getNative() ?? null);
|
|
455
|
+
return await this.native.openInput(url, fmt?.getNative() ?? null, options?.getNative() ?? null);
|
|
488
456
|
}
|
|
489
457
|
/**
|
|
490
|
-
*
|
|
458
|
+
* Analyze streams to get stream info.
|
|
491
459
|
*
|
|
492
|
-
*
|
|
493
|
-
*
|
|
460
|
+
* Reads packet headers to fill in stream information.
|
|
461
|
+
* Should be called after openInput for accurate stream data.
|
|
494
462
|
*
|
|
495
|
-
* Direct mapping to avformat_find_stream_info()
|
|
496
|
-
*
|
|
497
|
-
* @param options - Dictionary of options per stream. May be null
|
|
463
|
+
* Direct mapping to avformat_find_stream_info().
|
|
498
464
|
*
|
|
465
|
+
* @param options - Per-stream options array
|
|
499
466
|
* @returns >=0 on success, negative AVERROR on error:
|
|
500
|
-
* -
|
|
501
|
-
* -
|
|
502
|
-
* - AVERROR(ENOMEM): Memory allocation failure
|
|
503
|
-
* - <0: Other errors
|
|
467
|
+
* - AVERROR_EOF: End of file reached
|
|
468
|
+
* - AVERROR_ENOMEM: Memory allocation failure
|
|
504
469
|
*
|
|
505
470
|
* @example
|
|
506
471
|
* ```typescript
|
|
507
|
-
* import {
|
|
472
|
+
* import { FFmpegError } from 'node-av';
|
|
508
473
|
*
|
|
509
|
-
* const ret = await ctx.findStreamInfo(
|
|
474
|
+
* const ret = await ctx.findStreamInfo();
|
|
510
475
|
* FFmpegError.throwIfError(ret, 'findStreamInfo');
|
|
511
476
|
* console.log(`Found ${ctx.nbStreams} streams`);
|
|
512
477
|
* ```
|
|
478
|
+
*
|
|
479
|
+
* @see {@link openInput} Must be called first
|
|
513
480
|
*/
|
|
514
481
|
async findStreamInfo(options = null) {
|
|
515
|
-
return this.native.findStreamInfo(options?.map((d) => d.getNative()) ?? null);
|
|
482
|
+
return await this.native.findStreamInfo(options?.map((d) => d.getNative()) ?? null);
|
|
516
483
|
}
|
|
517
484
|
/**
|
|
518
|
-
* Read
|
|
485
|
+
* Read next packet from the input.
|
|
519
486
|
*
|
|
520
|
-
* Reads and returns the next packet
|
|
521
|
-
*
|
|
487
|
+
* Reads and returns the next packet in the stream.
|
|
488
|
+
* Packet must be unreferenced after use.
|
|
522
489
|
*
|
|
523
|
-
* Direct mapping to av_read_frame()
|
|
524
|
-
*
|
|
525
|
-
* @param pkt - Packet to fill with data
|
|
490
|
+
* Direct mapping to av_read_frame().
|
|
526
491
|
*
|
|
492
|
+
* @param pkt - Packet to read into
|
|
527
493
|
* @returns 0 on success, negative AVERROR on error:
|
|
528
|
-
* -
|
|
529
|
-
* -
|
|
530
|
-
* - AVERROR(EAGAIN): Temporarily unavailable
|
|
531
|
-
* - AVERROR(EIO): I/O error
|
|
532
|
-
* - <0: Other errors
|
|
494
|
+
* - AVERROR_EOF: End of file
|
|
495
|
+
* - AVERROR_EAGAIN: Temporarily unavailable
|
|
533
496
|
*
|
|
534
497
|
* @example
|
|
535
498
|
* ```typescript
|
|
536
|
-
* import {
|
|
499
|
+
* import { FFmpegError } from 'node-av';
|
|
500
|
+
* import { AVERROR_EOF } from 'node-av';
|
|
537
501
|
*
|
|
538
502
|
* const packet = new Packet();
|
|
539
503
|
* packet.alloc();
|
|
540
504
|
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
* if (ret === AVERROR_EOF) break;
|
|
544
|
-
* FFmpegError.throwIfError(ret, 'readFrame');
|
|
545
|
-
*
|
|
505
|
+
* let ret;
|
|
506
|
+
* while ((ret = await ctx.readFrame(packet)) >= 0) {
|
|
546
507
|
* // Process packet
|
|
547
508
|
* console.log(`Stream ${packet.streamIndex}, PTS: ${packet.pts}`);
|
|
548
509
|
* packet.unref();
|
|
549
510
|
* }
|
|
511
|
+
*
|
|
512
|
+
* if (ret !== AVERROR_EOF) {
|
|
513
|
+
* FFmpegError.throwIfError(ret, 'readFrame');
|
|
514
|
+
* }
|
|
550
515
|
* ```
|
|
516
|
+
*
|
|
517
|
+
* @see {@link seekFrame} To seek before reading
|
|
551
518
|
*/
|
|
552
519
|
async readFrame(pkt) {
|
|
553
|
-
return this.native.readFrame(pkt.getNative());
|
|
520
|
+
return await this.native.readFrame(pkt.getNative());
|
|
554
521
|
}
|
|
555
522
|
/**
|
|
556
|
-
* Seek to
|
|
557
|
-
*
|
|
558
|
-
* Seeks to the keyframe at or before the specified timestamp.
|
|
559
|
-
* The next packet read will be from the new position.
|
|
523
|
+
* Seek to timestamp in stream.
|
|
560
524
|
*
|
|
561
|
-
*
|
|
525
|
+
* Seeks to the keyframe at or before the given timestamp.
|
|
562
526
|
*
|
|
563
|
-
*
|
|
564
|
-
* @param timestamp - Timestamp in stream time_base units or AV_TIME_BASE if stream_index is -1
|
|
565
|
-
* @param flags - AVSEEK_FLAG_* flags
|
|
527
|
+
* Direct mapping to av_seek_frame().
|
|
566
528
|
*
|
|
529
|
+
* @param streamIndex - Stream to seek in (-1 for default)
|
|
530
|
+
* @param timestamp - Target timestamp in stream time base
|
|
531
|
+
* @param flags - Seek flags (AVSEEK_FLAG_*)
|
|
567
532
|
* @returns >=0 on success, negative AVERROR on error:
|
|
568
|
-
* -
|
|
569
|
-
* -
|
|
570
|
-
* - AVERROR(EIO): I/O error
|
|
571
|
-
* - <0: Other errors
|
|
533
|
+
* - AVERROR_EINVAL: Invalid parameters
|
|
534
|
+
* - AVERROR_EOF: Seek beyond file
|
|
572
535
|
*
|
|
573
536
|
* @example
|
|
574
537
|
* ```typescript
|
|
575
|
-
* import {
|
|
538
|
+
* import { FFmpegError } from 'node-av';
|
|
539
|
+
* import { AVSEEK_FLAG_BACKWARD } from 'node-av/constants';
|
|
576
540
|
*
|
|
577
|
-
* // Seek to 10 seconds
|
|
578
|
-
* const
|
|
579
|
-
* const ret = await ctx.seekFrame(-1, timestamp, AVSEEK_FLAG_BACKWARD);
|
|
541
|
+
* // Seek to 10 seconds (assuming 1/1000 time base)
|
|
542
|
+
* const ret = await ctx.seekFrame(videoStreamIndex, 10000n, AVSEEK_FLAG_BACKWARD);
|
|
580
543
|
* FFmpegError.throwIfError(ret, 'seekFrame');
|
|
581
|
-
* // Next readFrame will return packet from new position
|
|
582
544
|
* ```
|
|
545
|
+
*
|
|
546
|
+
* @see {@link seekFile} For more precise seeking
|
|
583
547
|
*/
|
|
584
548
|
async seekFrame(streamIndex, timestamp, flags = AVFLAG_NONE) {
|
|
585
|
-
return this.native.seekFrame(streamIndex, timestamp, flags);
|
|
549
|
+
return await this.native.seekFrame(streamIndex, timestamp, flags);
|
|
586
550
|
}
|
|
587
551
|
/**
|
|
588
|
-
* Seek to timestamp
|
|
552
|
+
* Seek to timestamp with bounds.
|
|
589
553
|
*
|
|
590
|
-
*
|
|
591
|
-
* More precise than seekFrame() with tolerance control.
|
|
554
|
+
* More precise seeking with min/max timestamp bounds.
|
|
592
555
|
*
|
|
593
|
-
* Direct mapping to avformat_seek_file()
|
|
556
|
+
* Direct mapping to avformat_seek_file().
|
|
594
557
|
*
|
|
595
|
-
* @param streamIndex - Stream
|
|
596
|
-
* @param minTs -
|
|
558
|
+
* @param streamIndex - Stream to seek in (-1 for default)
|
|
559
|
+
* @param minTs - Minimum acceptable timestamp
|
|
597
560
|
* @param ts - Target timestamp
|
|
598
|
-
* @param maxTs -
|
|
599
|
-
* @param flags -
|
|
600
|
-
*
|
|
601
|
-
* @returns >=0 on success, negative AVERROR on error:
|
|
602
|
-
* - >=0: Success
|
|
603
|
-
* - AVERROR(EINVAL): Invalid arguments
|
|
604
|
-
* - AVERROR(EIO): I/O error
|
|
605
|
-
* - <0: Other errors
|
|
561
|
+
* @param maxTs - Maximum acceptable timestamp
|
|
562
|
+
* @param flags - Seek flags
|
|
563
|
+
* @returns >=0 on success, negative AVERROR on error
|
|
606
564
|
*
|
|
607
565
|
* @example
|
|
608
566
|
* ```typescript
|
|
609
|
-
* import {
|
|
567
|
+
* import { FFmpegError } from 'node-av';
|
|
610
568
|
*
|
|
611
|
-
* // Seek to
|
|
612
|
-
* const target =
|
|
613
|
-
* const tolerance = BigInt(AV_TIME_BASE);
|
|
569
|
+
* // Seek to 10s with 0.5s tolerance
|
|
570
|
+
* const target = 10000n;
|
|
614
571
|
* const ret = await ctx.seekFile(
|
|
615
572
|
* -1,
|
|
616
|
-
* target -
|
|
617
|
-
* target,
|
|
618
|
-
* target +
|
|
619
|
-
* 0
|
|
573
|
+
* target - 500n,
|
|
574
|
+
* target,
|
|
575
|
+
* target + 500n
|
|
620
576
|
* );
|
|
621
577
|
* FFmpegError.throwIfError(ret, 'seekFile');
|
|
622
578
|
* ```
|
|
579
|
+
*
|
|
580
|
+
* @see {@link seekFrame} For simpler seeking
|
|
623
581
|
*/
|
|
624
582
|
async seekFile(streamIndex, minTs, ts, maxTs, flags = AVFLAG_NONE) {
|
|
625
|
-
return this.native.seekFile(streamIndex, minTs, ts, maxTs, flags);
|
|
583
|
+
return await this.native.seekFile(streamIndex, minTs, ts, maxTs, flags);
|
|
626
584
|
}
|
|
627
585
|
/**
|
|
628
|
-
*
|
|
629
|
-
*
|
|
630
|
-
* Initializes the output file and writes the file header.
|
|
631
|
-
* Must be called before writing any packets.
|
|
586
|
+
* Write file header.
|
|
632
587
|
*
|
|
633
|
-
*
|
|
588
|
+
* Writes the file header and initializes output.
|
|
589
|
+
* Must be called before writing packets.
|
|
634
590
|
*
|
|
635
|
-
*
|
|
591
|
+
* Direct mapping to avformat_write_header().
|
|
636
592
|
*
|
|
593
|
+
* @param options - Muxer-specific options
|
|
637
594
|
* @returns 0 on success, negative AVERROR on error:
|
|
638
|
-
* -
|
|
639
|
-
* -
|
|
640
|
-
* - AVERROR(EIO): I/O error
|
|
641
|
-
* - AVERROR(ENOMEM): Memory allocation failure
|
|
642
|
-
* - <0: Other muxer-specific errors
|
|
595
|
+
* - AVERROR_EINVAL: Invalid parameters
|
|
596
|
+
* - AVERROR_EIO: I/O error
|
|
643
597
|
*
|
|
644
598
|
* @example
|
|
645
599
|
* ```typescript
|
|
646
|
-
* import {
|
|
647
|
-
*
|
|
648
|
-
* const options = new Dictionary();
|
|
649
|
-
* options.set('movflags', 'faststart', 0);
|
|
600
|
+
* import { FFmpegError } from 'node-av';
|
|
650
601
|
*
|
|
651
|
-
* const ret = await ctx.writeHeader(
|
|
602
|
+
* const ret = await ctx.writeHeader();
|
|
652
603
|
* FFmpegError.throwIfError(ret, 'writeHeader');
|
|
653
|
-
*
|
|
654
|
-
* // Header written, ready to write packets
|
|
604
|
+
* // Now ready to write packets
|
|
655
605
|
* ```
|
|
606
|
+
*
|
|
607
|
+
* @see {@link writeTrailer} To finalize file
|
|
608
|
+
* @see {@link writeFrame} To write packets
|
|
656
609
|
*/
|
|
657
610
|
async writeHeader(options = null) {
|
|
658
|
-
return this.native.writeHeader(options?.getNative() ?? null);
|
|
611
|
+
return await this.native.writeHeader(options?.getNative() ?? null);
|
|
659
612
|
}
|
|
660
613
|
/**
|
|
661
|
-
* Write
|
|
662
|
-
*
|
|
663
|
-
* Writes a packet directly without reordering.
|
|
664
|
-
* Use interleavedWriteFrame() for automatic interleaving.
|
|
614
|
+
* Write packet to output.
|
|
665
615
|
*
|
|
666
|
-
*
|
|
616
|
+
* Writes a packet directly without interleaving.
|
|
617
|
+
* Caller must handle correct interleaving.
|
|
667
618
|
*
|
|
668
|
-
*
|
|
619
|
+
* Direct mapping to av_write_frame().
|
|
669
620
|
*
|
|
621
|
+
* @param pkt - Packet to write (null to flush)
|
|
670
622
|
* @returns 0 on success, negative AVERROR on error:
|
|
671
|
-
* -
|
|
672
|
-
* -
|
|
673
|
-
* - AVERROR(EIO): I/O error
|
|
674
|
-
* - <0: Other muxer-specific errors
|
|
623
|
+
* - AVERROR_EINVAL: Invalid packet
|
|
624
|
+
* - AVERROR_EIO: I/O error
|
|
675
625
|
*
|
|
676
626
|
* @example
|
|
677
627
|
* ```typescript
|
|
678
|
-
* import {
|
|
628
|
+
* import { FFmpegError } from 'node-av';
|
|
679
629
|
*
|
|
680
630
|
* const ret = await ctx.writeFrame(packet);
|
|
681
631
|
* FFmpegError.throwIfError(ret, 'writeFrame');
|
|
682
|
-
*
|
|
683
|
-
* // Flush at the end
|
|
684
|
-
* const flushRet = await ctx.writeFrame(null);
|
|
685
|
-
* FFmpegError.throwIfError(flushRet, 'writeFrame flush');
|
|
686
632
|
* ```
|
|
687
633
|
*
|
|
688
|
-
* @note This function does NOT take ownership of the packet.
|
|
689
|
-
*
|
|
690
634
|
* @see {@link interleavedWriteFrame} For automatic interleaving
|
|
691
635
|
*/
|
|
692
636
|
async writeFrame(pkt) {
|
|
693
|
-
return this.native.writeFrame(pkt ? pkt.getNative() : null);
|
|
637
|
+
return await this.native.writeFrame(pkt ? pkt.getNative() : null);
|
|
694
638
|
}
|
|
695
639
|
/**
|
|
696
|
-
* Write
|
|
697
|
-
*
|
|
698
|
-
* Automatically interleaves packets from different streams based on DTS.
|
|
699
|
-
* Preferred method for writing packets in most cases.
|
|
640
|
+
* Write packet with automatic interleaving.
|
|
700
641
|
*
|
|
701
|
-
*
|
|
642
|
+
* Writes packet with proper interleaving for muxing.
|
|
643
|
+
* Preferred method for writing packets.
|
|
702
644
|
*
|
|
703
|
-
*
|
|
645
|
+
* Direct mapping to av_interleaved_write_frame().
|
|
704
646
|
*
|
|
647
|
+
* @param pkt - Packet to write (null to flush)
|
|
705
648
|
* @returns 0 on success, negative AVERROR on error:
|
|
706
|
-
* -
|
|
707
|
-
* -
|
|
708
|
-
* - AVERROR(EIO): I/O error
|
|
709
|
-
* - <0: Other muxer-specific errors
|
|
649
|
+
* - AVERROR_EINVAL: Invalid packet
|
|
650
|
+
* - AVERROR_EIO: I/O error
|
|
710
651
|
*
|
|
711
652
|
* @example
|
|
712
653
|
* ```typescript
|
|
713
|
-
* import {
|
|
654
|
+
* import { FFmpegError } from 'node-av';
|
|
714
655
|
*
|
|
715
|
-
* // Write
|
|
656
|
+
* // Write with proper interleaving
|
|
716
657
|
* const ret = await ctx.interleavedWriteFrame(packet);
|
|
717
658
|
* FFmpegError.throwIfError(ret, 'interleavedWriteFrame');
|
|
718
|
-
* // Packet is automatically freed after writing
|
|
719
|
-
* ```
|
|
720
659
|
*
|
|
721
|
-
*
|
|
660
|
+
* // Flush buffered packets
|
|
661
|
+
* await ctx.interleavedWriteFrame(null);
|
|
662
|
+
* ```
|
|
722
663
|
*
|
|
723
|
-
* @see {@link writeFrame} For
|
|
664
|
+
* @see {@link writeFrame} For direct writing
|
|
724
665
|
*/
|
|
725
666
|
async interleavedWriteFrame(pkt) {
|
|
726
|
-
return this.native.interleavedWriteFrame(pkt ? pkt.getNative() : null);
|
|
667
|
+
return await this.native.interleavedWriteFrame(pkt ? pkt.getNative() : null);
|
|
727
668
|
}
|
|
728
669
|
/**
|
|
729
|
-
* Write
|
|
670
|
+
* Write file trailer.
|
|
730
671
|
*
|
|
731
|
-
* Finalizes the output file
|
|
732
|
-
* Must be called
|
|
672
|
+
* Finalizes the output file, writing index and metadata.
|
|
673
|
+
* Must be called to properly close output files.
|
|
733
674
|
*
|
|
734
|
-
* Direct mapping to av_write_trailer()
|
|
675
|
+
* Direct mapping to av_write_trailer().
|
|
735
676
|
*
|
|
736
677
|
* @returns 0 on success, negative AVERROR on error:
|
|
737
|
-
* -
|
|
738
|
-
* - AVERROR(EIO): I/O error
|
|
739
|
-
* - <0: Other muxer-specific errors
|
|
678
|
+
* - AVERROR_EIO: I/O error
|
|
740
679
|
*
|
|
741
680
|
* @example
|
|
742
681
|
* ```typescript
|
|
743
|
-
* import {
|
|
682
|
+
* import { FFmpegError } from 'node-av';
|
|
744
683
|
*
|
|
745
|
-
* // Finalize the output file
|
|
746
684
|
* const ret = await ctx.writeTrailer();
|
|
747
685
|
* FFmpegError.throwIfError(ret, 'writeTrailer');
|
|
748
|
-
* // File is now
|
|
686
|
+
* // File is now finalized
|
|
749
687
|
* ```
|
|
750
688
|
*
|
|
751
|
-
* @
|
|
689
|
+
* @see {@link writeHeader} Must be called first
|
|
752
690
|
*/
|
|
753
691
|
async writeTrailer() {
|
|
754
|
-
return this.native.writeTrailer();
|
|
692
|
+
return await this.native.writeTrailer();
|
|
755
693
|
}
|
|
756
694
|
/**
|
|
757
|
-
* Flush
|
|
695
|
+
* Flush buffered data.
|
|
758
696
|
*
|
|
759
|
-
*
|
|
697
|
+
* Flushes any buffered packets in muxers.
|
|
698
|
+
*
|
|
699
|
+
* Direct mapping to avio_flush().
|
|
760
700
|
*
|
|
761
701
|
* @example
|
|
762
702
|
* ```typescript
|
|
763
|
-
* import { FormatContext } from 'node-av';
|
|
764
|
-
*
|
|
765
|
-
* // Flush buffered data
|
|
766
703
|
* ctx.flush();
|
|
767
|
-
* //
|
|
704
|
+
* // Buffered data written to output
|
|
768
705
|
* ```
|
|
769
706
|
*/
|
|
770
707
|
flush() {
|
|
771
|
-
|
|
708
|
+
this.native.flush();
|
|
772
709
|
}
|
|
773
710
|
/**
|
|
774
|
-
*
|
|
711
|
+
* Print format information.
|
|
775
712
|
*
|
|
776
|
-
*
|
|
777
|
-
* Useful for debugging
|
|
713
|
+
* Dumps human-readable format info to stderr.
|
|
714
|
+
* Useful for debugging.
|
|
778
715
|
*
|
|
779
|
-
* Direct mapping to av_dump_format()
|
|
716
|
+
* Direct mapping to av_dump_format().
|
|
780
717
|
*
|
|
781
|
-
* @param index - Stream index
|
|
782
|
-
* @param url - URL
|
|
783
|
-
* @param isOutput -
|
|
718
|
+
* @param index - Stream index to highlight (-1 for none)
|
|
719
|
+
* @param url - URL to display
|
|
720
|
+
* @param isOutput - True for output format, false for input
|
|
784
721
|
*
|
|
785
722
|
* @example
|
|
786
723
|
* ```typescript
|
|
787
|
-
* import { FormatContext } from 'node-av';
|
|
788
|
-
*
|
|
789
724
|
* // Dump input format info
|
|
790
|
-
*
|
|
725
|
+
* ctx.dumpFormat(0, 'input.mp4', false);
|
|
791
726
|
*
|
|
792
727
|
* // Dump output format info
|
|
793
|
-
*
|
|
728
|
+
* ctx.dumpFormat(0, 'output.mp4', true);
|
|
794
729
|
* ```
|
|
795
730
|
*/
|
|
796
731
|
dumpFormat(index, url, isOutput) {
|
|
@@ -812,63 +747,56 @@ export class FormatContext extends OptionMember {
|
|
|
812
747
|
return this.native.findBestStream(type, wantedStreamNb, relatedStream, false, flags ?? 0);
|
|
813
748
|
}
|
|
814
749
|
/**
|
|
815
|
-
* Add a new stream to
|
|
816
|
-
*
|
|
817
|
-
* Creates a new stream in the output format context.
|
|
818
|
-
* The stream must be configured before calling writeHeader().
|
|
819
|
-
*
|
|
820
|
-
* Direct mapping to avformat_new_stream()
|
|
750
|
+
* Add a new stream to output context.
|
|
821
751
|
*
|
|
822
|
-
*
|
|
752
|
+
* Creates a new stream for writing.
|
|
823
753
|
*
|
|
824
|
-
*
|
|
754
|
+
* Direct mapping to avformat_new_stream().
|
|
825
755
|
*
|
|
826
|
-
* @
|
|
756
|
+
* @param c - Codec for the stream (optional)
|
|
757
|
+
* @returns New stream instance
|
|
827
758
|
*
|
|
828
759
|
* @example
|
|
829
760
|
* ```typescript
|
|
830
|
-
* import {
|
|
831
|
-
* import { AV_CODEC_ID_H264
|
|
832
|
-
*
|
|
833
|
-
*
|
|
834
|
-
* const
|
|
835
|
-
*
|
|
836
|
-
*
|
|
837
|
-
* // Configure stream parameters
|
|
838
|
-
* videoStream.codecpar.codecType = AVMEDIA_TYPE_VIDEO;
|
|
839
|
-
* videoStream.codecpar.codecId = AV_CODEC_ID_H264;
|
|
840
|
-
* videoStream.codecpar.width = 1920;
|
|
841
|
-
* videoStream.codecpar.height = 1080;
|
|
761
|
+
* import { Codec } from 'node-av';
|
|
762
|
+
* import { AV_CODEC_ID_H264 } from 'node-av/constants';
|
|
763
|
+
*
|
|
764
|
+
* const codec = Codec.findEncoder(AV_CODEC_ID_H264);
|
|
765
|
+
* const stream = ctx.newStream(codec);
|
|
766
|
+
* stream.id = ctx.nbStreams - 1;
|
|
842
767
|
* ```
|
|
768
|
+
*
|
|
769
|
+
* @see {@link Stream} For stream configuration
|
|
843
770
|
*/
|
|
844
771
|
newStream(c = null) {
|
|
845
772
|
const nativeStream = this.native.newStream(c?.getNative() ?? null);
|
|
846
773
|
return new Stream(nativeStream);
|
|
847
774
|
}
|
|
848
775
|
/**
|
|
849
|
-
* Get the native
|
|
776
|
+
* Get the underlying native FormatContext object.
|
|
777
|
+
*
|
|
778
|
+
* @returns The native FormatContext binding object
|
|
850
779
|
*
|
|
851
|
-
* @internal
|
|
852
|
-
* @returns The underlying native format context object
|
|
780
|
+
* @internal
|
|
853
781
|
*/
|
|
854
782
|
getNative() {
|
|
855
783
|
return this.native;
|
|
856
784
|
}
|
|
857
785
|
/**
|
|
858
|
-
* Dispose of the format context
|
|
786
|
+
* Dispose of the format context.
|
|
859
787
|
*
|
|
860
788
|
* Implements the AsyncDisposable interface for automatic cleanup.
|
|
861
|
-
*
|
|
789
|
+
* Closes input/output and frees resources.
|
|
790
|
+
*
|
|
791
|
+
* @returns Promise that resolves when disposed
|
|
862
792
|
*
|
|
863
793
|
* @example
|
|
864
794
|
* ```typescript
|
|
865
|
-
* import { FormatContext } from 'node-av';
|
|
866
|
-
*
|
|
867
795
|
* {
|
|
868
796
|
* await using ctx = new FormatContext();
|
|
869
|
-
* await ctx.openInput('
|
|
870
|
-
* //
|
|
871
|
-
* } // Automatically closed
|
|
797
|
+
* await ctx.openInput('input.mp4');
|
|
798
|
+
* // Use context...
|
|
799
|
+
* } // Automatically closed and freed
|
|
872
800
|
* ```
|
|
873
801
|
*/
|
|
874
802
|
async [Symbol.asyncDispose]() {
|