node-av 0.0.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/CHANGELOG.md +8 -0
- package/LICENSE.md +22 -0
- package/README.md +377 -0
- package/binding.gyp +78 -0
- package/dist/api/bitstream-filter.d.ts +246 -0
- package/dist/api/bitstream-filter.js +369 -0
- package/dist/api/bitstream-filter.js.map +1 -0
- package/dist/api/decoder.d.ts +257 -0
- package/dist/api/decoder.js +424 -0
- package/dist/api/decoder.js.map +1 -0
- package/dist/api/encoder.d.ts +298 -0
- package/dist/api/encoder.js +574 -0
- package/dist/api/encoder.js.map +1 -0
- package/dist/api/filter.d.ts +457 -0
- package/dist/api/filter.js +876 -0
- package/dist/api/filter.js.map +1 -0
- package/dist/api/hardware.d.ts +318 -0
- package/dist/api/hardware.js +558 -0
- package/dist/api/hardware.js.map +1 -0
- package/dist/api/index.d.ts +12 -0
- package/dist/api/index.js +20 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/io-stream.d.ts +109 -0
- package/dist/api/io-stream.js +124 -0
- package/dist/api/io-stream.js.map +1 -0
- package/dist/api/media-input.d.ts +295 -0
- package/dist/api/media-input.js +456 -0
- package/dist/api/media-input.js.map +1 -0
- package/dist/api/media-output.d.ts +274 -0
- package/dist/api/media-output.js +486 -0
- package/dist/api/media-output.js.map +1 -0
- package/dist/api/pipeline.d.ts +117 -0
- package/dist/api/pipeline.js +836 -0
- package/dist/api/pipeline.js.map +1 -0
- package/dist/api/types.d.ts +440 -0
- package/dist/api/types.js +2 -0
- package/dist/api/types.js.map +1 -0
- package/dist/api/utilities/audio-sample.d.ts +115 -0
- package/dist/api/utilities/audio-sample.js +110 -0
- package/dist/api/utilities/audio-sample.js.map +1 -0
- package/dist/api/utilities/channel-layout.d.ts +83 -0
- package/dist/api/utilities/channel-layout.js +87 -0
- package/dist/api/utilities/channel-layout.js.map +1 -0
- package/dist/api/utilities/image.d.ts +177 -0
- package/dist/api/utilities/image.js +183 -0
- package/dist/api/utilities/image.js.map +1 -0
- package/dist/api/utilities/index.d.ts +8 -0
- package/dist/api/utilities/index.js +17 -0
- package/dist/api/utilities/index.js.map +1 -0
- package/dist/api/utilities/media-type.d.ts +56 -0
- package/dist/api/utilities/media-type.js +60 -0
- package/dist/api/utilities/media-type.js.map +1 -0
- package/dist/api/utilities/pixel-format.d.ts +94 -0
- package/dist/api/utilities/pixel-format.js +102 -0
- package/dist/api/utilities/pixel-format.js.map +1 -0
- package/dist/api/utilities/sample-format.d.ts +132 -0
- package/dist/api/utilities/sample-format.js +144 -0
- package/dist/api/utilities/sample-format.js.map +1 -0
- package/dist/api/utilities/streaming.d.ts +104 -0
- package/dist/api/utilities/streaming.js +137 -0
- package/dist/api/utilities/streaming.js.map +1 -0
- package/dist/api/utilities/timestamp.d.ts +187 -0
- package/dist/api/utilities/timestamp.js +200 -0
- package/dist/api/utilities/timestamp.js.map +1 -0
- package/dist/api/utils.d.ts +61 -0
- package/dist/api/utils.js +330 -0
- package/dist/api/utils.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +5 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/audio-fifo.d.ts +339 -0
- package/dist/lib/audio-fifo.js +365 -0
- package/dist/lib/audio-fifo.js.map +1 -0
- package/dist/lib/binding.d.ts +192 -0
- package/dist/lib/binding.js +70 -0
- package/dist/lib/binding.js.map +1 -0
- package/dist/lib/bitstream-filter-context.d.ts +345 -0
- package/dist/lib/bitstream-filter-context.js +407 -0
- package/dist/lib/bitstream-filter-context.js.map +1 -0
- package/dist/lib/bitstream-filter.d.ts +124 -0
- package/dist/lib/bitstream-filter.js +138 -0
- package/dist/lib/bitstream-filter.js.map +1 -0
- package/dist/lib/channel-layouts.d.ts +51 -0
- package/dist/lib/channel-layouts.js +55 -0
- package/dist/lib/channel-layouts.js.map +1 -0
- package/dist/lib/codec-context.d.ts +763 -0
- package/dist/lib/codec-context.js +974 -0
- package/dist/lib/codec-context.js.map +1 -0
- package/dist/lib/codec-parameters.d.ts +362 -0
- package/dist/lib/codec-parameters.js +460 -0
- package/dist/lib/codec-parameters.js.map +1 -0
- package/dist/lib/codec-parser.d.ts +185 -0
- package/dist/lib/codec-parser.js +193 -0
- package/dist/lib/codec-parser.js.map +1 -0
- package/dist/lib/codec.d.ts +432 -0
- package/dist/lib/codec.js +492 -0
- package/dist/lib/codec.js.map +1 -0
- package/dist/lib/constants.d.ts +2037 -0
- package/dist/lib/constants.js +1659 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/dictionary.d.ts +371 -0
- package/dist/lib/dictionary.js +406 -0
- package/dist/lib/dictionary.js.map +1 -0
- package/dist/lib/error.d.ts +216 -0
- package/dist/lib/error.js +254 -0
- package/dist/lib/error.js.map +1 -0
- package/dist/lib/filter-context.d.ts +445 -0
- package/dist/lib/filter-context.js +505 -0
- package/dist/lib/filter-context.js.map +1 -0
- package/dist/lib/filter-graph.d.ts +556 -0
- package/dist/lib/filter-graph.js +608 -0
- package/dist/lib/filter-graph.js.map +1 -0
- package/dist/lib/filter-inout.d.ts +205 -0
- package/dist/lib/filter-inout.js +264 -0
- package/dist/lib/filter-inout.js.map +1 -0
- package/dist/lib/filter.d.ts +231 -0
- package/dist/lib/filter.js +260 -0
- package/dist/lib/filter.js.map +1 -0
- package/dist/lib/format-context.d.ts +798 -0
- package/dist/lib/format-context.js +845 -0
- package/dist/lib/format-context.js.map +1 -0
- package/dist/lib/frame.d.ts +784 -0
- package/dist/lib/frame.js +933 -0
- package/dist/lib/frame.js.map +1 -0
- package/dist/lib/hardware-device-context.d.ts +407 -0
- package/dist/lib/hardware-device-context.js +429 -0
- package/dist/lib/hardware-device-context.js.map +1 -0
- package/dist/lib/hardware-frames-context.d.ts +374 -0
- package/dist/lib/hardware-frames-context.js +430 -0
- package/dist/lib/hardware-frames-context.js.map +1 -0
- package/dist/lib/index.d.ts +31 -0
- package/dist/lib/index.js +54 -0
- package/dist/lib/index.js.map +1 -0
- package/dist/lib/input-format.d.ts +216 -0
- package/dist/lib/input-format.js +246 -0
- package/dist/lib/input-format.js.map +1 -0
- package/dist/lib/io-context.d.ts +495 -0
- package/dist/lib/io-context.js +550 -0
- package/dist/lib/io-context.js.map +1 -0
- package/dist/lib/log.d.ts +201 -0
- package/dist/lib/log.js +219 -0
- package/dist/lib/log.js.map +1 -0
- package/dist/lib/native-types.d.ts +719 -0
- package/dist/lib/native-types.js +2 -0
- package/dist/lib/native-types.js.map +1 -0
- package/dist/lib/option.d.ts +589 -0
- package/dist/lib/option.js +853 -0
- package/dist/lib/option.js.map +1 -0
- package/dist/lib/output-format.d.ts +179 -0
- package/dist/lib/output-format.js +205 -0
- package/dist/lib/output-format.js.map +1 -0
- package/dist/lib/packet.d.ts +487 -0
- package/dist/lib/packet.js +558 -0
- package/dist/lib/packet.js.map +1 -0
- package/dist/lib/rational.d.ts +210 -0
- package/dist/lib/rational.js +233 -0
- package/dist/lib/rational.js.map +1 -0
- package/dist/lib/software-resample-context.d.ts +572 -0
- package/dist/lib/software-resample-context.js +610 -0
- package/dist/lib/software-resample-context.js.map +1 -0
- package/dist/lib/software-scale-context.d.ts +290 -0
- package/dist/lib/software-scale-context.js +308 -0
- package/dist/lib/software-scale-context.js.map +1 -0
- package/dist/lib/stream.d.ts +322 -0
- package/dist/lib/stream.js +408 -0
- package/dist/lib/stream.js.map +1 -0
- package/dist/lib/types.d.ts +59 -0
- package/dist/lib/types.js +8 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/utilities.d.ts +346 -0
- package/dist/lib/utilities.js +424 -0
- package/dist/lib/utilities.js.map +1 -0
- package/install/check.js +113 -0
- package/install/ffmpeg.js +163 -0
- package/package.json +107 -0
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
import { bindings } from './binding.js';
|
|
2
|
+
import { Codec } from './codec.js';
|
|
3
|
+
import { AVFLAG_NONE } from './constants.js';
|
|
4
|
+
import { Dictionary } from './dictionary.js';
|
|
5
|
+
import { InputFormat } from './input-format.js';
|
|
6
|
+
import { OptionMember } from './option.js';
|
|
7
|
+
import { OutputFormat } from './output-format.js';
|
|
8
|
+
import { Stream } from './stream.js';
|
|
9
|
+
/**
|
|
10
|
+
* FFmpeg format context for demuxing and muxing.
|
|
11
|
+
*
|
|
12
|
+
* Central structure for media file handling, managing both input (demuxing) and output (muxing).
|
|
13
|
+
* Provides full control over allocation, configuration and lifecycle with no hidden operations.
|
|
14
|
+
* Handles container formats, streams, metadata, and packet I/O operations.
|
|
15
|
+
*
|
|
16
|
+
* Direct mapping to FFmpeg's AVFormatContext.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* import { FormatContext, Packet, FFmpegError } from 'node-av';
|
|
21
|
+
*
|
|
22
|
+
* // Demuxing - full control over every step
|
|
23
|
+
* const ctx = new FormatContext();
|
|
24
|
+
* ctx.allocContext();
|
|
25
|
+
*
|
|
26
|
+
* const ret = await ctx.openInput('video.mp4', null, null);
|
|
27
|
+
* FFmpegError.throwIfError(ret, 'openInput');
|
|
28
|
+
*
|
|
29
|
+
* const infoRet = await ctx.findStreamInfo(null);
|
|
30
|
+
* FFmpegError.throwIfError(infoRet, 'findStreamInfo');
|
|
31
|
+
*
|
|
32
|
+
* const packet = new Packet();
|
|
33
|
+
* packet.alloc();
|
|
34
|
+
*
|
|
35
|
+
* while (true) {
|
|
36
|
+
* const readRet = await ctx.readFrame(packet);
|
|
37
|
+
* if (readRet < 0) break; // EOF or error
|
|
38
|
+
* // Process packet
|
|
39
|
+
* packet.unref();
|
|
40
|
+
* }
|
|
41
|
+
*
|
|
42
|
+
* await ctx.closeInput();
|
|
43
|
+
* ctx.freeContext();
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* ```typescript
|
|
48
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
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
|
|
74
|
+
* @see {@link Stream} For stream management
|
|
75
|
+
* @see {@link Packet} For packet handling
|
|
76
|
+
*/
|
|
77
|
+
export class FormatContext extends OptionMember {
|
|
78
|
+
_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
|
+
constructor() {
|
|
99
|
+
super(new bindings.FormatContext());
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Input or output URL/filename.
|
|
103
|
+
*
|
|
104
|
+
* Direct mapping to AVFormatContext->url
|
|
105
|
+
*
|
|
106
|
+
* - muxing: Set by user
|
|
107
|
+
* - demuxing: Set by avformat_open_input
|
|
108
|
+
*/
|
|
109
|
+
get url() {
|
|
110
|
+
return this.native.url;
|
|
111
|
+
}
|
|
112
|
+
set url(value) {
|
|
113
|
+
this.native.url = value;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Position of the first frame of the component, in AV_TIME_BASE units.
|
|
117
|
+
*
|
|
118
|
+
* Direct mapping to AVFormatContext->start_time
|
|
119
|
+
*
|
|
120
|
+
* NEVER set this value directly: it is deduced from the AVStream values.
|
|
121
|
+
* - demuxing: Set by libavformat
|
|
122
|
+
*/
|
|
123
|
+
get startTime() {
|
|
124
|
+
return this.native.startTime;
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Duration of the stream, in AV_TIME_BASE units.
|
|
128
|
+
*
|
|
129
|
+
* Direct mapping to AVFormatContext->duration
|
|
130
|
+
*
|
|
131
|
+
* Only set this value if you know none of the individual stream durations.
|
|
132
|
+
* - demuxing: Set by libavformat
|
|
133
|
+
* - muxing: May be set by user
|
|
134
|
+
*/
|
|
135
|
+
get duration() {
|
|
136
|
+
return this.native.duration;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Total stream bitrate in bit/s, 0 if not available.
|
|
140
|
+
*
|
|
141
|
+
* Direct mapping to AVFormatContext->bit_rate
|
|
142
|
+
*
|
|
143
|
+
* Never set directly if the file_size and duration are known.
|
|
144
|
+
*/
|
|
145
|
+
get bitRate() {
|
|
146
|
+
return this.native.bitRate;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Flags modifying demuxer/muxer behavior.
|
|
150
|
+
*
|
|
151
|
+
* Direct mapping to AVFormatContext->flags
|
|
152
|
+
*
|
|
153
|
+
* AVFMT_FLAG_GENPTS, AVFMT_FLAG_IGNIDX, etc.
|
|
154
|
+
* - encoding: Set by user
|
|
155
|
+
* - decoding: Set by user
|
|
156
|
+
*/
|
|
157
|
+
get flags() {
|
|
158
|
+
return this.native.flags;
|
|
159
|
+
}
|
|
160
|
+
set flags(value) {
|
|
161
|
+
this.native.flags = value;
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Maximum size of the data read from input for determining format.
|
|
165
|
+
*
|
|
166
|
+
* Direct mapping to AVFormatContext->probesize
|
|
167
|
+
*
|
|
168
|
+
* - encoding: unused
|
|
169
|
+
* - decoding: Set by user
|
|
170
|
+
*/
|
|
171
|
+
get probesize() {
|
|
172
|
+
return this.native.probesize;
|
|
173
|
+
}
|
|
174
|
+
set probesize(value) {
|
|
175
|
+
this.native.probesize = value;
|
|
176
|
+
}
|
|
177
|
+
/**
|
|
178
|
+
* Maximum duration (in AV_TIME_BASE units) of the data read from input.
|
|
179
|
+
*
|
|
180
|
+
* Direct mapping to AVFormatContext->max_analyze_duration
|
|
181
|
+
*
|
|
182
|
+
* - encoding: unused
|
|
183
|
+
* - decoding: Set by user
|
|
184
|
+
*/
|
|
185
|
+
get maxAnalyzeDuration() {
|
|
186
|
+
return this.native.maxAnalyzeDuration;
|
|
187
|
+
}
|
|
188
|
+
set maxAnalyzeDuration(value) {
|
|
189
|
+
this.native.maxAnalyzeDuration = value;
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Metadata that applies to the whole file.
|
|
193
|
+
*
|
|
194
|
+
* Direct mapping to AVFormatContext->metadata
|
|
195
|
+
*
|
|
196
|
+
* - demuxing: Set by libavformat
|
|
197
|
+
* - muxing: May be set by user
|
|
198
|
+
*/
|
|
199
|
+
get metadata() {
|
|
200
|
+
const nativeDict = this.native.metadata;
|
|
201
|
+
if (!nativeDict) {
|
|
202
|
+
return null;
|
|
203
|
+
}
|
|
204
|
+
return Dictionary.fromNative(nativeDict);
|
|
205
|
+
}
|
|
206
|
+
set metadata(value) {
|
|
207
|
+
this.native.metadata = value?.getNative() ?? null;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Input format (demuxing only).
|
|
211
|
+
*
|
|
212
|
+
* Direct mapping to AVFormatContext->iformat
|
|
213
|
+
*
|
|
214
|
+
* The detected or specified input format.
|
|
215
|
+
*/
|
|
216
|
+
get iformat() {
|
|
217
|
+
const nativeFormat = this.native.iformat;
|
|
218
|
+
if (!nativeFormat) {
|
|
219
|
+
return null;
|
|
220
|
+
}
|
|
221
|
+
return new InputFormat(nativeFormat);
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* Output format (muxing only).
|
|
225
|
+
*
|
|
226
|
+
* Direct mapping to AVFormatContext->oformat
|
|
227
|
+
*
|
|
228
|
+
* The specified output format.
|
|
229
|
+
*/
|
|
230
|
+
get oformat() {
|
|
231
|
+
const nativeFormat = this.native.oformat;
|
|
232
|
+
if (!nativeFormat) {
|
|
233
|
+
return null;
|
|
234
|
+
}
|
|
235
|
+
return new OutputFormat(nativeFormat);
|
|
236
|
+
}
|
|
237
|
+
set oformat(value) {
|
|
238
|
+
this.native.oformat = value?.getNative() ?? null;
|
|
239
|
+
}
|
|
240
|
+
/**
|
|
241
|
+
* I/O context.
|
|
242
|
+
*
|
|
243
|
+
* Direct mapping to AVFormatContext->pb
|
|
244
|
+
*
|
|
245
|
+
* - demuxing: Either set by user or internal (for protocols like file:)
|
|
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.
|
|
250
|
+
*/
|
|
251
|
+
get pb() {
|
|
252
|
+
return this._ioContext;
|
|
253
|
+
}
|
|
254
|
+
set pb(value) {
|
|
255
|
+
this._ioContext = value;
|
|
256
|
+
this.native.pb = value?.getNative() ?? null;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Number of streams in the file.
|
|
260
|
+
*
|
|
261
|
+
* Direct mapping to AVFormatContext->nb_streams
|
|
262
|
+
*/
|
|
263
|
+
get nbStreams() {
|
|
264
|
+
return this.native.nbStreams;
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* Array of streams in the file.
|
|
268
|
+
*
|
|
269
|
+
* Direct mapping to AVFormatContext->streams
|
|
270
|
+
*/
|
|
271
|
+
get streams() {
|
|
272
|
+
const nativeStreams = this.native.streams;
|
|
273
|
+
if (!nativeStreams) {
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
276
|
+
return nativeStreams.map((nativeStream) => new Stream(nativeStream));
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Allow non-standard and experimental extension.
|
|
280
|
+
*
|
|
281
|
+
* Direct mapping to AVFormatContext->strict_std_compliance
|
|
282
|
+
*
|
|
283
|
+
* @see AVCodecContext.strict_std_compliance
|
|
284
|
+
*/
|
|
285
|
+
get strictStdCompliance() {
|
|
286
|
+
return this.native.strictStdCompliance;
|
|
287
|
+
}
|
|
288
|
+
set strictStdCompliance(value) {
|
|
289
|
+
this.native.strictStdCompliance = value;
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Maximum number of streams.
|
|
293
|
+
*
|
|
294
|
+
* Direct mapping to AVFormatContext->max_streams
|
|
295
|
+
*
|
|
296
|
+
* - encoding: unused
|
|
297
|
+
* - decoding: Set by user
|
|
298
|
+
*/
|
|
299
|
+
get maxStreams() {
|
|
300
|
+
return this.native.maxStreams;
|
|
301
|
+
}
|
|
302
|
+
set maxStreams(value) {
|
|
303
|
+
this.native.maxStreams = value;
|
|
304
|
+
}
|
|
305
|
+
/**
|
|
306
|
+
* Allocate an AVFormatContext for input.
|
|
307
|
+
*
|
|
308
|
+
* Direct mapping to avformat_alloc_context()
|
|
309
|
+
*
|
|
310
|
+
* @example
|
|
311
|
+
* ```typescript
|
|
312
|
+
* const ctx = new FormatContext();
|
|
313
|
+
* ctx.allocContext();
|
|
314
|
+
* // Context is now allocated for demuxing
|
|
315
|
+
* ```
|
|
316
|
+
*
|
|
317
|
+
* @throws {Error} If allocation fails (ENOMEM)
|
|
318
|
+
*/
|
|
319
|
+
allocContext() {
|
|
320
|
+
return this.native.allocContext();
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Allocate an AVFormatContext for output.
|
|
324
|
+
*
|
|
325
|
+
* Direct mapping to avformat_alloc_output_context2()
|
|
326
|
+
*
|
|
327
|
+
* @param oformat - Output format. May be null to auto-detect from filename
|
|
328
|
+
* @param formatName - Format name. May be null to auto-detect
|
|
329
|
+
* @param filename - Filename for output. Used to guess format if not specified
|
|
330
|
+
*
|
|
331
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
332
|
+
* - 0: Success
|
|
333
|
+
* - AVERROR(EINVAL): Invalid arguments
|
|
334
|
+
* - AVERROR(ENOMEM): Memory allocation failure
|
|
335
|
+
*
|
|
336
|
+
* @example
|
|
337
|
+
* ```typescript
|
|
338
|
+
* const ctx = new FormatContext();
|
|
339
|
+
* const ret = ctx.allocOutputContext2(null, 'mp4', 'output.mp4');
|
|
340
|
+
* if (ret < 0) {
|
|
341
|
+
* throw new FFmpegError(ret);
|
|
342
|
+
* }
|
|
343
|
+
* ```
|
|
344
|
+
*/
|
|
345
|
+
allocOutputContext2(oformat, formatName, filename) {
|
|
346
|
+
if (!oformat && !formatName && !filename) {
|
|
347
|
+
throw new Error('At least one of oformat, formatName, or filename must be specified');
|
|
348
|
+
}
|
|
349
|
+
return this.native.allocOutputContext2(oformat?.getNative() ?? null, formatName, filename);
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Free an AVFormatContext and all its streams.
|
|
353
|
+
*
|
|
354
|
+
* Direct mapping to avformat_free_context()
|
|
355
|
+
*
|
|
356
|
+
* @example
|
|
357
|
+
* ```typescript
|
|
358
|
+
* ctx.freeContext();
|
|
359
|
+
* // ctx is now invalid and should not be used
|
|
360
|
+
* ```
|
|
361
|
+
*/
|
|
362
|
+
freeContext() {
|
|
363
|
+
return this.native.freeContext();
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Close an opened input AVFormatContext.
|
|
367
|
+
*
|
|
368
|
+
* Direct mapping to avformat_close_input()
|
|
369
|
+
*
|
|
370
|
+
* @example
|
|
371
|
+
* ```typescript
|
|
372
|
+
* await ctx.closeInput();
|
|
373
|
+
* // Input is closed and context is freed
|
|
374
|
+
* ```
|
|
375
|
+
*/
|
|
376
|
+
async closeInput() {
|
|
377
|
+
return this.native.closeInput();
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Open the output file for writing.
|
|
381
|
+
*
|
|
382
|
+
* Must be called after allocOutputContext2() and before writeHeader()
|
|
383
|
+
* for file-based formats (not NOFILE formats).
|
|
384
|
+
*
|
|
385
|
+
* Direct mapping to avio_open()
|
|
386
|
+
*
|
|
387
|
+
* @returns Promise resolving to 0 on success, negative AVERROR on failure:
|
|
388
|
+
* - 0: Success
|
|
389
|
+
* - AVERROR(ENOENT): File cannot be created
|
|
390
|
+
* - AVERROR(EACCES): Permission denied
|
|
391
|
+
* - AVERROR(EIO): I/O error
|
|
392
|
+
*
|
|
393
|
+
* @example
|
|
394
|
+
* ```typescript
|
|
395
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
396
|
+
*
|
|
397
|
+
* ctx.allocOutputContext2(null, null, 'output.mp4');
|
|
398
|
+
* const ret = await ctx.openOutput(); // Opens the file for writing
|
|
399
|
+
* FFmpegError.throwIfError(ret, 'openOutput');
|
|
400
|
+
* await ctx.writeHeader(null);
|
|
401
|
+
* ```
|
|
402
|
+
*/
|
|
403
|
+
async openOutput() {
|
|
404
|
+
return this.native.openOutput();
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Close the output file.
|
|
408
|
+
*
|
|
409
|
+
* Direct mapping to avio_closep()
|
|
410
|
+
*
|
|
411
|
+
* Should be called after writeTrailer() for file-based formats.
|
|
412
|
+
* The file is automatically closed by freeContext() as well.
|
|
413
|
+
*
|
|
414
|
+
* @example
|
|
415
|
+
* ```typescript
|
|
416
|
+
* await ctx.writeTrailer();
|
|
417
|
+
* await ctx.closeOutput();
|
|
418
|
+
* ctx.freeContext();
|
|
419
|
+
* ```
|
|
420
|
+
*/
|
|
421
|
+
async closeOutput() {
|
|
422
|
+
return this.native.closeOutput();
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Open an input stream and read the header.
|
|
426
|
+
*
|
|
427
|
+
* Opens the specified URL, reads the format header, and initializes the stream information.
|
|
428
|
+
* Automatically detects the format if not specified.
|
|
429
|
+
*
|
|
430
|
+
* Direct mapping to avformat_open_input()
|
|
431
|
+
*
|
|
432
|
+
* @param url - URL of the stream to open
|
|
433
|
+
* @param fmt - Input format. May be null to auto-detect
|
|
434
|
+
* @param options - Dictionary of options. May be null
|
|
435
|
+
*
|
|
436
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
437
|
+
* - 0: Success
|
|
438
|
+
* - AVERROR(ENOENT): File not found
|
|
439
|
+
* - AVERROR(EIO): I/O error
|
|
440
|
+
* - AVERROR(EINVAL): Invalid data found
|
|
441
|
+
* - AVERROR(ENOMEM): Memory allocation failure
|
|
442
|
+
* - <0: Other format-specific errors
|
|
443
|
+
*
|
|
444
|
+
* @example
|
|
445
|
+
* ```typescript
|
|
446
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
447
|
+
*
|
|
448
|
+
* const ret = await ctx.openInput('video.mp4', null, null);
|
|
449
|
+
* FFmpegError.throwIfError(ret, 'openInput');
|
|
450
|
+
* // Context is now open and header is read
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
async openInput(url, fmt = null, options = null) {
|
|
454
|
+
return this.native.openInput(url, fmt?.getNative() ?? null, options?.getNative() ?? null);
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Read packets of a media file to get stream information.
|
|
458
|
+
*
|
|
459
|
+
* Analyzes the media file by reading packets to determine stream parameters
|
|
460
|
+
* like codec, dimensions, sample rate, etc. Required after openInput().
|
|
461
|
+
*
|
|
462
|
+
* Direct mapping to avformat_find_stream_info()
|
|
463
|
+
*
|
|
464
|
+
* @param options - Dictionary of options per stream. May be null
|
|
465
|
+
*
|
|
466
|
+
* @returns >=0 on success, negative AVERROR on error:
|
|
467
|
+
* - >=0: Success (number of stream info found)
|
|
468
|
+
* - AVERROR(EIO): I/O error
|
|
469
|
+
* - AVERROR(ENOMEM): Memory allocation failure
|
|
470
|
+
* - <0: Other errors
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```typescript
|
|
474
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
475
|
+
*
|
|
476
|
+
* const ret = await ctx.findStreamInfo(null);
|
|
477
|
+
* FFmpegError.throwIfError(ret, 'findStreamInfo');
|
|
478
|
+
* console.log(`Found ${ctx.nbStreams} streams`);
|
|
479
|
+
* ```
|
|
480
|
+
*/
|
|
481
|
+
async findStreamInfo(options = null) {
|
|
482
|
+
return this.native.findStreamInfo(options?.map((d) => d.getNative()) ?? null);
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Read the next packet in the file.
|
|
486
|
+
*
|
|
487
|
+
* Reads and returns the next packet from the input file.
|
|
488
|
+
* Packets must be unreferenced after use to free memory.
|
|
489
|
+
*
|
|
490
|
+
* Direct mapping to av_read_frame()
|
|
491
|
+
*
|
|
492
|
+
* @param pkt - Packet to fill with data
|
|
493
|
+
*
|
|
494
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
495
|
+
* - 0: Success
|
|
496
|
+
* - AVERROR_EOF: End of file reached
|
|
497
|
+
* - AVERROR(EAGAIN): Temporarily unavailable
|
|
498
|
+
* - AVERROR(EIO): I/O error
|
|
499
|
+
* - <0: Other errors
|
|
500
|
+
*
|
|
501
|
+
* @example
|
|
502
|
+
* ```typescript
|
|
503
|
+
* import { Packet, FormatContext, FFmpegError, AVERROR_EOF } from 'node-av';
|
|
504
|
+
*
|
|
505
|
+
* const packet = new Packet();
|
|
506
|
+
* packet.alloc();
|
|
507
|
+
*
|
|
508
|
+
* while (true) {
|
|
509
|
+
* const ret = await ctx.readFrame(packet);
|
|
510
|
+
* if (ret === AVERROR_EOF) break;
|
|
511
|
+
* FFmpegError.throwIfError(ret, 'readFrame');
|
|
512
|
+
*
|
|
513
|
+
* // Process packet
|
|
514
|
+
* console.log(`Stream ${packet.streamIndex}, PTS: ${packet.pts}`);
|
|
515
|
+
* packet.unref();
|
|
516
|
+
* }
|
|
517
|
+
* ```
|
|
518
|
+
*/
|
|
519
|
+
async readFrame(pkt) {
|
|
520
|
+
return this.native.readFrame(pkt.getNative());
|
|
521
|
+
}
|
|
522
|
+
/**
|
|
523
|
+
* Seek to the keyframe at timestamp.
|
|
524
|
+
*
|
|
525
|
+
* Seeks to the keyframe at or before the specified timestamp.
|
|
526
|
+
* The next packet read will be from the new position.
|
|
527
|
+
*
|
|
528
|
+
* Direct mapping to av_seek_frame()
|
|
529
|
+
*
|
|
530
|
+
* @param streamIndex - Stream index or -1 for default
|
|
531
|
+
* @param timestamp - Timestamp in stream time_base units or AV_TIME_BASE if stream_index is -1
|
|
532
|
+
* @param flags - AVSEEK_FLAG_* flags
|
|
533
|
+
*
|
|
534
|
+
* @returns >=0 on success, negative AVERROR on error:
|
|
535
|
+
* - >=0: Success
|
|
536
|
+
* - AVERROR(EINVAL): Invalid arguments
|
|
537
|
+
* - AVERROR(EIO): I/O error
|
|
538
|
+
* - <0: Other errors
|
|
539
|
+
*
|
|
540
|
+
* @example
|
|
541
|
+
* ```typescript
|
|
542
|
+
* import { FormatContext, FFmpegError, AV_TIME_BASE, AVSEEK_FLAG_BACKWARD } from 'node-av';
|
|
543
|
+
*
|
|
544
|
+
* // Seek to 10 seconds
|
|
545
|
+
* const timestamp = 10n * BigInt(AV_TIME_BASE);
|
|
546
|
+
* const ret = await ctx.seekFrame(-1, timestamp, AVSEEK_FLAG_BACKWARD);
|
|
547
|
+
* FFmpegError.throwIfError(ret, 'seekFrame');
|
|
548
|
+
* // Next readFrame will return packet from new position
|
|
549
|
+
* ```
|
|
550
|
+
*/
|
|
551
|
+
async seekFrame(streamIndex, timestamp, flags = AVFLAG_NONE) {
|
|
552
|
+
return this.native.seekFrame(streamIndex, timestamp, flags);
|
|
553
|
+
}
|
|
554
|
+
/**
|
|
555
|
+
* Seek to timestamp ts with more control.
|
|
556
|
+
*
|
|
557
|
+
* Seeks to a timestamp within the specified min/max range.
|
|
558
|
+
* More precise than seekFrame() with tolerance control.
|
|
559
|
+
*
|
|
560
|
+
* Direct mapping to avformat_seek_file()
|
|
561
|
+
*
|
|
562
|
+
* @param streamIndex - Stream index or -1 for default
|
|
563
|
+
* @param minTs - Smallest acceptable timestamp
|
|
564
|
+
* @param ts - Target timestamp
|
|
565
|
+
* @param maxTs - Largest acceptable timestamp
|
|
566
|
+
* @param flags - AVSEEK_FLAG_* flags
|
|
567
|
+
*
|
|
568
|
+
* @returns >=0 on success, negative AVERROR on error:
|
|
569
|
+
* - >=0: Success
|
|
570
|
+
* - AVERROR(EINVAL): Invalid arguments
|
|
571
|
+
* - AVERROR(EIO): I/O error
|
|
572
|
+
* - <0: Other errors
|
|
573
|
+
*
|
|
574
|
+
* @example
|
|
575
|
+
* ```typescript
|
|
576
|
+
* import { FormatContext, FFmpegError, AV_TIME_BASE } from 'node-av';
|
|
577
|
+
*
|
|
578
|
+
* // Seek to timestamp with tolerance
|
|
579
|
+
* const target = 10n * BigInt(AV_TIME_BASE);
|
|
580
|
+
* const tolerance = BigInt(AV_TIME_BASE);
|
|
581
|
+
* const ret = await ctx.seekFile(
|
|
582
|
+
* -1,
|
|
583
|
+
* target - tolerance, // min: 9 seconds
|
|
584
|
+
* target, // target: 10 seconds
|
|
585
|
+
* target + tolerance, // max: 11 seconds
|
|
586
|
+
* 0
|
|
587
|
+
* );
|
|
588
|
+
* FFmpegError.throwIfError(ret, 'seekFile');
|
|
589
|
+
* ```
|
|
590
|
+
*/
|
|
591
|
+
async seekFile(streamIndex, minTs, ts, maxTs, flags = AVFLAG_NONE) {
|
|
592
|
+
return this.native.seekFile(streamIndex, minTs, ts, maxTs, flags);
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Allocate the stream private data and write the stream header.
|
|
596
|
+
*
|
|
597
|
+
* Initializes the output file and writes the file header.
|
|
598
|
+
* Must be called before writing any packets.
|
|
599
|
+
*
|
|
600
|
+
* Direct mapping to avformat_write_header()
|
|
601
|
+
*
|
|
602
|
+
* @param options - Dictionary of options. May be null
|
|
603
|
+
*
|
|
604
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
605
|
+
* - 0: Success
|
|
606
|
+
* - AVERROR(EINVAL): Invalid parameters
|
|
607
|
+
* - AVERROR(EIO): I/O error
|
|
608
|
+
* - AVERROR(ENOMEM): Memory allocation failure
|
|
609
|
+
* - <0: Other muxer-specific errors
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* ```typescript
|
|
613
|
+
* import { Dictionary, FormatContext, FFmpegError } from 'node-av';
|
|
614
|
+
*
|
|
615
|
+
* const options = new Dictionary();
|
|
616
|
+
* options.set('movflags', 'faststart', 0);
|
|
617
|
+
*
|
|
618
|
+
* const ret = await ctx.writeHeader(options);
|
|
619
|
+
* FFmpegError.throwIfError(ret, 'writeHeader');
|
|
620
|
+
* options.free();
|
|
621
|
+
* // Header written, ready to write packets
|
|
622
|
+
* ```
|
|
623
|
+
*/
|
|
624
|
+
async writeHeader(options = null) {
|
|
625
|
+
return this.native.writeHeader(options?.getNative() ?? null);
|
|
626
|
+
}
|
|
627
|
+
/**
|
|
628
|
+
* Write a packet to an output media file.
|
|
629
|
+
*
|
|
630
|
+
* Writes a packet directly without reordering.
|
|
631
|
+
* Use interleavedWriteFrame() for automatic interleaving.
|
|
632
|
+
*
|
|
633
|
+
* Direct mapping to av_write_frame()
|
|
634
|
+
*
|
|
635
|
+
* @param pkt - Packet to write. May be null to flush
|
|
636
|
+
*
|
|
637
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
638
|
+
* - 0: Success
|
|
639
|
+
* - AVERROR(EINVAL): Invalid packet
|
|
640
|
+
* - AVERROR(EIO): I/O error
|
|
641
|
+
* - <0: Other muxer-specific errors
|
|
642
|
+
*
|
|
643
|
+
* @example
|
|
644
|
+
* ```typescript
|
|
645
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
646
|
+
*
|
|
647
|
+
* const ret = await ctx.writeFrame(packet);
|
|
648
|
+
* FFmpegError.throwIfError(ret, 'writeFrame');
|
|
649
|
+
*
|
|
650
|
+
* // Flush at the end
|
|
651
|
+
* const flushRet = await ctx.writeFrame(null);
|
|
652
|
+
* FFmpegError.throwIfError(flushRet, 'writeFrame flush');
|
|
653
|
+
* ```
|
|
654
|
+
*
|
|
655
|
+
* @note This function does NOT take ownership of the packet.
|
|
656
|
+
*
|
|
657
|
+
* @see {@link interleavedWriteFrame} For automatic interleaving
|
|
658
|
+
*/
|
|
659
|
+
async writeFrame(pkt) {
|
|
660
|
+
return this.native.writeFrame(pkt ? pkt.getNative() : null);
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* Write a packet to an output media file ensuring correct interleaving.
|
|
664
|
+
*
|
|
665
|
+
* Automatically interleaves packets from different streams based on DTS.
|
|
666
|
+
* Preferred method for writing packets in most cases.
|
|
667
|
+
*
|
|
668
|
+
* Direct mapping to av_interleaved_write_frame()
|
|
669
|
+
*
|
|
670
|
+
* @param pkt - Packet to write. May be null to flush
|
|
671
|
+
*
|
|
672
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
673
|
+
* - 0: Success
|
|
674
|
+
* - AVERROR(EINVAL): Invalid packet
|
|
675
|
+
* - AVERROR(EIO): I/O error
|
|
676
|
+
* - <0: Other muxer-specific errors
|
|
677
|
+
*
|
|
678
|
+
* @example
|
|
679
|
+
* ```typescript
|
|
680
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
681
|
+
*
|
|
682
|
+
* // Write packets with automatic interleaving
|
|
683
|
+
* const ret = await ctx.interleavedWriteFrame(packet);
|
|
684
|
+
* FFmpegError.throwIfError(ret, 'interleavedWriteFrame');
|
|
685
|
+
* // Packet is automatically freed after writing
|
|
686
|
+
* ```
|
|
687
|
+
*
|
|
688
|
+
* @note This function TAKES OWNERSHIP of the packet and will free it.
|
|
689
|
+
*
|
|
690
|
+
* @see {@link writeFrame} For manual interleaving control
|
|
691
|
+
*/
|
|
692
|
+
async interleavedWriteFrame(pkt) {
|
|
693
|
+
return this.native.interleavedWriteFrame(pkt ? pkt.getNative() : null);
|
|
694
|
+
}
|
|
695
|
+
/**
|
|
696
|
+
* Write the stream trailer to an output media file.
|
|
697
|
+
*
|
|
698
|
+
* Finalizes the output file by writing the trailer.
|
|
699
|
+
* Must be called after all packets have been written.
|
|
700
|
+
*
|
|
701
|
+
* Direct mapping to av_write_trailer()
|
|
702
|
+
*
|
|
703
|
+
* @returns 0 on success, negative AVERROR on error:
|
|
704
|
+
* - 0: Success
|
|
705
|
+
* - AVERROR(EIO): I/O error
|
|
706
|
+
* - <0: Other muxer-specific errors
|
|
707
|
+
*
|
|
708
|
+
* @example
|
|
709
|
+
* ```typescript
|
|
710
|
+
* import { FormatContext, FFmpegError } from 'node-av';
|
|
711
|
+
*
|
|
712
|
+
* // Finalize the output file
|
|
713
|
+
* const ret = await ctx.writeTrailer();
|
|
714
|
+
* FFmpegError.throwIfError(ret, 'writeTrailer');
|
|
715
|
+
* // File is now complete and finalized
|
|
716
|
+
* ```
|
|
717
|
+
*
|
|
718
|
+
* @note Must be called after all packets have been written.
|
|
719
|
+
*/
|
|
720
|
+
async writeTrailer() {
|
|
721
|
+
return this.native.writeTrailer();
|
|
722
|
+
}
|
|
723
|
+
/**
|
|
724
|
+
* Flush any buffered data to the output.
|
|
725
|
+
*
|
|
726
|
+
* Direct mapping to avio_flush()
|
|
727
|
+
*
|
|
728
|
+
* @example
|
|
729
|
+
* ```typescript
|
|
730
|
+
* import { FormatContext } from 'node-av';
|
|
731
|
+
*
|
|
732
|
+
* // Flush buffered data
|
|
733
|
+
* ctx.flush();
|
|
734
|
+
* // All buffered data written to output
|
|
735
|
+
* ```
|
|
736
|
+
*/
|
|
737
|
+
flush() {
|
|
738
|
+
return this.native.flush();
|
|
739
|
+
}
|
|
740
|
+
/**
|
|
741
|
+
* Dump format information to stderr.
|
|
742
|
+
*
|
|
743
|
+
* Prints detailed information about the format and streams to stderr.
|
|
744
|
+
* Useful for debugging and understanding file structure.
|
|
745
|
+
*
|
|
746
|
+
* Direct mapping to av_dump_format()
|
|
747
|
+
*
|
|
748
|
+
* @param index - Stream index or program index to dump
|
|
749
|
+
* @param url - URL or filename to display
|
|
750
|
+
* @param isOutput - true for output format, false for input format
|
|
751
|
+
*
|
|
752
|
+
* @example
|
|
753
|
+
* ```typescript
|
|
754
|
+
* import { FormatContext } from 'node-av';
|
|
755
|
+
*
|
|
756
|
+
* // Dump input format info
|
|
757
|
+
* formatCtx.dumpFormat(0, 'input.mp4', false);
|
|
758
|
+
*
|
|
759
|
+
* // Dump output format info
|
|
760
|
+
* formatCtx.dumpFormat(0, 'output.mp4', true);
|
|
761
|
+
* ```
|
|
762
|
+
*/
|
|
763
|
+
dumpFormat(index, url, isOutput) {
|
|
764
|
+
this.native.dumpFormat(index, url, isOutput);
|
|
765
|
+
}
|
|
766
|
+
findBestStream(type, wantedStreamNb = -1, relatedStream = -1, wantDecoder = false, flags = 0) {
|
|
767
|
+
if (wantDecoder === true) {
|
|
768
|
+
const result = this.native.findBestStream(type, wantedStreamNb, relatedStream, true, flags ?? 0);
|
|
769
|
+
if (typeof result === 'object' && result !== null) {
|
|
770
|
+
// Wrap the native decoder in a Codec instance
|
|
771
|
+
return {
|
|
772
|
+
streamIndex: result.streamIndex,
|
|
773
|
+
decoder: Codec.fromNative(result.decoder),
|
|
774
|
+
};
|
|
775
|
+
}
|
|
776
|
+
// If not an object, return as error code
|
|
777
|
+
return { streamIndex: result, decoder: null };
|
|
778
|
+
}
|
|
779
|
+
return this.native.findBestStream(type, wantedStreamNb, relatedStream, false, flags ?? 0);
|
|
780
|
+
}
|
|
781
|
+
/**
|
|
782
|
+
* Add a new stream to the media file.
|
|
783
|
+
*
|
|
784
|
+
* Creates a new stream in the output format context.
|
|
785
|
+
* The stream must be configured before calling writeHeader().
|
|
786
|
+
*
|
|
787
|
+
* Direct mapping to avformat_new_stream()
|
|
788
|
+
*
|
|
789
|
+
* @param c - Codec to use for the stream. May be null
|
|
790
|
+
*
|
|
791
|
+
* @returns The newly created stream
|
|
792
|
+
*
|
|
793
|
+
* @throws {Error} If stream creation fails (ENOMEM)
|
|
794
|
+
*
|
|
795
|
+
* @example
|
|
796
|
+
* ```typescript
|
|
797
|
+
* import { FormatContext, Codec, FFmpegError } from 'node-av';
|
|
798
|
+
* import { AV_CODEC_ID_H264, AVMEDIA_TYPE_VIDEO } from 'node-av/constants';
|
|
799
|
+
*
|
|
800
|
+
* // Add a video stream
|
|
801
|
+
* const videoCodec = Codec.findEncoder(AV_CODEC_ID_H264);
|
|
802
|
+
* const videoStream = ctx.newStream(videoCodec);
|
|
803
|
+
*
|
|
804
|
+
* // Configure stream parameters
|
|
805
|
+
* videoStream.codecpar.codecType = AVMEDIA_TYPE_VIDEO;
|
|
806
|
+
* videoStream.codecpar.codecId = AV_CODEC_ID_H264;
|
|
807
|
+
* videoStream.codecpar.width = 1920;
|
|
808
|
+
* videoStream.codecpar.height = 1080;
|
|
809
|
+
* ```
|
|
810
|
+
*/
|
|
811
|
+
newStream(c = null) {
|
|
812
|
+
const nativeStream = this.native.newStream(c?.getNative() ?? null);
|
|
813
|
+
return new Stream(nativeStream);
|
|
814
|
+
}
|
|
815
|
+
/**
|
|
816
|
+
* Get the native FFmpeg AVFormatContext pointer.
|
|
817
|
+
*
|
|
818
|
+
* @internal For use by other wrapper classes
|
|
819
|
+
* @returns The underlying native format context object
|
|
820
|
+
*/
|
|
821
|
+
getNative() {
|
|
822
|
+
return this.native;
|
|
823
|
+
}
|
|
824
|
+
/**
|
|
825
|
+
* Dispose of the format context asynchronously.
|
|
826
|
+
*
|
|
827
|
+
* Implements the AsyncDisposable interface for automatic cleanup.
|
|
828
|
+
* Properly handles network connections and I/O operations.
|
|
829
|
+
*
|
|
830
|
+
* @example
|
|
831
|
+
* ```typescript
|
|
832
|
+
* import { FormatContext } from 'node-av';
|
|
833
|
+
*
|
|
834
|
+
* {
|
|
835
|
+
* await using ctx = new FormatContext();
|
|
836
|
+
* await ctx.openInput('rtsp://camera/stream');
|
|
837
|
+
* // ... use context
|
|
838
|
+
* } // Automatically closed when leaving scope
|
|
839
|
+
* ```
|
|
840
|
+
*/
|
|
841
|
+
async [Symbol.asyncDispose]() {
|
|
842
|
+
await this.native[Symbol.asyncDispose]();
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
//# sourceMappingURL=format-context.js.map
|