node-av 5.2.4 → 6.0.0-beta.11

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.
Files changed (111) hide show
  1. package/README.md +15 -1
  2. package/dist/api/bitstream-filter.d.ts +110 -87
  3. package/dist/api/bitstream-filter.js +161 -103
  4. package/dist/api/bitstream-filter.js.map +1 -1
  5. package/dist/api/decoder.d.ts +177 -15
  6. package/dist/api/decoder.js +335 -28
  7. package/dist/api/decoder.js.map +1 -1
  8. package/dist/api/demuxer.d.ts +30 -24
  9. package/dist/api/demuxer.js +4 -5
  10. package/dist/api/demuxer.js.map +1 -1
  11. package/dist/api/device.js.map +1 -1
  12. package/dist/api/encoder-pool.d.ts +220 -0
  13. package/dist/api/encoder-pool.js +285 -0
  14. package/dist/api/encoder-pool.js.map +1 -0
  15. package/dist/api/encoder.d.ts +194 -7
  16. package/dist/api/encoder.js +431 -71
  17. package/dist/api/encoder.js.map +1 -1
  18. package/dist/api/filter-complex.d.ts +2 -1
  19. package/dist/api/filter-complex.js +11 -7
  20. package/dist/api/filter-complex.js.map +1 -1
  21. package/dist/api/filter-presets.d.ts +130 -654
  22. package/dist/api/filter-presets.js +180 -858
  23. package/dist/api/filter-presets.js.map +1 -1
  24. package/dist/api/filter.js +12 -9
  25. package/dist/api/filter.js.map +1 -1
  26. package/dist/api/fmp4-stream.js +1 -1
  27. package/dist/api/fmp4-stream.js.map +1 -1
  28. package/dist/api/index.d.ts +6 -6
  29. package/dist/api/index.js +8 -8
  30. package/dist/api/index.js.map +1 -1
  31. package/dist/api/muxer.d.ts +43 -15
  32. package/dist/api/muxer.js +79 -27
  33. package/dist/api/muxer.js.map +1 -1
  34. package/dist/api/pipeline.d.ts +50 -0
  35. package/dist/api/pipeline.js +138 -22
  36. package/dist/api/pipeline.js.map +1 -1
  37. package/dist/api/probe.d.ts +128 -0
  38. package/dist/api/probe.js +227 -0
  39. package/dist/api/probe.js.map +1 -0
  40. package/dist/api/rtp-stream.d.ts +14 -11
  41. package/dist/api/rtp-stream.js +23 -48
  42. package/dist/api/rtp-stream.js.map +1 -1
  43. package/dist/api/scaler.d.ts +431 -0
  44. package/dist/api/scaler.js +620 -0
  45. package/dist/api/scaler.js.map +1 -0
  46. package/dist/api/utilities/async-queue.d.ts +27 -1
  47. package/dist/api/utilities/async-queue.js +38 -3
  48. package/dist/api/utilities/async-queue.js.map +1 -1
  49. package/dist/api/utilities/codec-format.d.ts +87 -0
  50. package/dist/api/utilities/codec-format.js +117 -0
  51. package/dist/api/utilities/codec-format.js.map +1 -0
  52. package/dist/api/utilities/electron-shared-texture.d.ts +41 -1
  53. package/dist/api/utilities/electron-shared-texture.js +41 -4
  54. package/dist/api/utilities/electron-shared-texture.js.map +1 -1
  55. package/dist/api/utilities/index.d.ts +2 -1
  56. package/dist/api/utilities/index.js +2 -0
  57. package/dist/api/utilities/index.js.map +1 -1
  58. package/dist/api/webrtc-stream.d.ts +0 -1
  59. package/dist/api/webrtc-stream.js +0 -1
  60. package/dist/api/webrtc-stream.js.map +1 -1
  61. package/dist/constants/bsf-options.d.ts +333 -0
  62. package/dist/constants/bsf-options.js +7 -0
  63. package/dist/constants/bsf-options.js.map +1 -0
  64. package/dist/constants/constants.d.ts +109 -0
  65. package/dist/constants/constants.js +110 -0
  66. package/dist/constants/constants.js.map +1 -1
  67. package/dist/constants/decoders.d.ts +636 -618
  68. package/dist/constants/decoders.js +1 -3
  69. package/dist/constants/decoders.js.map +1 -1
  70. package/dist/constants/encoders.d.ts +300 -282
  71. package/dist/constants/encoders.js +0 -2
  72. package/dist/constants/encoders.js.map +1 -1
  73. package/dist/constants/filter-options.d.ts +10915 -0
  74. package/dist/constants/filter-options.js +7 -0
  75. package/dist/constants/filter-options.js.map +1 -0
  76. package/dist/constants/format-options.d.ts +3056 -0
  77. package/dist/constants/format-options.js +7 -0
  78. package/dist/constants/format-options.js.map +1 -0
  79. package/dist/constants/formats.d.ts +18 -0
  80. package/dist/constants/formats.js +7 -0
  81. package/dist/constants/formats.js.map +1 -0
  82. package/dist/constants/index.d.ts +5 -0
  83. package/dist/constants/options.d.ts +4073 -0
  84. package/dist/constants/options.js +7 -0
  85. package/dist/constants/options.js.map +1 -0
  86. package/dist/lib/binding.d.ts +5 -1
  87. package/dist/lib/binding.js.map +1 -1
  88. package/dist/lib/codec.d.ts +36 -5
  89. package/dist/lib/codec.js +37 -4
  90. package/dist/lib/codec.js.map +1 -1
  91. package/dist/lib/dictionary.d.ts +1 -1
  92. package/dist/lib/dictionary.js.map +1 -1
  93. package/dist/lib/error.d.ts +69 -0
  94. package/dist/lib/error.js +92 -0
  95. package/dist/lib/error.js.map +1 -1
  96. package/dist/lib/frame.d.ts +55 -3
  97. package/dist/lib/frame.js +59 -3
  98. package/dist/lib/frame.js.map +1 -1
  99. package/dist/lib/index.d.ts +1 -1
  100. package/dist/lib/index.js.map +1 -1
  101. package/dist/lib/native-types.d.ts +68 -0
  102. package/dist/lib/packet.d.ts +22 -3
  103. package/dist/lib/packet.js +24 -3
  104. package/dist/lib/packet.js.map +1 -1
  105. package/dist/lib/utilities.d.ts +45 -0
  106. package/dist/lib/utilities.js +49 -0
  107. package/dist/lib/utilities.js.map +1 -1
  108. package/dist/webrtc/index.d.ts +3 -0
  109. package/dist/webrtc/index.js +7 -0
  110. package/dist/webrtc/index.js.map +1 -0
  111. package/package.json +34 -23
@@ -3,16 +3,16 @@ import { Codec } from '../lib/codec.js';
3
3
  import { Frame } from '../lib/frame.js';
4
4
  import { Packet } from '../lib/packet.js';
5
5
  import { Scheduler } from './utilities/scheduler.js';
6
- import type { AVCodecID, AVPixelFormat, AVThreadType, EOFSignal, FFDecoderCodec } from '../constants/index.js';
6
+ import type { AVCodecID, AVPixelFormat, AVSampleFormat, AVThreadType, DecoderOptionsFor, EOFSignal, FFDecoderCodec } from '../constants/index.js';
7
7
  import type { Stream } from '../lib/stream.js';
8
- import type { IRational } from '../lib/types.js';
8
+ import type { ChannelLayout, IRational } from '../lib/types.js';
9
9
  import type { Encoder } from './encoder.js';
10
10
  import type { FilterAPI } from './filter.js';
11
11
  import type { HardwareContext } from './hardware.js';
12
12
  /**
13
13
  * Options for decoder creation.
14
14
  */
15
- export interface DecoderOptions {
15
+ export interface DecoderOptions<C = unknown> {
16
16
  /**
17
17
  * Exit immediately on first decode error.
18
18
  *
@@ -36,13 +36,6 @@ export interface DecoderOptions {
36
36
  * Some hardware decoders need extra frames for reference or look-ahead.
37
37
  */
38
38
  extraHWFrames?: number;
39
- /**
40
- * Hardware frame output format.
41
- *
42
- * When set, hardware frames will be automatically transferred to this software pixel format.
43
- * Useful when you need software frames for further processing but want to use hardware decoding.
44
- */
45
- hwaccelOutputFormat?: AVPixelFormat;
46
39
  /**
47
40
  * Force constant framerate mode.
48
41
  *
@@ -68,6 +61,57 @@ export interface DecoderOptions {
68
61
  * @default false
69
62
  */
70
63
  applyCropping?: boolean;
64
+ /**
65
+ * Resample decoded audio to a target format (audio only).
66
+ *
67
+ * When set, decoded audio frames are transparently converted to the requested
68
+ * sample rate, sample format, and/or channel layout before they are returned —
69
+ * the audio mirror of {@link rescale}. Any omitted field keeps the decoded
70
+ * value, and conversion is skipped entirely when the source already matches the
71
+ * target. Useful when a capture device delivers a rate you cannot control (e.g.
72
+ * avfoundation ignoring a microphone sample-rate request) and you want every
73
+ * downstream stage to receive the rate you asked for.
74
+ *
75
+ * @example
76
+ * ```typescript
77
+ * // Guarantee 48 kHz frames regardless of the device's actual rate
78
+ * const decoder = await Decoder.create(stream, { resample: { sampleRate: 48000 } });
79
+ * ```
80
+ */
81
+ resample?: {
82
+ sampleRate?: number;
83
+ sampleFormat?: AVSampleFormat;
84
+ channelLayout?: ChannelLayout;
85
+ };
86
+ /**
87
+ * Rescale decoded video to a target pixel format and/or size (video only).
88
+ *
89
+ * When set, decoded video frames are transparently converted to the requested
90
+ * pixel format and/or dimensions before they are returned — the video mirror of
91
+ * {@link resample}. Any omitted field keeps the decoded value, and conversion is
92
+ * skipped entirely when the source already matches the target.
93
+ *
94
+ * Hardware frames are automatically transferred to a supported software format
95
+ * first and then converted to the requested one; software frames are converted
96
+ * directly. Hardware frames are left untouched (kept on the GPU, zero-copy) when
97
+ * `rescale` is not set. This replaces the former `hwaccelOutputFormat` option:
98
+ * use `rescale: { pixelFormat }` to get decoded frames in a fixed software format.
99
+ *
100
+ * Useful to normalize a heterogeneous set of sources (e.g. RTSP cameras that each
101
+ * deliver a different pixel format) so every downstream stage receives a uniform
102
+ * format/size, regardless of whether a stream was hardware- or software-decoded.
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * // Normalize any source to yuv420p, whether it was hardware- or software-decoded
107
+ * const decoder = await Decoder.create(stream, { hardware: hw, rescale: { pixelFormat: AV_PIX_FMT_YUV420P } });
108
+ * ```
109
+ */
110
+ rescale?: {
111
+ width?: number;
112
+ height?: number;
113
+ pixelFormat?: AVPixelFormat;
114
+ };
71
115
  /**
72
116
  * Number of threads to use for decoding.
73
117
  *
@@ -92,10 +136,12 @@ export interface DecoderOptions {
92
136
  /**
93
137
  * Additional codec-specific options.
94
138
  *
95
- * Key-value pairs of FFmpeg AVCodecContext options.
96
- * These are passed directly to the decoder.
139
+ * Key-value pairs of FFmpeg private codec options, passed directly to the decoder.
140
+ * When the codec is created from a branded constant (e.g. `FF_DECODER_H264_CUVID`),
141
+ * these are strongly typed to that codec's known options (autocomplete + validation);
142
+ * otherwise any string/number/boolean values are accepted.
97
143
  */
98
- options?: Record<string, string | number | boolean | undefined | null>;
144
+ options?: DecoderOptionsFor<C>;
99
145
  /**
100
146
  * AbortSignal for cancellation.
101
147
  *
@@ -158,6 +204,15 @@ export declare class Decoder implements Disposable {
158
204
  private lastFrameTb;
159
205
  private lastFrameSampleRate;
160
206
  private lastFilterInRescaleDelta;
207
+ private audioResampler?;
208
+ private resampledFrame?;
209
+ private resampleTarget?;
210
+ private resampleInputLayout?;
211
+ private audioResamplerSetup;
212
+ private audioResamplerDrained;
213
+ private videoScaler?;
214
+ private scaledFrame?;
215
+ private hwTransferFormat?;
161
216
  private inputQueue;
162
217
  private outputQueue;
163
218
  private workerPromise;
@@ -235,7 +290,7 @@ export declare class Decoder implements Disposable {
235
290
  * @see {@link createSync} For synchronous version
236
291
  */
237
292
  static create(stream: Stream, options?: DecoderOptions): Promise<Decoder>;
238
- static create(stream: Stream, decoderCodec?: FFDecoderCodec | AVCodecID | Codec, options?: DecoderOptions): Promise<Decoder>;
293
+ static create<const C extends FFDecoderCodec | AVCodecID | Codec>(stream: Stream, decoderCodec: C, options?: DecoderOptions<C>): Promise<Decoder>;
239
294
  /**
240
295
  * Create a decoder for a media stream synchronously.
241
296
  * Synchronous version of create.
@@ -292,7 +347,7 @@ export declare class Decoder implements Disposable {
292
347
  * @see {@link create} For async version
293
348
  */
294
349
  static createSync(stream: Stream, options?: DecoderOptions): Decoder;
295
- static createSync(stream: Stream, decoderCodec?: FFDecoderCodec | AVCodecID | Codec, options?: DecoderOptions): Decoder;
350
+ static createSync<const C extends FFDecoderCodec | AVCodecID | Codec>(stream: Stream, decoderCodec: C, options?: DecoderOptions<C>): Decoder;
296
351
  /**
297
352
  * Check if decoder is open.
298
353
  *
@@ -1068,6 +1123,113 @@ export declare class Decoder implements Disposable {
1068
1123
  * @internal
1069
1124
  */
1070
1125
  private processAudioFrame;
1126
+ /**
1127
+ * Lazily configure the audio output resampler from the first decoded frame.
1128
+ *
1129
+ * Reads the source format from the frame, resolves the target from
1130
+ * `options.resample` (omitted fields keep the source value), and builds a
1131
+ * `SoftwareResampleContext` only when something actually differs. Runs once.
1132
+ *
1133
+ * @param frame - First decoded audio frame
1134
+ *
1135
+ * @throws {FFmpegError} If the resampler cannot be configured or initialized
1136
+ *
1137
+ * @internal
1138
+ */
1139
+ private setupAudioResampler;
1140
+ /**
1141
+ * Lazily allocate the reused resampler output frame.
1142
+ *
1143
+ * @returns The allocated output frame
1144
+ *
1145
+ * @internal
1146
+ */
1147
+ private getResampleFrame;
1148
+ /**
1149
+ * Resample a decoded audio frame to the target format and clone it for the user.
1150
+ *
1151
+ * `swr_convert_frame` allocates/sizes the output buffer; the sample timestamp
1152
+ * (carried in the frame's own timebase) is preserved, while `nb_samples` and
1153
+ * `sample_rate` reflect the new rate. Returns null when the resampler buffered
1154
+ * the input without emitting samples yet (caller should feed more).
1155
+ *
1156
+ * @param frame - Decoded source audio frame
1157
+ *
1158
+ * @returns Cloned resampled frame owned by the caller, or null if none emitted
1159
+ *
1160
+ * @throws {FFmpegError} If resampling fails
1161
+ *
1162
+ * @internal
1163
+ */
1164
+ private resampleAudioClone;
1165
+ /**
1166
+ * Drain samples buffered inside the resampler (rate-conversion delay) at EOF.
1167
+ *
1168
+ * @returns Cloned drained frame owned by the caller, or null when empty
1169
+ *
1170
+ * @throws {FFmpegError} If draining fails
1171
+ *
1172
+ * @internal
1173
+ */
1174
+ private drainResamplerClone;
1175
+ /**
1176
+ * Resolve (once, then cache) the software format to download hardware frames to.
1177
+ *
1178
+ * When `rescale.pixelFormat` is set and the frame's hardware frames context can
1179
+ * transfer directly to it, that format is used so the subsequent swscale can be
1180
+ * skipped entirely (when no resize is requested) or stay format-preserving. When
1181
+ * it cannot, `AV_PIX_FMT_NONE` is returned so `av_hwframe_transfer_data` picks a
1182
+ * supported format and the swscale handles the final conversion. Cached because
1183
+ * the hardware frames context is stable for the lifetime of the decoder.
1184
+ *
1185
+ * @param frame - First hardware frame (used to read the hardware frames context)
1186
+ *
1187
+ * @returns The download format, or `AV_PIX_FMT_NONE` to let FFmpeg choose
1188
+ *
1189
+ * @internal
1190
+ */
1191
+ private resolveHwTransferFormat;
1192
+ /**
1193
+ * Transfer a hardware frame down to system memory, replacing it in place.
1194
+ *
1195
+ * The destination software format is the requested one when the GPU can transfer
1196
+ * to it directly (see {@link resolveHwTransferFormat}), otherwise one chosen
1197
+ * automatically by FFmpeg. The downloaded data replaces the hardware frame's
1198
+ * contents so the rest of the pipeline operates on a software frame.
1199
+ *
1200
+ * @param frame - Hardware frame to download (modified in place)
1201
+ *
1202
+ * @returns True on success; false when the transfer failed and `exitOnError` is off
1203
+ *
1204
+ * @throws {FFmpegError} If the transfer fails and `exitOnError` is enabled
1205
+ *
1206
+ * @internal
1207
+ */
1208
+ private transferHwFrameToSoftware;
1209
+ /**
1210
+ * Lazily allocate the reused rescaler output frame.
1211
+ *
1212
+ * @returns The allocated output frame
1213
+ *
1214
+ * @internal
1215
+ */
1216
+ private getScaledFrame;
1217
+ /**
1218
+ * Convert a (software) video frame to the requested `rescale` pixel format and/or
1219
+ * size, replacing it in place.
1220
+ *
1221
+ * Each omitted target field keeps the source value, and the conversion is skipped
1222
+ * entirely when the frame already matches. The swscale context is configured
1223
+ * lazily from the first frame that needs conversion. `sws_scale_frame` copies the
1224
+ * frame properties (timing, colorimetry, aspect ratio).
1225
+ *
1226
+ * @param frame - Software video frame to convert (modified in place)
1227
+ *
1228
+ * @throws {FFmpegError} If the rescaler fails to configure or convert and `exitOnError` is enabled
1229
+ *
1230
+ * @internal
1231
+ */
1232
+ private rescaleVideoInPlace;
1071
1233
  /**
1072
1234
  * Dispose of decoder.
1073
1235
  *