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
package/dist/api/media-output.js
CHANGED
|
@@ -1,67 +1,56 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* MediaOutput - Unified Output Handler for FFmpeg
|
|
3
|
-
*
|
|
4
|
-
* Provides a high-level interface for writing media to various destinations.
|
|
5
|
-
* Supports files, streams, and custom IO with automatic format configuration.
|
|
6
|
-
*
|
|
7
|
-
* Central entry point for all media output operations.
|
|
8
|
-
* Manages FormatContext lifecycle and provides stream management.
|
|
9
|
-
*
|
|
10
|
-
* @module api/media-output
|
|
11
|
-
*/
|
|
12
1
|
import { mkdir } from 'fs/promises';
|
|
13
2
|
import { dirname, resolve } from 'path';
|
|
14
3
|
import { AVFMT_FLAG_CUSTOM_IO, AVFMT_NOFILE, AVIO_FLAG_WRITE } from '../constants/constants.js';
|
|
15
4
|
import { FFmpegError, FormatContext, IOContext, Rational } from '../lib/index.js';
|
|
16
5
|
import { Encoder } from './encoder.js';
|
|
17
6
|
/**
|
|
18
|
-
*
|
|
7
|
+
* High-level media output for writing and muxing media files.
|
|
19
8
|
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* adding streams, writing packets, and finalizing output.
|
|
9
|
+
* Provides simplified access to media muxing and file writing operations.
|
|
10
|
+
* Handles stream configuration, packet writing, and format management.
|
|
11
|
+
* Supports files, URLs, and custom I/O with automatic cleanup.
|
|
12
|
+
* Essential component for media encoding pipelines and transcoding.
|
|
25
13
|
*
|
|
26
14
|
* @example
|
|
27
15
|
* ```typescript
|
|
28
|
-
* import { MediaOutput
|
|
16
|
+
* import { MediaOutput } from 'node-av/api';
|
|
29
17
|
*
|
|
30
|
-
* //
|
|
31
|
-
*
|
|
18
|
+
* // Create output file
|
|
19
|
+
* await using output = await MediaOutput.open('output.mp4');
|
|
32
20
|
*
|
|
33
|
-
* // Add
|
|
34
|
-
* const
|
|
35
|
-
*
|
|
36
|
-
* height: 1080,
|
|
37
|
-
* pixelFormat: AV_PIX_FMT_YUV420P
|
|
38
|
-
* });
|
|
39
|
-
* const streamIdx = output.addStream(encoder);
|
|
21
|
+
* // Add streams from encoders
|
|
22
|
+
* const videoIdx = output.addStream(videoEncoder);
|
|
23
|
+
* const audioIdx = output.addStream(audioEncoder);
|
|
40
24
|
*
|
|
41
|
-
* // Write header
|
|
25
|
+
* // Write header
|
|
42
26
|
* await output.writeHeader();
|
|
43
|
-
*
|
|
27
|
+
*
|
|
28
|
+
* // Write packets
|
|
29
|
+
* await output.writePacket(packet, videoIdx);
|
|
30
|
+
*
|
|
31
|
+
* // Write trailer and close
|
|
44
32
|
* await output.writeTrailer();
|
|
45
|
-
* await output.close();
|
|
46
33
|
* ```
|
|
47
34
|
*
|
|
48
35
|
* @example
|
|
49
36
|
* ```typescript
|
|
50
|
-
* // Stream copy
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
54
|
-
* const videoStream = input.video();
|
|
55
|
-
* const streamIdx = output.addStream(videoStream);
|
|
37
|
+
* // Stream copy
|
|
38
|
+
* await using input = await MediaInput.open('input.mp4');
|
|
39
|
+
* await using output = await MediaOutput.open('output.mp4');
|
|
56
40
|
*
|
|
41
|
+
* // Copy stream configuration
|
|
42
|
+
* const videoIdx = output.addStream(input.video());
|
|
57
43
|
* await output.writeHeader();
|
|
44
|
+
*
|
|
58
45
|
* for await (const packet of input.packets()) {
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
* }
|
|
46
|
+
* await output.writePacket(packet, videoIdx);
|
|
47
|
+
* packet.free();
|
|
62
48
|
* }
|
|
63
|
-
* await output.writeTrailer();
|
|
64
49
|
* ```
|
|
50
|
+
*
|
|
51
|
+
* @see {@link MediaInput} For reading media files
|
|
52
|
+
* @see {@link Encoder} For encoding frames to packets
|
|
53
|
+
* @see {@link FormatContext} For low-level API
|
|
65
54
|
*/
|
|
66
55
|
export class MediaOutput {
|
|
67
56
|
formatContext;
|
|
@@ -71,50 +60,63 @@ export class MediaOutput {
|
|
|
71
60
|
trailerWritten = false;
|
|
72
61
|
closed = false;
|
|
73
62
|
/**
|
|
74
|
-
*
|
|
75
|
-
*
|
|
76
|
-
* Initializes the output with a new FormatContext.
|
|
77
|
-
* The actual format setup happens in the static factory method.
|
|
63
|
+
* @internal
|
|
78
64
|
*/
|
|
79
65
|
constructor() {
|
|
80
66
|
this.formatContext = new FormatContext();
|
|
81
67
|
}
|
|
82
68
|
/**
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* Creates a FormatContext and prepares the output for writing.
|
|
86
|
-
* Automatically detects format from filename/URL if not specified.
|
|
87
|
-
*
|
|
88
|
-
* If io callbacks is used, it creates a FormatContext with custom IO handling.
|
|
89
|
-
* Format must be explicitly specified for custom IO.
|
|
69
|
+
* Open media output for writing.
|
|
90
70
|
*
|
|
91
|
-
*
|
|
71
|
+
* Creates and configures output context for muxing.
|
|
72
|
+
* Automatically creates directories for file output.
|
|
73
|
+
* Supports files, URLs, and custom I/O callbacks.
|
|
92
74
|
*
|
|
93
|
-
*
|
|
94
|
-
* @param options - Optional configuration
|
|
75
|
+
* Direct mapping to avformat_alloc_output_context2() and avio_open2().
|
|
95
76
|
*
|
|
96
|
-
* @
|
|
77
|
+
* @param target - File path, URL, or I/O callbacks
|
|
78
|
+
* @param options - Output configuration options
|
|
79
|
+
* @returns Opened media output instance
|
|
97
80
|
*
|
|
98
|
-
* @throws {Error} If format
|
|
81
|
+
* @throws {Error} If format required for custom I/O
|
|
82
|
+
* @throws {FFmpegError} If allocation or opening fails
|
|
99
83
|
*
|
|
100
84
|
* @example
|
|
101
85
|
* ```typescript
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
* seek: (offset, whence) => offset
|
|
105
|
-
* };
|
|
106
|
-
* const output = await MediaOutput.open(callbacks, { format: 'mp4' });
|
|
86
|
+
* // Create file output
|
|
87
|
+
* await using output = await MediaOutput.open('output.mp4');
|
|
107
88
|
* ```
|
|
108
89
|
*
|
|
109
90
|
* @example
|
|
110
91
|
* ```typescript
|
|
111
|
-
*
|
|
92
|
+
* // Create output with specific format
|
|
93
|
+
* await using output = await MediaOutput.open('output.ts', {
|
|
94
|
+
* format: 'mpegts'
|
|
95
|
+
* });
|
|
112
96
|
* ```
|
|
113
97
|
*
|
|
114
98
|
* @example
|
|
115
99
|
* ```typescript
|
|
116
|
-
*
|
|
100
|
+
* // Custom I/O callbacks
|
|
101
|
+
* const callbacks = {
|
|
102
|
+
* write: async (buffer: Buffer) => {
|
|
103
|
+
* // Write to custom destination
|
|
104
|
+
* return buffer.length;
|
|
105
|
+
* },
|
|
106
|
+
* seek: async (offset: bigint, whence: number) => {
|
|
107
|
+
* // Seek in custom destination
|
|
108
|
+
* return offset;
|
|
109
|
+
* }
|
|
110
|
+
* };
|
|
111
|
+
*
|
|
112
|
+
* await using output = await MediaOutput.open(callbacks, {
|
|
113
|
+
* format: 'mp4',
|
|
114
|
+
* bufferSize: 8192
|
|
115
|
+
* });
|
|
117
116
|
* ```
|
|
117
|
+
*
|
|
118
|
+
* @see {@link MediaOutputOptions} For configuration options
|
|
119
|
+
* @see {@link IOOutputCallbacks} For custom I/O interface
|
|
118
120
|
*/
|
|
119
121
|
static async open(target, options) {
|
|
120
122
|
const output = new MediaOutput();
|
|
@@ -163,7 +165,8 @@ export class MediaOutput {
|
|
|
163
165
|
// Cleanup on error
|
|
164
166
|
if (output.ioContext) {
|
|
165
167
|
try {
|
|
166
|
-
|
|
168
|
+
const isCustomIO = (output.formatContext.flags & AVFMT_FLAG_CUSTOM_IO) !== 0;
|
|
169
|
+
if (isCustomIO) {
|
|
167
170
|
// Clear the pb reference first
|
|
168
171
|
output.formatContext.pb = null;
|
|
169
172
|
// For custom IO with callbacks, free the context
|
|
@@ -190,46 +193,38 @@ export class MediaOutput {
|
|
|
190
193
|
}
|
|
191
194
|
}
|
|
192
195
|
/**
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
* Creates a new stream in the output format context.
|
|
196
|
-
* Copies codec parameters from encoder or input stream.
|
|
196
|
+
* Add a stream to the output.
|
|
197
197
|
*
|
|
198
|
-
*
|
|
198
|
+
* Configures output stream from encoder or input stream.
|
|
199
|
+
* Must be called before writeHeader().
|
|
200
|
+
* Returns stream index for packet writing.
|
|
199
201
|
*
|
|
200
|
-
*
|
|
201
|
-
* @param options - Optional stream configuration
|
|
202
|
-
* @param options.timeBase - Custom output timebase for the stream.
|
|
203
|
-
* If not specified, uses the source's timebase.
|
|
204
|
-
* When set, packets will be automatically rescaled
|
|
205
|
-
* from source timebase to this output timebase.
|
|
202
|
+
* Direct mapping to avformat_new_stream() and avcodec_parameters_copy().
|
|
206
203
|
*
|
|
204
|
+
* @param source - Encoder or stream to add
|
|
205
|
+
* @param options - Stream configuration options
|
|
206
|
+
* @param options.timeBase - Optional custom timebase for the stream
|
|
207
207
|
* @returns Stream index for packet writing
|
|
208
208
|
*
|
|
209
|
-
* @throws {Error} If called after header
|
|
210
|
-
*
|
|
211
|
-
* @example
|
|
212
|
-
* ```typescript
|
|
213
|
-
* // Add encoder stream (transcoding) - uses encoder's timebase
|
|
214
|
-
* const encoder = await Encoder.create('libx264', { width: 1920, height: 1080 });
|
|
215
|
-
* const streamIdx = output.addStream(encoder);
|
|
216
|
-
* ```
|
|
209
|
+
* @throws {Error} If called after header written or output closed
|
|
217
210
|
*
|
|
218
211
|
* @example
|
|
219
212
|
* ```typescript
|
|
220
|
-
* // Add stream
|
|
221
|
-
* const
|
|
222
|
-
* const
|
|
213
|
+
* // Add stream from encoder
|
|
214
|
+
* const videoIdx = output.addStream(videoEncoder);
|
|
215
|
+
* const audioIdx = output.addStream(audioEncoder);
|
|
223
216
|
* ```
|
|
224
217
|
*
|
|
225
218
|
* @example
|
|
226
219
|
* ```typescript
|
|
227
|
-
* //
|
|
228
|
-
* const streamIdx = output.addStream(
|
|
229
|
-
* timeBase: { num: 1, den: 90000 }
|
|
220
|
+
* // Stream copy with custom timebase
|
|
221
|
+
* const streamIdx = output.addStream(input.video(), {
|
|
222
|
+
* timeBase: { num: 1, den: 90000 }
|
|
230
223
|
* });
|
|
231
|
-
* // Packets from encoder will be automatically rescaled to 1/90000
|
|
232
224
|
* ```
|
|
225
|
+
*
|
|
226
|
+
* @see {@link writePacket} For writing packets to streams
|
|
227
|
+
* @see {@link Encoder} For transcoding source
|
|
233
228
|
*/
|
|
234
229
|
addStream(source, options) {
|
|
235
230
|
if (this.closed) {
|
|
@@ -277,26 +272,42 @@ export class MediaOutput {
|
|
|
277
272
|
return stream.index;
|
|
278
273
|
}
|
|
279
274
|
/**
|
|
280
|
-
*
|
|
275
|
+
* Write a packet to the output.
|
|
281
276
|
*
|
|
282
|
-
* Writes
|
|
283
|
-
* Automatically
|
|
277
|
+
* Writes muxed packet to the specified stream.
|
|
278
|
+
* Automatically handles timestamp rescaling.
|
|
279
|
+
* Must be called after writeHeader() and before writeTrailer().
|
|
284
280
|
*
|
|
285
|
-
*
|
|
281
|
+
* Direct mapping to av_interleaved_write_frame().
|
|
286
282
|
*
|
|
287
283
|
* @param packet - Packet to write
|
|
288
284
|
* @param streamIndex - Target stream index
|
|
285
|
+
* @throws {Error} If stream invalid or called at wrong time
|
|
286
|
+
* @throws {FFmpegError} If write fails
|
|
289
287
|
*
|
|
290
|
-
* @
|
|
288
|
+
* @example
|
|
289
|
+
* ```typescript
|
|
290
|
+
* // Write encoded packet
|
|
291
|
+
* const packet = await encoder.encode(frame);
|
|
292
|
+
* if (packet) {
|
|
293
|
+
* await output.writePacket(packet, videoIdx);
|
|
294
|
+
* packet.free();
|
|
295
|
+
* }
|
|
296
|
+
* ```
|
|
291
297
|
*
|
|
292
298
|
* @example
|
|
293
299
|
* ```typescript
|
|
294
|
-
*
|
|
295
|
-
*
|
|
296
|
-
*
|
|
297
|
-
*
|
|
300
|
+
* // Stream copy with packet processing
|
|
301
|
+
* for await (const packet of input.packets()) {
|
|
302
|
+
* if (packet.streamIndex === inputVideoIdx) {
|
|
303
|
+
* await output.writePacket(packet, outputVideoIdx);
|
|
304
|
+
* }
|
|
305
|
+
* packet.free();
|
|
298
306
|
* }
|
|
299
307
|
* ```
|
|
308
|
+
*
|
|
309
|
+
* @see {@link addStream} For adding streams
|
|
310
|
+
* @see {@link writeHeader} Must be called first
|
|
300
311
|
*/
|
|
301
312
|
async writePacket(packet, streamIndex) {
|
|
302
313
|
if (this.closed) {
|
|
@@ -332,21 +343,29 @@ export class MediaOutput {
|
|
|
332
343
|
FFmpegError.throwIfError(ret, 'Failed to write packet');
|
|
333
344
|
}
|
|
334
345
|
/**
|
|
335
|
-
*
|
|
336
|
-
*
|
|
337
|
-
* Writes the container header with stream information.
|
|
338
|
-
* Must be called before writing any packets.
|
|
346
|
+
* Write file header.
|
|
339
347
|
*
|
|
340
|
-
*
|
|
348
|
+
* Writes format header with stream configuration.
|
|
349
|
+
* Must be called after adding all streams and before writing packets.
|
|
350
|
+
* Finalizes stream parameters and initializes muxer.
|
|
341
351
|
*
|
|
342
|
-
*
|
|
352
|
+
* Direct mapping to avformat_write_header().
|
|
343
353
|
*
|
|
344
|
-
* @throws {Error} If
|
|
354
|
+
* @throws {Error} If already written or output closed
|
|
355
|
+
* @throws {FFmpegError} If write fails
|
|
345
356
|
*
|
|
346
357
|
* @example
|
|
347
358
|
* ```typescript
|
|
359
|
+
* // Standard workflow
|
|
360
|
+
* const output = await MediaOutput.open('output.mp4');
|
|
361
|
+
* output.addStream(encoder);
|
|
348
362
|
* await output.writeHeader();
|
|
363
|
+
* // Now ready to write packets
|
|
349
364
|
* ```
|
|
365
|
+
*
|
|
366
|
+
* @see {@link addStream} Must add streams first
|
|
367
|
+
* @see {@link writePacket} Can write packets after
|
|
368
|
+
* @see {@link writeTrailer} Must call at end
|
|
350
369
|
*/
|
|
351
370
|
async writeHeader() {
|
|
352
371
|
if (this.closed) {
|
|
@@ -360,19 +379,26 @@ export class MediaOutput {
|
|
|
360
379
|
this.headerWritten = true;
|
|
361
380
|
}
|
|
362
381
|
/**
|
|
363
|
-
*
|
|
382
|
+
* Write file trailer.
|
|
364
383
|
*
|
|
365
|
-
*
|
|
366
|
-
*
|
|
384
|
+
* Writes format trailer and finalizes the file.
|
|
385
|
+
* Must be called after all packets are written.
|
|
386
|
+
* Flushes any buffered data and updates file headers.
|
|
367
387
|
*
|
|
368
|
-
*
|
|
388
|
+
* Direct mapping to av_write_trailer().
|
|
369
389
|
*
|
|
370
|
-
* @throws {Error} If header not written
|
|
390
|
+
* @throws {Error} If header not written or already written
|
|
391
|
+
* @throws {FFmpegError} If write fails
|
|
371
392
|
*
|
|
372
393
|
* @example
|
|
373
394
|
* ```typescript
|
|
395
|
+
* // Finalize output
|
|
374
396
|
* await output.writeTrailer();
|
|
397
|
+
* await output.close();
|
|
375
398
|
* ```
|
|
399
|
+
*
|
|
400
|
+
* @see {@link writeHeader} Must be called first
|
|
401
|
+
* @see {@link close} For cleanup after trailer
|
|
376
402
|
*/
|
|
377
403
|
async writeTrailer() {
|
|
378
404
|
if (this.closed) {
|
|
@@ -389,17 +415,23 @@ export class MediaOutput {
|
|
|
389
415
|
this.trailerWritten = true;
|
|
390
416
|
}
|
|
391
417
|
/**
|
|
392
|
-
*
|
|
418
|
+
* Close media output and free resources.
|
|
393
419
|
*
|
|
394
|
-
* Writes trailer if needed
|
|
420
|
+
* Writes trailer if needed and releases all resources.
|
|
395
421
|
* Safe to call multiple times.
|
|
396
|
-
*
|
|
397
|
-
* Uses av_write_trailer(), avio_closep(), and avformat_free_context() internally.
|
|
422
|
+
* Automatically called by Symbol.asyncDispose.
|
|
398
423
|
*
|
|
399
424
|
* @example
|
|
400
425
|
* ```typescript
|
|
401
|
-
* await output.
|
|
426
|
+
* const output = await MediaOutput.open('output.mp4');
|
|
427
|
+
* try {
|
|
428
|
+
* // Use output
|
|
429
|
+
* } finally {
|
|
430
|
+
* await output.close();
|
|
431
|
+
* }
|
|
402
432
|
* ```
|
|
433
|
+
*
|
|
434
|
+
* @see {@link Symbol.asyncDispose} For automatic cleanup
|
|
403
435
|
*/
|
|
404
436
|
async close() {
|
|
405
437
|
if (this.closed) {
|
|
@@ -419,9 +451,11 @@ export class MediaOutput {
|
|
|
419
451
|
if (this.ioContext) {
|
|
420
452
|
this.formatContext.pb = null;
|
|
421
453
|
}
|
|
454
|
+
// Determine if this is custom IO before freeing format context
|
|
455
|
+
const isCustomIO = (this.formatContext.flags & AVFMT_FLAG_CUSTOM_IO) !== 0;
|
|
422
456
|
// For file-based IO, close the file handle via closep
|
|
423
457
|
// For custom IO, the context will be freed below
|
|
424
|
-
if (this.ioContext && !
|
|
458
|
+
if (this.ioContext && !isCustomIO) {
|
|
425
459
|
try {
|
|
426
460
|
await this.ioContext.closep();
|
|
427
461
|
}
|
|
@@ -439,7 +473,7 @@ export class MediaOutput {
|
|
|
439
473
|
}
|
|
440
474
|
}
|
|
441
475
|
// Now free custom IO context if present
|
|
442
|
-
if (this.ioContext &&
|
|
476
|
+
if (this.ioContext && isCustomIO) {
|
|
443
477
|
try {
|
|
444
478
|
this.ioContext.freeContext();
|
|
445
479
|
}
|
|
@@ -449,47 +483,95 @@ export class MediaOutput {
|
|
|
449
483
|
}
|
|
450
484
|
}
|
|
451
485
|
/**
|
|
452
|
-
*
|
|
486
|
+
* Get stream information.
|
|
487
|
+
*
|
|
488
|
+
* Returns internal stream info for the specified index.
|
|
489
|
+
*
|
|
490
|
+
* @param streamIndex - Stream index
|
|
491
|
+
* @returns Stream info or undefined
|
|
492
|
+
*
|
|
493
|
+
* @example
|
|
494
|
+
* ```typescript
|
|
495
|
+
* const info = output.getStreamInfo(0);
|
|
496
|
+
* console.log(`Stream 0 timebase: ${info?.timeBase.num}/${info?.timeBase.den}`);
|
|
497
|
+
* ```
|
|
453
498
|
*/
|
|
454
499
|
getStreamInfo(streamIndex) {
|
|
455
500
|
return this.streams.get(streamIndex);
|
|
456
501
|
}
|
|
457
502
|
/**
|
|
458
|
-
*
|
|
503
|
+
* Get all stream indices.
|
|
504
|
+
*
|
|
505
|
+
* Returns array of all added stream indices.
|
|
506
|
+
*
|
|
507
|
+
* @returns Array of stream indices
|
|
508
|
+
*
|
|
509
|
+
* @example
|
|
510
|
+
* ```typescript
|
|
511
|
+
* const indices = output.getStreamIndices();
|
|
512
|
+
* console.log(`Output has ${indices.length} streams`);
|
|
513
|
+
* ```
|
|
459
514
|
*/
|
|
460
515
|
getStreamIndices() {
|
|
461
516
|
return Array.from(this.streams.keys());
|
|
462
517
|
}
|
|
463
518
|
/**
|
|
464
|
-
*
|
|
519
|
+
* Check if header has been written.
|
|
520
|
+
*
|
|
521
|
+
* @returns true if header written
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```typescript
|
|
525
|
+
* if (!output.isHeaderWritten()) {
|
|
526
|
+
* await output.writeHeader();
|
|
527
|
+
* }
|
|
528
|
+
* ```
|
|
465
529
|
*/
|
|
466
530
|
isHeaderWritten() {
|
|
467
531
|
return this.headerWritten;
|
|
468
532
|
}
|
|
469
533
|
/**
|
|
470
|
-
*
|
|
534
|
+
* Check if trailer has been written.
|
|
535
|
+
*
|
|
536
|
+
* @returns true if trailer written
|
|
537
|
+
*
|
|
538
|
+
* @example
|
|
539
|
+
* ```typescript
|
|
540
|
+
* if (!output.isTrailerWritten()) {
|
|
541
|
+
* await output.writeTrailer();
|
|
542
|
+
* }
|
|
543
|
+
* ```
|
|
471
544
|
*/
|
|
472
545
|
isTrailerWritten() {
|
|
473
546
|
return this.trailerWritten;
|
|
474
547
|
}
|
|
475
548
|
/**
|
|
476
|
-
*
|
|
549
|
+
* Get underlying format context.
|
|
477
550
|
*
|
|
478
|
-
*
|
|
551
|
+
* Returns the internal format context for advanced operations.
|
|
552
|
+
*
|
|
553
|
+
* @returns Format context
|
|
554
|
+
*
|
|
555
|
+
* @internal
|
|
479
556
|
*/
|
|
480
557
|
getFormatContext() {
|
|
481
558
|
return this.formatContext;
|
|
482
559
|
}
|
|
483
560
|
/**
|
|
484
|
-
*
|
|
561
|
+
* Dispose of media output.
|
|
485
562
|
*
|
|
486
|
-
*
|
|
563
|
+
* Implements AsyncDisposable interface for automatic cleanup.
|
|
564
|
+
* Equivalent to calling close().
|
|
487
565
|
*
|
|
488
566
|
* @example
|
|
489
567
|
* ```typescript
|
|
490
|
-
*
|
|
491
|
-
*
|
|
568
|
+
* {
|
|
569
|
+
* await using output = await MediaOutput.open('output.mp4');
|
|
570
|
+
* // Use output...
|
|
571
|
+
* } // Automatically closed
|
|
492
572
|
* ```
|
|
573
|
+
*
|
|
574
|
+
* @see {@link close} For manual cleanup
|
|
493
575
|
*/
|
|
494
576
|
async [Symbol.asyncDispose]() {
|
|
495
577
|
await this.close();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"media-output.js","sourceRoot":"","sources":["../../src/api/media-output.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"media-output.js","sourceRoot":"","sources":["../../src/api/media-output.ts"],"names":[],"mappings":"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"}
|