@revizly/node-av 5.2.2-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (254) hide show
  1. package/BUILD_LINUX.md +61 -0
  2. package/LICENSE.md +22 -0
  3. package/README.md +662 -0
  4. package/build_mac_local.sh +69 -0
  5. package/dist/api/audio-frame-buffer.d.ts +205 -0
  6. package/dist/api/audio-frame-buffer.js +287 -0
  7. package/dist/api/audio-frame-buffer.js.map +1 -0
  8. package/dist/api/bitstream-filter.d.ts +820 -0
  9. package/dist/api/bitstream-filter.js +1242 -0
  10. package/dist/api/bitstream-filter.js.map +1 -0
  11. package/dist/api/constants.d.ts +44 -0
  12. package/dist/api/constants.js +45 -0
  13. package/dist/api/constants.js.map +1 -0
  14. package/dist/api/data/test_av1.ivf +0 -0
  15. package/dist/api/data/test_h264.h264 +0 -0
  16. package/dist/api/data/test_hevc.h265 +0 -0
  17. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  18. package/dist/api/data/test_vp8.ivf +0 -0
  19. package/dist/api/data/test_vp9.ivf +0 -0
  20. package/dist/api/decoder.d.ts +1088 -0
  21. package/dist/api/decoder.js +1775 -0
  22. package/dist/api/decoder.js.map +1 -0
  23. package/dist/api/demuxer.d.ts +1219 -0
  24. package/dist/api/demuxer.js +2081 -0
  25. package/dist/api/demuxer.js.map +1 -0
  26. package/dist/api/device.d.ts +586 -0
  27. package/dist/api/device.js +961 -0
  28. package/dist/api/device.js.map +1 -0
  29. package/dist/api/encoder.d.ts +1132 -0
  30. package/dist/api/encoder.js +1988 -0
  31. package/dist/api/encoder.js.map +1 -0
  32. package/dist/api/filter-complex.d.ts +821 -0
  33. package/dist/api/filter-complex.js +1604 -0
  34. package/dist/api/filter-complex.js.map +1 -0
  35. package/dist/api/filter-presets.d.ts +1286 -0
  36. package/dist/api/filter-presets.js +2152 -0
  37. package/dist/api/filter-presets.js.map +1 -0
  38. package/dist/api/filter.d.ts +1234 -0
  39. package/dist/api/filter.js +1976 -0
  40. package/dist/api/filter.js.map +1 -0
  41. package/dist/api/fmp4-stream.d.ts +426 -0
  42. package/dist/api/fmp4-stream.js +739 -0
  43. package/dist/api/fmp4-stream.js.map +1 -0
  44. package/dist/api/hardware.d.ts +651 -0
  45. package/dist/api/hardware.js +1260 -0
  46. package/dist/api/hardware.js.map +1 -0
  47. package/dist/api/index.d.ts +17 -0
  48. package/dist/api/index.js +32 -0
  49. package/dist/api/index.js.map +1 -0
  50. package/dist/api/io-stream.d.ts +307 -0
  51. package/dist/api/io-stream.js +282 -0
  52. package/dist/api/io-stream.js.map +1 -0
  53. package/dist/api/muxer.d.ts +957 -0
  54. package/dist/api/muxer.js +2002 -0
  55. package/dist/api/muxer.js.map +1 -0
  56. package/dist/api/pipeline.d.ts +607 -0
  57. package/dist/api/pipeline.js +1145 -0
  58. package/dist/api/pipeline.js.map +1 -0
  59. package/dist/api/utilities/async-queue.d.ts +120 -0
  60. package/dist/api/utilities/async-queue.js +211 -0
  61. package/dist/api/utilities/async-queue.js.map +1 -0
  62. package/dist/api/utilities/audio-sample.d.ts +117 -0
  63. package/dist/api/utilities/audio-sample.js +112 -0
  64. package/dist/api/utilities/audio-sample.js.map +1 -0
  65. package/dist/api/utilities/channel-layout.d.ts +76 -0
  66. package/dist/api/utilities/channel-layout.js +80 -0
  67. package/dist/api/utilities/channel-layout.js.map +1 -0
  68. package/dist/api/utilities/electron-shared-texture.d.ts +328 -0
  69. package/dist/api/utilities/electron-shared-texture.js +503 -0
  70. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  71. package/dist/api/utilities/image.d.ts +207 -0
  72. package/dist/api/utilities/image.js +213 -0
  73. package/dist/api/utilities/image.js.map +1 -0
  74. package/dist/api/utilities/index.d.ts +12 -0
  75. package/dist/api/utilities/index.js +25 -0
  76. package/dist/api/utilities/index.js.map +1 -0
  77. package/dist/api/utilities/media-type.d.ts +49 -0
  78. package/dist/api/utilities/media-type.js +53 -0
  79. package/dist/api/utilities/media-type.js.map +1 -0
  80. package/dist/api/utilities/pixel-format.d.ts +89 -0
  81. package/dist/api/utilities/pixel-format.js +97 -0
  82. package/dist/api/utilities/pixel-format.js.map +1 -0
  83. package/dist/api/utilities/sample-format.d.ts +129 -0
  84. package/dist/api/utilities/sample-format.js +141 -0
  85. package/dist/api/utilities/sample-format.js.map +1 -0
  86. package/dist/api/utilities/scheduler.d.ts +138 -0
  87. package/dist/api/utilities/scheduler.js +98 -0
  88. package/dist/api/utilities/scheduler.js.map +1 -0
  89. package/dist/api/utilities/streaming.d.ts +186 -0
  90. package/dist/api/utilities/streaming.js +309 -0
  91. package/dist/api/utilities/streaming.js.map +1 -0
  92. package/dist/api/utilities/timestamp.d.ts +193 -0
  93. package/dist/api/utilities/timestamp.js +206 -0
  94. package/dist/api/utilities/timestamp.js.map +1 -0
  95. package/dist/api/utilities/whisper-model.d.ts +310 -0
  96. package/dist/api/utilities/whisper-model.js +528 -0
  97. package/dist/api/utilities/whisper-model.js.map +1 -0
  98. package/dist/api/utils.d.ts +19 -0
  99. package/dist/api/utils.js +39 -0
  100. package/dist/api/utils.js.map +1 -0
  101. package/dist/api/whisper.d.ts +324 -0
  102. package/dist/api/whisper.js +362 -0
  103. package/dist/api/whisper.js.map +1 -0
  104. package/dist/constants/channel-layouts.d.ts +53 -0
  105. package/dist/constants/channel-layouts.js +57 -0
  106. package/dist/constants/channel-layouts.js.map +1 -0
  107. package/dist/constants/constants.d.ts +2325 -0
  108. package/dist/constants/constants.js +1887 -0
  109. package/dist/constants/constants.js.map +1 -0
  110. package/dist/constants/decoders.d.ts +633 -0
  111. package/dist/constants/decoders.js +641 -0
  112. package/dist/constants/decoders.js.map +1 -0
  113. package/dist/constants/encoders.d.ts +295 -0
  114. package/dist/constants/encoders.js +308 -0
  115. package/dist/constants/encoders.js.map +1 -0
  116. package/dist/constants/hardware.d.ts +26 -0
  117. package/dist/constants/hardware.js +27 -0
  118. package/dist/constants/hardware.js.map +1 -0
  119. package/dist/constants/index.d.ts +5 -0
  120. package/dist/constants/index.js +6 -0
  121. package/dist/constants/index.js.map +1 -0
  122. package/dist/ffmpeg/index.d.ts +99 -0
  123. package/dist/ffmpeg/index.js +115 -0
  124. package/dist/ffmpeg/index.js.map +1 -0
  125. package/dist/ffmpeg/utils.d.ts +31 -0
  126. package/dist/ffmpeg/utils.js +68 -0
  127. package/dist/ffmpeg/utils.js.map +1 -0
  128. package/dist/ffmpeg/version.d.ts +6 -0
  129. package/dist/ffmpeg/version.js +7 -0
  130. package/dist/ffmpeg/version.js.map +1 -0
  131. package/dist/index.d.ts +4 -0
  132. package/dist/index.js +9 -0
  133. package/dist/index.js.map +1 -0
  134. package/dist/lib/audio-fifo.d.ts +399 -0
  135. package/dist/lib/audio-fifo.js +431 -0
  136. package/dist/lib/audio-fifo.js.map +1 -0
  137. package/dist/lib/binding.d.ts +228 -0
  138. package/dist/lib/binding.js +60 -0
  139. package/dist/lib/binding.js.map +1 -0
  140. package/dist/lib/bitstream-filter-context.d.ts +379 -0
  141. package/dist/lib/bitstream-filter-context.js +441 -0
  142. package/dist/lib/bitstream-filter-context.js.map +1 -0
  143. package/dist/lib/bitstream-filter.d.ts +140 -0
  144. package/dist/lib/bitstream-filter.js +154 -0
  145. package/dist/lib/bitstream-filter.js.map +1 -0
  146. package/dist/lib/codec-context.d.ts +1071 -0
  147. package/dist/lib/codec-context.js +1354 -0
  148. package/dist/lib/codec-context.js.map +1 -0
  149. package/dist/lib/codec-parameters.d.ts +616 -0
  150. package/dist/lib/codec-parameters.js +761 -0
  151. package/dist/lib/codec-parameters.js.map +1 -0
  152. package/dist/lib/codec-parser.d.ts +201 -0
  153. package/dist/lib/codec-parser.js +213 -0
  154. package/dist/lib/codec-parser.js.map +1 -0
  155. package/dist/lib/codec.d.ts +586 -0
  156. package/dist/lib/codec.js +713 -0
  157. package/dist/lib/codec.js.map +1 -0
  158. package/dist/lib/device.d.ts +291 -0
  159. package/dist/lib/device.js +324 -0
  160. package/dist/lib/device.js.map +1 -0
  161. package/dist/lib/dictionary.d.ts +333 -0
  162. package/dist/lib/dictionary.js +372 -0
  163. package/dist/lib/dictionary.js.map +1 -0
  164. package/dist/lib/error.d.ts +242 -0
  165. package/dist/lib/error.js +303 -0
  166. package/dist/lib/error.js.map +1 -0
  167. package/dist/lib/fifo.d.ts +416 -0
  168. package/dist/lib/fifo.js +453 -0
  169. package/dist/lib/fifo.js.map +1 -0
  170. package/dist/lib/filter-context.d.ts +712 -0
  171. package/dist/lib/filter-context.js +789 -0
  172. package/dist/lib/filter-context.js.map +1 -0
  173. package/dist/lib/filter-graph-segment.d.ts +160 -0
  174. package/dist/lib/filter-graph-segment.js +171 -0
  175. package/dist/lib/filter-graph-segment.js.map +1 -0
  176. package/dist/lib/filter-graph.d.ts +641 -0
  177. package/dist/lib/filter-graph.js +704 -0
  178. package/dist/lib/filter-graph.js.map +1 -0
  179. package/dist/lib/filter-inout.d.ts +198 -0
  180. package/dist/lib/filter-inout.js +257 -0
  181. package/dist/lib/filter-inout.js.map +1 -0
  182. package/dist/lib/filter.d.ts +243 -0
  183. package/dist/lib/filter.js +272 -0
  184. package/dist/lib/filter.js.map +1 -0
  185. package/dist/lib/format-context.d.ts +1254 -0
  186. package/dist/lib/format-context.js +1379 -0
  187. package/dist/lib/format-context.js.map +1 -0
  188. package/dist/lib/frame-utils.d.ts +116 -0
  189. package/dist/lib/frame-utils.js +98 -0
  190. package/dist/lib/frame-utils.js.map +1 -0
  191. package/dist/lib/frame.d.ts +1222 -0
  192. package/dist/lib/frame.js +1435 -0
  193. package/dist/lib/frame.js.map +1 -0
  194. package/dist/lib/hardware-device-context.d.ts +362 -0
  195. package/dist/lib/hardware-device-context.js +383 -0
  196. package/dist/lib/hardware-device-context.js.map +1 -0
  197. package/dist/lib/hardware-frames-context.d.ts +419 -0
  198. package/dist/lib/hardware-frames-context.js +477 -0
  199. package/dist/lib/hardware-frames-context.js.map +1 -0
  200. package/dist/lib/index.d.ts +35 -0
  201. package/dist/lib/index.js +60 -0
  202. package/dist/lib/index.js.map +1 -0
  203. package/dist/lib/input-format.d.ts +249 -0
  204. package/dist/lib/input-format.js +306 -0
  205. package/dist/lib/input-format.js.map +1 -0
  206. package/dist/lib/io-context.d.ts +696 -0
  207. package/dist/lib/io-context.js +769 -0
  208. package/dist/lib/io-context.js.map +1 -0
  209. package/dist/lib/log.d.ts +174 -0
  210. package/dist/lib/log.js +184 -0
  211. package/dist/lib/log.js.map +1 -0
  212. package/dist/lib/native-types.d.ts +946 -0
  213. package/dist/lib/native-types.js +2 -0
  214. package/dist/lib/native-types.js.map +1 -0
  215. package/dist/lib/option.d.ts +927 -0
  216. package/dist/lib/option.js +1583 -0
  217. package/dist/lib/option.js.map +1 -0
  218. package/dist/lib/output-format.d.ts +180 -0
  219. package/dist/lib/output-format.js +213 -0
  220. package/dist/lib/output-format.js.map +1 -0
  221. package/dist/lib/packet.d.ts +501 -0
  222. package/dist/lib/packet.js +590 -0
  223. package/dist/lib/packet.js.map +1 -0
  224. package/dist/lib/rational.d.ts +251 -0
  225. package/dist/lib/rational.js +278 -0
  226. package/dist/lib/rational.js.map +1 -0
  227. package/dist/lib/software-resample-context.d.ts +552 -0
  228. package/dist/lib/software-resample-context.js +592 -0
  229. package/dist/lib/software-resample-context.js.map +1 -0
  230. package/dist/lib/software-scale-context.d.ts +344 -0
  231. package/dist/lib/software-scale-context.js +366 -0
  232. package/dist/lib/software-scale-context.js.map +1 -0
  233. package/dist/lib/stream.d.ts +379 -0
  234. package/dist/lib/stream.js +526 -0
  235. package/dist/lib/stream.js.map +1 -0
  236. package/dist/lib/sync-queue.d.ts +179 -0
  237. package/dist/lib/sync-queue.js +197 -0
  238. package/dist/lib/sync-queue.js.map +1 -0
  239. package/dist/lib/types.d.ts +34 -0
  240. package/dist/lib/types.js +2 -0
  241. package/dist/lib/types.js.map +1 -0
  242. package/dist/lib/utilities.d.ts +1127 -0
  243. package/dist/lib/utilities.js +1225 -0
  244. package/dist/lib/utilities.js.map +1 -0
  245. package/dist/utils/electron.d.ts +49 -0
  246. package/dist/utils/electron.js +63 -0
  247. package/dist/utils/electron.js.map +1 -0
  248. package/dist/utils/index.d.ts +4 -0
  249. package/dist/utils/index.js +5 -0
  250. package/dist/utils/index.js.map +1 -0
  251. package/install/check.js +121 -0
  252. package/install/ffmpeg.js +66 -0
  253. package/jellyfin-ffmpeg.patch +181 -0
  254. package/package.json +129 -0
@@ -0,0 +1,1219 @@
1
+ import { Readable } from 'node:stream';
2
+ import { FormatContext } from '../lib/format-context.js';
3
+ import { InputFormat } from '../lib/input-format.js';
4
+ import { IOContext } from '../lib/io-context.js';
5
+ import { Packet } from '../lib/packet.js';
6
+ import type { AVMediaType, AVPixelFormat, AVSampleFormat, AVSeekFlag } from '../constants/index.js';
7
+ import type { Stream } from '../lib/stream.js';
8
+ import type { IRational } from '../lib/types.js';
9
+ import type { IOInputCallbacks } from './io-stream.js';
10
+ /**
11
+ * Raw video data configuration.
12
+ */
13
+ export interface VideoRawData {
14
+ /**
15
+ * Type discriminator for TypeScript.
16
+ *
17
+ * Must be set to 'video' to identify this as video raw data.
18
+ */
19
+ type: 'video';
20
+ /**
21
+ * Raw video input source.
22
+ *
23
+ * Can be a file path, Buffer containing raw video data, or custom I/O callbacks.
24
+ */
25
+ input: string | Buffer | IOInputCallbacks;
26
+ /**
27
+ * Video frame width in pixels.
28
+ *
29
+ * Must match the actual width of the raw video data.
30
+ */
31
+ width: number;
32
+ /**
33
+ * Video frame height in pixels.
34
+ *
35
+ * Must match the actual height of the raw video data.
36
+ */
37
+ height: number;
38
+ /**
39
+ * Pixel format of the raw video data.
40
+ *
41
+ * Specifies how pixel data is stored (e.g., YUV420P, NV12, RGB24).
42
+ */
43
+ pixelFormat: AVPixelFormat;
44
+ /**
45
+ * Frame rate of the raw video.
46
+ *
47
+ * Specified as a rational number (numerator/denominator).
48
+ */
49
+ frameRate: IRational;
50
+ }
51
+ /**
52
+ * Raw audio data configuration.
53
+ */
54
+ export interface AudioRawData {
55
+ /**
56
+ * Type discriminator for TypeScript.
57
+ *
58
+ * Must be set to 'audio' to identify this as audio raw data.
59
+ */
60
+ type: 'audio';
61
+ /**
62
+ * Raw audio input source.
63
+ *
64
+ * Can be a file path, Buffer containing raw audio data, or custom I/O callbacks.
65
+ */
66
+ input: string | Buffer | IOInputCallbacks;
67
+ /**
68
+ * Sample rate in Hz.
69
+ *
70
+ * Number of audio samples per second (e.g., 44100, 48000).
71
+ */
72
+ sampleRate: number;
73
+ /**
74
+ * Number of audio channels.
75
+ *
76
+ * Typical values: 1 (mono), 2 (stereo), 6 (5.1 surround).
77
+ */
78
+ channels: number;
79
+ /**
80
+ * Sample format of the raw audio data.
81
+ *
82
+ * Specifies how audio samples are stored (e.g., S16, FLT, S32).
83
+ */
84
+ sampleFormat: AVSampleFormat;
85
+ }
86
+ /**
87
+ * Options for Demuxer opening.
88
+ */
89
+ export interface DemuxerOptions {
90
+ /**
91
+ * Buffer size for reading/writing operations.
92
+ *
93
+ * This option allows you to specify the buffer size used for I/O operations.
94
+ *
95
+ * @default 65536
96
+ *
97
+ */
98
+ bufferSize?: number;
99
+ /**
100
+ * Force specific input format.
101
+ *
102
+ * Use this to specify the input format explicitly instead of auto-detection.
103
+ * Useful for raw formats like 'rawvideo', 'rawaudio', etc.
104
+ *
105
+ */
106
+ format?: string;
107
+ /**
108
+ * Skip reading stream information on open.
109
+ *
110
+ * If true, stream info (codecs, formats, etc.) will not be read during opening.
111
+ * This can speed up opening time for certain use cases where stream info is not needed.
112
+ *
113
+ * @default false
114
+ */
115
+ skipStreamInfo?: boolean;
116
+ /**
117
+ * Start reading packets from the first keyframe.
118
+ *
119
+ * When enabled, all packets before the first keyframe will be skipped.
120
+ * Useful for seeking and trimming operations.
121
+ *
122
+ * @default false
123
+ */
124
+ startWithKeyframe?: boolean;
125
+ /**
126
+ * DTS delta threshold in seconds.
127
+ *
128
+ * Timestamp discontinuity detection threshold for formats with AVFMT_TS_DISCONT flag.
129
+ * When DTS delta exceeds this value, it's considered a discontinuity.
130
+ *
131
+ * Matches FFmpeg CLI's -dts_delta_threshold option.
132
+ *
133
+ * @default 10
134
+ */
135
+ dtsDeltaThreshold?: number;
136
+ /**
137
+ * DTS error threshold in seconds.
138
+ *
139
+ * Timestamp discontinuity detection threshold for continuous formats (without AVFMT_TS_DISCONT).
140
+ * When DTS delta exceeds this value, it's considered a timestamp error.
141
+ *
142
+ * Matches FFmpeg CLI's -dts_error_threshold option.
143
+ *
144
+ * @default 108000 (30 hours)
145
+ */
146
+ dtsErrorThreshold?: number;
147
+ /**
148
+ * Copy timestamps from input to output.
149
+ *
150
+ * When enabled, timestamps are passed through without modification.
151
+ * This disables most timestamp discontinuity corrections except for
152
+ * PTS wrap-around detection in discontinuous formats.
153
+ *
154
+ * Matches FFmpeg CLI's -copyts option.
155
+ *
156
+ * @default false
157
+ */
158
+ copyTs?: boolean;
159
+ /**
160
+ * FFmpeg format options passed directly to the input.
161
+ *
162
+ * Key-value pairs of FFmpeg AVFormatContext options.
163
+ * These are passed directly to avformat_open_input().
164
+ */
165
+ options?: Record<string, string | number | boolean | undefined | null>;
166
+ /**
167
+ * AbortSignal for cancellation.
168
+ *
169
+ * When aborted, async generators stop yielding and async methods throw AbortError.
170
+ * The demux thread is stopped automatically.
171
+ */
172
+ signal?: AbortSignal;
173
+ }
174
+ /**
175
+ * RTP Demuxer interface.
176
+ */
177
+ export interface RTPDemuxer {
178
+ /**
179
+ * Demuxer configured for RTP/SRTP reception.
180
+ *
181
+ * Receives RTP packets via localhost UDP and feeds them to FFmpeg for decoding.
182
+ */
183
+ input: Demuxer;
184
+ /**
185
+ * Send RTP packet to FFmpeg for decoding.
186
+ *
187
+ * @param rtpPacket - RTP packet as Buffer
188
+ *
189
+ * @param streamIndex - Optional stream index for multiplexed RTP
190
+ */
191
+ sendPacket: (rtpPacket: Buffer, streamIndex?: number) => void;
192
+ /**
193
+ * Cleanup function.
194
+ *
195
+ * Closes the demuxer and UDP socket asynchronously.
196
+ */
197
+ close: () => Promise<void>;
198
+ /**
199
+ * Synchronous cleanup function.
200
+ *
201
+ * Closes the demuxer and UDP socket synchronously.
202
+ */
203
+ closeSync: () => void;
204
+ }
205
+ /**
206
+ * High-level demuxer for reading and demuxing media files.
207
+ *
208
+ * Provides simplified access to media streams, packets, and metadata.
209
+ * Handles file opening, format detection, and stream information extraction.
210
+ * Supports files, URLs, buffers, and raw data input with automatic cleanup.
211
+ * Essential component for media processing pipelines and transcoding.
212
+ *
213
+ * @example
214
+ * ```typescript
215
+ * import { Demuxer } from 'node-av/api';
216
+ *
217
+ * // Open media file
218
+ * await using input = await Demuxer.open('video.mp4');
219
+ * console.log(`Format: ${input.formatName}`);
220
+ * console.log(`Duration: ${input.duration}s`);
221
+ *
222
+ * // Process packets
223
+ * for await (const packet of input.packets()) {
224
+ * console.log(`Packet from stream ${packet.streamIndex}`);
225
+ * packet.free();
226
+ * }
227
+ * ```
228
+ *
229
+ * @example
230
+ * ```typescript
231
+ * // From buffer
232
+ * const buffer = await fs.readFile('video.mp4');
233
+ * await using input = await Demuxer.open(buffer);
234
+ *
235
+ * // Access streams
236
+ * const videoStream = input.video();
237
+ * const audioStream = input.audio();
238
+ * ```
239
+ *
240
+ * @see {@link Muxer} For writing media files
241
+ * @see {@link Decoder} For decoding packets to frames
242
+ * @see {@link FormatContext} For low-level API
243
+ */
244
+ export declare class Demuxer implements AsyncDisposable, Disposable {
245
+ private formatContext;
246
+ private _streams;
247
+ private ioContext?;
248
+ private isClosed;
249
+ private options;
250
+ private streamStates;
251
+ private tsOffsetDiscont;
252
+ private lastTs;
253
+ private activeGenerators;
254
+ private demuxThread;
255
+ private packetQueues;
256
+ private queueResolvers;
257
+ private demuxThreadActive;
258
+ private demuxEof;
259
+ private signal?;
260
+ private signalCleanup?;
261
+ /**
262
+ * @param formatContext - Opened format context
263
+ *
264
+ * @param options - Media input options
265
+ *
266
+ * @param ioContext - Optional IO context for custom I/O (e.g., from Buffer)
267
+ *
268
+ * @internal
269
+ */
270
+ private constructor();
271
+ /**
272
+ * Probe media format without fully opening the file.
273
+ *
274
+ * Detects format by analyzing file headers and content.
275
+ * Useful for format validation before processing.
276
+ *
277
+ * Direct mapping to av_probe_input_format().
278
+ *
279
+ * @param input - File path or buffer to probe
280
+ *
281
+ * @returns Format information or null if unrecognized
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * const info = await Demuxer.probeFormat('video.mp4');
286
+ * if (info) {
287
+ * console.log(`Format: ${info.format}`);
288
+ * console.log(`Confidence: ${info.confidence}%`);
289
+ * }
290
+ * ```
291
+ *
292
+ * @example
293
+ * ```typescript
294
+ * // Probe from buffer
295
+ * const buffer = await fs.readFile('video.webm');
296
+ * const info = await Demuxer.probeFormat(buffer);
297
+ * console.log(`MIME type: ${info?.mimeType}`);
298
+ * ```
299
+ *
300
+ * @see {@link InputFormat.probe} For low-level probing
301
+ */
302
+ static probeFormat(input: string | Buffer): Promise<{
303
+ format: string;
304
+ longName?: string;
305
+ extensions?: string;
306
+ mimeType?: string;
307
+ confidence: number;
308
+ } | null>;
309
+ /**
310
+ * Probe media format without fully opening the file synchronously.
311
+ * Synchronous version of probeFormat.
312
+ *
313
+ * Detects format by analyzing file headers and content.
314
+ * Useful for format validation before processing.
315
+ *
316
+ * Direct mapping to av_probe_input_format().
317
+ *
318
+ * @param input - File path or buffer to probe
319
+ *
320
+ * @returns Format information or null if unrecognized
321
+ *
322
+ * @example
323
+ * ```typescript
324
+ * const info = Demuxer.probeFormatSync('video.mp4');
325
+ * if (info) {
326
+ * console.log(`Format: ${info.format}`);
327
+ * console.log(`Confidence: ${info.confidence}%`);
328
+ * }
329
+ * ```
330
+ *
331
+ * @example
332
+ * ```typescript
333
+ * // Probe from buffer
334
+ * const buffer = fs.readFileSync('video.webm');
335
+ * const info = Demuxer.probeFormatSync(buffer);
336
+ * console.log(`MIME type: ${info?.mimeType}`);
337
+ * ```
338
+ *
339
+ * @see {@link probeFormat} For async version
340
+ */
341
+ static probeFormatSync(input: string | Buffer): {
342
+ format: string;
343
+ longName?: string;
344
+ extensions?: string;
345
+ mimeType?: string;
346
+ confidence: number;
347
+ } | null;
348
+ /**
349
+ * Open media from file, URL, buffer, raw data, or custom I/O callbacks.
350
+ *
351
+ * Automatically detects format and extracts stream information.
352
+ * Supports various input sources with flexible configuration.
353
+ * Creates demuxer ready for packet extraction.
354
+ *
355
+ * Direct mapping to avformat_open_input() and avformat_find_stream_info().
356
+ *
357
+ * @param input - File path, URL, buffer, raw data descriptor, or custom I/O callbacks
358
+ *
359
+ * @param options - Input configuration options
360
+ *
361
+ * @returns Opened demuxer instance
362
+ *
363
+ * @throws {Error} If format not found or open fails, or format required for custom I/O
364
+ *
365
+ * @throws {FFmpegError} If FFmpeg operations fail
366
+ *
367
+ * @example
368
+ * ```typescript
369
+ * // Open file
370
+ * await using input = await Demuxer.open('video.mp4');
371
+ * ```
372
+ *
373
+ * @example
374
+ * ```typescript
375
+ * // Open URL
376
+ * await using input = await Demuxer.open('http://example.com/stream.m3u8');
377
+ * ```
378
+ *
379
+ * @example
380
+ * ```typescript
381
+ * // Open with options
382
+ * await using input = await Demuxer.open('rtsp://camera.local', {
383
+ * format: 'rtsp',
384
+ * options: {
385
+ * rtsp_transport: 'tcp',
386
+ * analyzeduration: '5000000'
387
+ * }
388
+ * });
389
+ * ```
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * // Open raw video data
394
+ * await using input = await Demuxer.open({
395
+ * type: 'video',
396
+ * input: rawBuffer,
397
+ * width: 1920,
398
+ * height: 1080,
399
+ * pixelFormat: AV_PIX_FMT_YUV420P,
400
+ * frameRate: { num: 30, den: 1 }
401
+ * });
402
+ * ```
403
+ *
404
+ * @example
405
+ * ```typescript
406
+ * // Custom I/O callbacks
407
+ * const callbacks = {
408
+ * read: (size: number) => {
409
+ * // Read data from custom source
410
+ * return buffer; // or null for EOF, or negative error code
411
+ * },
412
+ * seek: (offset: bigint, whence: AVSeekWhence) => {
413
+ * // Seek in custom source
414
+ * return offset; // or negative error code
415
+ * }
416
+ * };
417
+ *
418
+ * await using input = await Demuxer.open(callbacks, {
419
+ * format: 'mp4',
420
+ * bufferSize: 8192
421
+ * });
422
+ * ```
423
+ *
424
+ * @see {@link DemuxerOptions} For configuration options
425
+ * @see {@link RawData} For raw data input
426
+ * @see {@link IOInputCallbacks} For custom I/O interface
427
+ */
428
+ static open(input: string | Buffer, options?: DemuxerOptions): Promise<Demuxer>;
429
+ static open(input: IOInputCallbacks, options: (DemuxerOptions | undefined) & {
430
+ format: string;
431
+ }): Promise<Demuxer>;
432
+ static open(input: IOContext, options: (DemuxerOptions | undefined) & {
433
+ format: string;
434
+ }): Promise<Demuxer>;
435
+ static open(input: Readable, options: (DemuxerOptions | undefined) & {
436
+ format: string;
437
+ }): Promise<Demuxer>;
438
+ static open(rawData: VideoRawData | AudioRawData, options?: DemuxerOptions): Promise<Demuxer>;
439
+ /**
440
+ * Open media from file, URL, Buffer, raw data, or custom I/O callbacks synchronously.
441
+ * Synchronous version of open.
442
+ *
443
+ * Automatically detects format and extracts stream information.
444
+ * Supports various input sources with flexible configuration.
445
+ * Creates demuxer ready for packet extraction.
446
+ *
447
+ * Direct mapping to avformat_open_input() and avformat_find_stream_info().
448
+ *
449
+ * @param input - File path, URL, Buffer, raw data descriptor, or custom I/O callbacks
450
+ *
451
+ * @param options - Input configuration options
452
+ *
453
+ * @returns Opened muxer instance
454
+ *
455
+ * @throws {Error} If format not found or open fails, or format required for custom I/O
456
+ *
457
+ * @throws {FFmpegError} If FFmpeg operations fail
458
+ *
459
+ * @example
460
+ * ```typescript
461
+ * // Open file
462
+ * using input = Demuxer.openSync('video.mp4');
463
+ * ```
464
+ *
465
+ * @example
466
+ * ```typescript
467
+ * // Open from buffer
468
+ * const buffer = await fs.readFile('video.mp4');
469
+ * using input = Demuxer.openSync(buffer);
470
+ * ```
471
+ *
472
+ * @example
473
+ * ```typescript
474
+ * // Open with options
475
+ * using input = Demuxer.openSync('rtsp://camera.local', {
476
+ * format: 'rtsp',
477
+ * options: {
478
+ * rtsp_transport: 'tcp',
479
+ * analyzeduration: '5000000'
480
+ * }
481
+ * });
482
+ * ```
483
+ *
484
+ * @example
485
+ * ```typescript
486
+ * // Custom I/O callbacks
487
+ * const callbacks = {
488
+ * read: (size: number) => {
489
+ * // Read data from custom source
490
+ * return buffer; // or null for EOF, or negative error code
491
+ * },
492
+ * seek: (offset: bigint, whence: AVSeekWhence) => {
493
+ * // Seek in custom source
494
+ * return offset; // or negative error code
495
+ * }
496
+ * };
497
+ *
498
+ * using input = Demuxer.openSync(callbacks, {
499
+ * format: 'mp4',
500
+ * bufferSize: 8192
501
+ * });
502
+ * ```
503
+ *
504
+ * @see {@link open} For async version
505
+ * @see {@link IOInputCallbacks} For custom I/O interface
506
+ */
507
+ static openSync(input: string | Buffer, options?: DemuxerOptions): Demuxer;
508
+ static openSync(input: IOInputCallbacks, options: (DemuxerOptions | undefined) & {
509
+ format: string;
510
+ }): Demuxer;
511
+ static openSync(input: IOContext, options: (DemuxerOptions | undefined) & {
512
+ format: string;
513
+ }): Demuxer;
514
+ static openSync(input: Readable, options: (DemuxerOptions | undefined) & {
515
+ format: string;
516
+ }): Demuxer;
517
+ static openSync(rawData: VideoRawData | AudioRawData, options?: DemuxerOptions): Demuxer;
518
+ /**
519
+ * Open RTP/SRTP input stream via localhost UDP.
520
+ *
521
+ * Creates a Demuxer from SDP string received via UDP socket.
522
+ * Opens UDP socket and configures FFmpeg to receive and parse RTP packets.
523
+ *
524
+ * @param sdpContent - SDP content string describing the RTP stream
525
+ *
526
+ * @throws {Error} If SDP parsing or socket setup fails
527
+ *
528
+ * @throws {FFmpegError} If FFmpeg operations fail
529
+ *
530
+ * @returns Promise with Demuxer, sendPacket function and cleanup
531
+ *
532
+ * @example
533
+ * ```typescript
534
+ * import { Demuxer, StreamingUtils } from 'node-av/api';
535
+ * import { AV_CODEC_ID_OPUS } from 'node-av/constants';
536
+ *
537
+ * // Generate SDP for SRTP encrypted Opus
538
+ * const sdp = StreamingUtils.createRTPInputSDP([{
539
+ * port: 5004,
540
+ * codecId: AV_CODEC_ID_OPUS,
541
+ * payloadType: 111,
542
+ * clockRate: 16000,
543
+ * channels: 1,
544
+ * srtp: { key: srtpKey, salt: srtpSalt }
545
+ * }]);
546
+ *
547
+ * // Open RTP input
548
+ * const { input, sendPacket, close } = await Demuxer.openSDP(sdp);
549
+ *
550
+ * // Route encrypted RTP packets from network
551
+ * socket.on('message', (msg) => sendPacket(msg));
552
+ *
553
+ * // Decode audio
554
+ * const decoder = await Decoder.create(input.audio()!);
555
+ * for await (const packet of input.packets()) {
556
+ * const frame = await decoder.decode(packet);
557
+ * // Process frame...
558
+ * }
559
+ *
560
+ * // Cleanup
561
+ * await close();
562
+ * ```
563
+ *
564
+ * @see {@link StreamingUtils.createInputSDP} to generate SDP content.
565
+ */
566
+ static openSDP(sdpContent: string): Promise<RTPDemuxer>;
567
+ /**
568
+ * Open RTP/SRTP input stream via localhost UDP synchronously.
569
+ * Synchronous version of openSDP.
570
+ *
571
+ * Creates a Demuxer from SDP string received via UDP socket.
572
+ * Opens UDP socket and configures FFmpeg to receive and parse RTP packets.
573
+ *
574
+ * @param sdpContent - SDP content string describing the RTP stream
575
+ *
576
+ * @throws {Error} If SDP parsing or socket setup fails
577
+ *
578
+ * @throws {FFmpegError} If FFmpeg operations fail
579
+ *
580
+ * @returns Object with Demuxer, sendPacket function and cleanup
581
+ *
582
+ * @example
583
+ * ```typescript
584
+ * import { Demuxer, StreamingUtils } from 'node-av/api';
585
+ * import { AV_CODEC_ID_OPUS } from 'node-av/constants';
586
+ *
587
+ * // Generate SDP for SRTP encrypted Opus
588
+ * const sdp = StreamingUtils.createRTPInputSDP([{
589
+ * port: 5004,
590
+ * codecId: AV_CODEC_ID_OPUS,
591
+ * payloadType: 111,
592
+ * clockRate: 16000,
593
+ * channels: 1,
594
+ * srtp: { key: srtpKey, salt: srtpSalt }
595
+ * }]);
596
+ *
597
+ * // Open RTP input
598
+ * const { input, sendPacket, closeSync } = Demuxer.openSDPSync(sdp);
599
+ *
600
+ * // Route encrypted RTP packets from network
601
+ * socket.on('message', (msg) => sendPacket(msg));
602
+ *
603
+ * // Decode audio
604
+ * const decoder = await Decoder.create(input.audio()!);
605
+ * for await (const packet of input.packets()) {
606
+ * const frame = await decoder.decode(packet);
607
+ * // Process frame...
608
+ * }
609
+ *
610
+ * // Cleanup synchronously
611
+ * closeSync();
612
+ * ```
613
+ *
614
+ * @see {@link StreamingUtils.createInputSDP} to generate SDP content.
615
+ * @see {@link openSDP} For async version
616
+ */
617
+ static openSDPSync(sdpContent: string): RTPDemuxer;
618
+ /**
619
+ * Check if input is open.
620
+ *
621
+ * @example
622
+ * ```typescript
623
+ * if (!input.isInputOpen) {
624
+ * console.log('Input is not open');
625
+ * }
626
+ * ```
627
+ */
628
+ get isInputOpen(): boolean;
629
+ /**
630
+ * Get all streams in the media.
631
+ *
632
+ * @example
633
+ * ```typescript
634
+ * for (const stream of input.streams) {
635
+ * console.log(`Stream ${stream.index}: ${stream.codecpar.codecType}`);
636
+ * }
637
+ * ```
638
+ */
639
+ get streams(): Stream[];
640
+ /**
641
+ * Get media duration in seconds.
642
+ *
643
+ * Returns 0 if duration is unknown or not available or input is closed.
644
+ *
645
+ * @example
646
+ * ```typescript
647
+ * console.log(`Duration: ${input.duration} seconds`);
648
+ * ```
649
+ */
650
+ get duration(): number;
651
+ /**
652
+ * Get media start time in seconds.
653
+ *
654
+ * For device inputs (e.g., avfoundation), this reflects the system uptime
655
+ * at capture start. Pass this value to `Muxer.open()` via the `startTime`
656
+ * option to produce correct output timestamps.
657
+ *
658
+ * Returns 0 if start time is unknown or not available or input is closed.
659
+ *
660
+ * @example
661
+ * ```typescript
662
+ * await using input = await Demuxer.open(source);
663
+ * await using output = await Muxer.open('output.mp4', { startTime: input.startTime });
664
+ * ```
665
+ */
666
+ get startTime(): number;
667
+ /**
668
+ * Get media bitrate in kilobits per second.
669
+ *
670
+ * Returns 0 if bitrate is unknown or not available or input is closed.
671
+ *
672
+ * @example
673
+ * ```typescript
674
+ * console.log(`Bitrate: ${input.bitRate} kbps`);
675
+ * ```
676
+ */
677
+ get bitRate(): number;
678
+ /**
679
+ * Get media metadata.
680
+ *
681
+ * Returns all metadata tags as key-value pairs.
682
+ *
683
+ * @example
684
+ * ```typescript
685
+ * const metadata = input.metadata;
686
+ * console.log(`Title: ${metadata.title}`);
687
+ * console.log(`Artist: ${metadata.artist}`);
688
+ * ```
689
+ */
690
+ get metadata(): Record<string, string>;
691
+ /**
692
+ * Get format name.
693
+ *
694
+ * Returns 'unknown' if input is closed or format is not available.
695
+ *
696
+ * @example
697
+ * ```typescript
698
+ * console.log(`Format: ${input.formatName}`); // "mov,mp4,m4a,3gp,3g2,mj2"
699
+ * ```
700
+ */
701
+ get formatName(): string;
702
+ /**
703
+ * Get format long name.
704
+ *
705
+ * Returns 'Unknown Format' if input is closed or format is not available.
706
+ *
707
+ * @example
708
+ * ```typescript
709
+ * console.log(`Format: ${input.formatLongName}`); // "QuickTime / MOV"
710
+ * ```
711
+ */
712
+ get formatLongName(): string;
713
+ /**
714
+ * Get MIME type of the input format.
715
+ *
716
+ * Returns null if input is closed or format is not available.
717
+ *
718
+ * @example
719
+ * ```typescript
720
+ * console.log(`MIME Type: ${input.mimeType}`); // "video/mp4"
721
+ * ```
722
+ */
723
+ get mimeType(): string | null;
724
+ /**
725
+ * Get input stream by index.
726
+ *
727
+ * Returns the stream at the specified index.
728
+ *
729
+ * @param index - Stream index
730
+ *
731
+ * @returns Stream or undefined if index is invalid
732
+ *
733
+ * @example
734
+ * ```typescript
735
+ * const input = await Demuxer.open('input.mp4');
736
+ *
737
+ * // Get the input stream to inspect codec parameters
738
+ * const stream = input.getStream(1); // Get stream at index 1
739
+ * if (stream) {
740
+ * console.log(`Input codec: ${stream.codecpar.codecId}`);
741
+ * }
742
+ * ```
743
+ *
744
+ * @see {@link video} For getting video streams
745
+ * @see {@link audio} For getting audio streams
746
+ */
747
+ getStream(index: number): Stream | undefined;
748
+ /**
749
+ * Get video stream by index.
750
+ *
751
+ * Returns the nth video stream (0-based index).
752
+ * Returns undefined if stream doesn't exist.
753
+ *
754
+ * @param index - Video stream index (default: 0)
755
+ *
756
+ * @returns Video stream or undefined
757
+ *
758
+ * @example
759
+ * ```typescript
760
+ * const videoStream = input.video();
761
+ * if (videoStream) {
762
+ * console.log(`Video: ${videoStream.codecpar.width}x${videoStream.codecpar.height}`);
763
+ * }
764
+ * ```
765
+ *
766
+ * @example
767
+ * ```typescript
768
+ * // Get second video stream
769
+ * const secondVideo = input.video(1);
770
+ * ```
771
+ *
772
+ * @see {@link audio} For audio streams
773
+ * @see {@link findBestStream} For automatic selection
774
+ */
775
+ video(index?: number): Stream | undefined;
776
+ /**
777
+ * Get audio stream by index.
778
+ *
779
+ * Returns the nth audio stream (0-based index).
780
+ * Returns undefined if stream doesn't exist.
781
+ *
782
+ * @param index - Audio stream index (default: 0)
783
+ *
784
+ * @returns Audio stream or undefined
785
+ *
786
+ * @example
787
+ * ```typescript
788
+ * const audioStream = input.audio();
789
+ * if (audioStream) {
790
+ * console.log(`Audio: ${audioStream.codecpar.sampleRate}Hz`);
791
+ * }
792
+ * ```
793
+ *
794
+ * @example
795
+ * ```typescript
796
+ * // Get second audio stream
797
+ * const secondAudio = input.audio(1);
798
+ * ```
799
+ *
800
+ * @see {@link video} For video streams
801
+ * @see {@link findBestStream} For automatic selection
802
+ */
803
+ audio(index?: number): Stream | undefined;
804
+ /**
805
+ * Get input format details.
806
+ *
807
+ * Returns null if input is closed or format is not available.
808
+ *
809
+ * @returns Input format or null
810
+ *
811
+ * @example
812
+ * ```typescript
813
+ * const inputFormat = input.inputFormat;
814
+ * if (inputFormat) {
815
+ * console.log(`Input Format: ${inputFormat.name}`);
816
+ * }
817
+ * ```
818
+ */
819
+ inputFormat(): InputFormat | null;
820
+ /**
821
+ * Find the best stream of a given type.
822
+ *
823
+ * Uses FFmpeg's stream selection algorithm.
824
+ * Considers codec support, default flags, and quality.
825
+ *
826
+ * Direct mapping to av_find_best_stream().
827
+ *
828
+ * @param type - Media type to find
829
+ *
830
+ * @returns Best stream or undefined if not found or input is closed
831
+ *
832
+ * @example
833
+ * ```typescript
834
+ * import { AVMEDIA_TYPE_VIDEO } from 'node-av/constants';
835
+ *
836
+ * const bestVideo = input.findBestStream(AVMEDIA_TYPE_VIDEO);
837
+ * if (bestVideo) {
838
+ * const decoder = await Decoder.create(bestVideo);
839
+ * }
840
+ * ```
841
+ *
842
+ * @see {@link video} For direct video stream access
843
+ * @see {@link audio} For direct audio stream access
844
+ */
845
+ findBestStream(type: AVMediaType): Stream | undefined;
846
+ /**
847
+ * Read packets from media as async generator.
848
+ *
849
+ * Yields demuxed packets for processing.
850
+ * Automatically handles packet memory management.
851
+ * Optionally filters packets by stream index.
852
+ *
853
+ * **Supports parallel generators**: Multiple `packets()` iterators can run concurrently.
854
+ * When multiple generators are active, an internal demux thread automatically handles
855
+ * packet distribution to avoid race conditions.
856
+ *
857
+ * Direct mapping to av_read_frame().
858
+ *
859
+ * @param index - Optional stream index to filter
860
+ *
861
+ * @yields {Packet} Demuxed packets (must be freed by caller)
862
+ *
863
+ * @throws {Error} If packet cloning fails
864
+ *
865
+ * @example
866
+ * ```typescript
867
+ * // Read all packets
868
+ * for await (const packet of input.packets()) {
869
+ * console.log(`Packet: stream=${packet.streamIndex}, pts=${packet.pts}`);
870
+ * packet.free();
871
+ * }
872
+ * ```
873
+ *
874
+ * @example
875
+ * ```typescript
876
+ * // Read only video packets
877
+ * const videoStream = input.video();
878
+ * for await (const packet of input.packets(videoStream.index)) {
879
+ * // Process video packet
880
+ * packet.free();
881
+ * }
882
+ * ```
883
+ *
884
+ * @example
885
+ * ```typescript
886
+ * // Parallel processing of video and audio streams
887
+ * const videoGen = input.packets(videoStream.index);
888
+ * const audioGen = input.packets(audioStream.index);
889
+ *
890
+ * await Promise.all([
891
+ * (async () => {
892
+ * for await (const packet of videoGen) {
893
+ * // Process video
894
+ * packet.free();
895
+ * }
896
+ * })(),
897
+ * (async () => {
898
+ * for await (const packet of audioGen) {
899
+ * // Process audio
900
+ * packet.free();
901
+ * }
902
+ * })()
903
+ * ]);
904
+ * ```
905
+ *
906
+ * @see {@link Decoder.frames} For decoding packets
907
+ */
908
+ packets(index?: number): AsyncGenerator<Packet | null>;
909
+ /**
910
+ * Read packets from media as generator synchronously.
911
+ * Synchronous version of packets.
912
+ *
913
+ * Yields demuxed packets for processing.
914
+ * Automatically handles packet memory management.
915
+ * Optionally filters packets by stream index.
916
+ *
917
+ * Direct mapping to av_read_frame().
918
+ *
919
+ * @param index - Optional stream index to filter
920
+ *
921
+ * @yields {Packet} Demuxed packets (must be freed by caller)
922
+ *
923
+ * @throws {Error} If packet cloning fails
924
+ *
925
+ * @example
926
+ * ```typescript
927
+ * // Read all packets
928
+ * for (const packet of input.packetsSync()) {
929
+ * console.log(`Packet: stream=${packet.streamIndex}, pts=${packet.pts}`);
930
+ * packet.free();
931
+ * }
932
+ * ```
933
+ *
934
+ * @example
935
+ * ```typescript
936
+ * // Read only video packets
937
+ * const videoStream = input.video();
938
+ * for (const packet of input.packetsSync(videoStream.index)) {
939
+ * // Process video packet
940
+ * packet.free();
941
+ * }
942
+ * ```
943
+ *
944
+ * @see {@link packets} For async version
945
+ */
946
+ packetsSync(index?: number): Generator<Packet | null>;
947
+ /**
948
+ * Seek to timestamp in media.
949
+ *
950
+ * Seeks to the specified position in seconds.
951
+ * Can seek in specific stream or globally.
952
+ *
953
+ * Direct mapping to av_seek_frame().
954
+ *
955
+ * @param timestamp - Target position in seconds
956
+ *
957
+ * @param streamIndex - Stream index or -1 for global (default: -1)
958
+ *
959
+ * @param flags - Seek flags (default: AVFLAG_NONE)
960
+ *
961
+ * @returns 0 on success, negative on error
962
+ *
963
+ * @throws {Error} If input is closed
964
+ *
965
+ * @example
966
+ * ```typescript
967
+ * // Seek to 30 seconds
968
+ * const ret = await input.seek(30);
969
+ * FFmpegError.throwIfError(ret, 'seek failed');
970
+ * ```
971
+ *
972
+ * @example
973
+ * ```typescript
974
+ * import { AVSEEK_FLAG_BACKWARD } from 'node-av/constants';
975
+ *
976
+ * // Seek to keyframe before 60 seconds
977
+ * await input.seek(60, -1, AVSEEK_FLAG_BACKWARD);
978
+ * ```
979
+ *
980
+ * @see {@link AVSeekFlag} For seek flags
981
+ */
982
+ seek(timestamp: number, streamIndex?: number, flags?: AVSeekFlag): Promise<number>;
983
+ /**
984
+ * Seek to timestamp in media synchronously.
985
+ * Synchronous version of seek.
986
+ *
987
+ * Seeks to the specified position in seconds.
988
+ * Can seek in specific stream or globally.
989
+ *
990
+ * Direct mapping to av_seek_frame().
991
+ *
992
+ * @param timestamp - Target position in seconds
993
+ *
994
+ * @param streamIndex - Stream index or -1 for global (default: -1)
995
+ *
996
+ * @param flags - Seek flags (default: AVFLAG_NONE)
997
+ *
998
+ * @returns 0 on success, negative on error
999
+ *
1000
+ * @throws {Error} If input is closed
1001
+ *
1002
+ * @example
1003
+ * ```typescript
1004
+ * // Seek to 30 seconds
1005
+ * const ret = input.seekSync(30);
1006
+ * FFmpegError.throwIfError(ret, 'seek failed');
1007
+ * ```
1008
+ *
1009
+ * @example
1010
+ * ```typescript
1011
+ * import { AVSEEK_FLAG_BACKWARD } from 'node-av/constants';
1012
+ *
1013
+ * // Seek to keyframe before 60 seconds
1014
+ * input.seekSync(60, -1, AVSEEK_FLAG_BACKWARD);
1015
+ * ```
1016
+ *
1017
+ * @see {@link seek} For async version
1018
+ */
1019
+ seekSync(timestamp: number, streamIndex?: number, flags?: AVSeekFlag): number;
1020
+ /**
1021
+ * Start the internal demux thread for handling multiple parallel packet generators.
1022
+ * This thread reads packets from the format context and distributes them to queues.
1023
+ *
1024
+ * @internal
1025
+ */
1026
+ private startDemuxThread;
1027
+ /**
1028
+ * Stop the internal demux thread.
1029
+ *
1030
+ * @internal
1031
+ */
1032
+ private stopDemuxThread;
1033
+ /**
1034
+ * Get or create stream state for timestamp processing.
1035
+ *
1036
+ * @param streamIndex - Stream index
1037
+ *
1038
+ * @returns Stream state
1039
+ *
1040
+ * @internal
1041
+ */
1042
+ private getStreamState;
1043
+ /**
1044
+ * PTS Wrap-Around Correction.
1045
+ *
1046
+ * Based on FFmpeg's ts_fixup().
1047
+ *
1048
+ * Corrects timestamp wrap-around for streams with limited timestamp bits.
1049
+ * DVB streams typically use 31-bit timestamps that wrap around.
1050
+ * Without correction, timestamps become negative causing playback errors.
1051
+ *
1052
+ * Handles:
1053
+ * - Detects wrap-around based on pts_wrap_bits from stream
1054
+ * - Applies correction once per stream
1055
+ * - Corrects both PTS and DTS
1056
+ *
1057
+ * @param packet - Packet to correct
1058
+ *
1059
+ * @param stream - Stream metadata
1060
+ *
1061
+ * @internal
1062
+ */
1063
+ private ptsWrapAroundCorrection;
1064
+ /**
1065
+ * DTS Prediction and Update.
1066
+ *
1067
+ * Based on FFmpeg's ist_dts_update().
1068
+ *
1069
+ * Predicts next expected DTS for frame ordering validation and discontinuity detection.
1070
+ * Uses codec-specific logic:
1071
+ * - Audio: Based on sample_rate and frame_size
1072
+ * - Video: Based on framerate or duration
1073
+ *
1074
+ * Handles:
1075
+ * - First timestamp initialization
1076
+ * - Codec-specific duration calculation
1077
+ * - DTS sequence tracking
1078
+ *
1079
+ * @param packet - Packet to process
1080
+ *
1081
+ * @param stream - Stream metadata
1082
+ *
1083
+ * @internal
1084
+ */
1085
+ private dtsPredict;
1086
+ /**
1087
+ * Timestamp Discontinuity Detection.
1088
+ *
1089
+ * Based on FFmpeg's ts_discontinuity_detect().
1090
+ *
1091
+ * Detects and corrects timestamp discontinuities in streams.
1092
+ * Handles two cases:
1093
+ * - Discontinuous formats (MPEG-TS): Apply offset correction
1094
+ * - Continuous formats (MP4): Mark timestamps as invalid
1095
+ *
1096
+ * Handles:
1097
+ * - Format-specific discontinuity handling (AVFMT_TS_DISCONT flag)
1098
+ * - PTS wrap-around detection for streams with limited timestamp bits
1099
+ * - Intra-stream discontinuity detection
1100
+ * - Inter-stream discontinuity detection
1101
+ * - Offset accumulation and application
1102
+ * - copyTs mode with selective correction
1103
+ *
1104
+ * @param packet - Packet to check for discontinuities
1105
+ *
1106
+ * @param stream - Stream metadata
1107
+ *
1108
+ * @internal
1109
+ */
1110
+ private timestampDiscontinuityDetect;
1111
+ /**
1112
+ * Timestamp Discontinuity Processing - main entry point.
1113
+ *
1114
+ * Based on FFmpeg's ts_discontinuity_process().
1115
+ *
1116
+ * Applies accumulated discontinuity offset and detects new discontinuities.
1117
+ * Must be called for every packet before other timestamp processing.
1118
+ *
1119
+ * Handles:
1120
+ * - Applying previously-detected offset to all streams
1121
+ * - Detecting new discontinuities for audio/video streams
1122
+ *
1123
+ * @param packet - Packet to process
1124
+ *
1125
+ * @param stream - Stream metadata
1126
+ *
1127
+ * @internal
1128
+ */
1129
+ private timestampDiscontinuityProcess;
1130
+ /**
1131
+ * Close demuxer and free resources.
1132
+ *
1133
+ * Releases format context and I/O context.
1134
+ * Safe to call multiple times.
1135
+ * Automatically called by Symbol.asyncDispose.
1136
+ *
1137
+ * Direct mapping to avformat_close_input().
1138
+ *
1139
+ * @example
1140
+ * ```typescript
1141
+ * const input = await Demuxer.open('video.mp4');
1142
+ * try {
1143
+ * // Use input
1144
+ * } finally {
1145
+ * await input.close();
1146
+ * }
1147
+ * ```
1148
+ *
1149
+ * @see {@link Symbol.asyncDispose} For automatic cleanup
1150
+ */
1151
+ close(): Promise<void>;
1152
+ /**
1153
+ * Close demuxer and free resources synchronously.
1154
+ * Synchronous version of close.
1155
+ *
1156
+ * Releases format context and I/O context.
1157
+ * Safe to call multiple times.
1158
+ * Automatically called by Symbol.dispose.
1159
+ *
1160
+ * Direct mapping to avformat_close_input().
1161
+ *
1162
+ * @example
1163
+ * ```typescript
1164
+ * const input = Demuxer.openSync('video.mp4');
1165
+ * try {
1166
+ * // Use input
1167
+ * } finally {
1168
+ * input.closeSync();
1169
+ * }
1170
+ * ```
1171
+ *
1172
+ * @see {@link close} For async version
1173
+ */
1174
+ closeSync(): void;
1175
+ /**
1176
+ * Get underlying format context.
1177
+ *
1178
+ * Returns the internal format context for advanced operations.
1179
+ *
1180
+ * @returns Format context
1181
+ *
1182
+ * @internal
1183
+ */
1184
+ getFormatContext(): FormatContext;
1185
+ /**
1186
+ * Dispose of demuxer.
1187
+ *
1188
+ * Implements AsyncDisposable interface for automatic cleanup.
1189
+ * Equivalent to calling close().
1190
+ *
1191
+ * @example
1192
+ * ```typescript
1193
+ * {
1194
+ * await using input = await Demuxer.open('video.mp4');
1195
+ * // Process media...
1196
+ * } // Automatically closed
1197
+ * ```
1198
+ *
1199
+ * @see {@link close} For manual cleanup
1200
+ */
1201
+ [Symbol.asyncDispose](): Promise<void>;
1202
+ /**
1203
+ * Dispose of demuxer synchronously.
1204
+ *
1205
+ * Implements Disposable interface for automatic cleanup.
1206
+ * Equivalent to calling closeSync().
1207
+ *
1208
+ * @example
1209
+ * ```typescript
1210
+ * {
1211
+ * using input = Demuxer.openSync('video.mp4');
1212
+ * // Process media...
1213
+ * } // Automatically closed
1214
+ * ```
1215
+ *
1216
+ * @see {@link closeSync} For manual cleanup
1217
+ */
1218
+ [Symbol.dispose](): void;
1219
+ }