node-av-light 0.0.0-stage → 7.1.0-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 (311) hide show
  1. package/LICENSE.md +22 -0
  2. package/README.md +710 -2
  3. package/dist/api/audio-frame-buffer.d.ts +636 -0
  4. package/dist/api/audio-frame-buffer.js +1027 -0
  5. package/dist/api/audio-frame-buffer.js.map +1 -0
  6. package/dist/api/bitstream-filter.d.ts +938 -0
  7. package/dist/api/bitstream-filter.js +1427 -0
  8. package/dist/api/bitstream-filter.js.map +1 -0
  9. package/dist/api/constants.d.ts +44 -0
  10. package/dist/api/constants.js +45 -0
  11. package/dist/api/constants.js.map +1 -0
  12. package/dist/api/data/test_av1.ivf +0 -0
  13. package/dist/api/data/test_h264.h264 +0 -0
  14. package/dist/api/data/test_hevc.h265 +0 -0
  15. package/dist/api/data/test_mjpeg.mjpeg +0 -0
  16. package/dist/api/data/test_vp8.ivf +0 -0
  17. package/dist/api/data/test_vp9.ivf +0 -0
  18. package/dist/api/decoder.d.ts +1413 -0
  19. package/dist/api/decoder.js +2367 -0
  20. package/dist/api/decoder.js.map +1 -0
  21. package/dist/api/demuxer.d.ts +1295 -0
  22. package/dist/api/demuxer.js +2344 -0
  23. package/dist/api/demuxer.js.map +1 -0
  24. package/dist/api/device.d.ts +589 -0
  25. package/dist/api/device.js +964 -0
  26. package/dist/api/device.js.map +1 -0
  27. package/dist/api/encoder-pool.d.ts +262 -0
  28. package/dist/api/encoder-pool.js +397 -0
  29. package/dist/api/encoder-pool.js.map +1 -0
  30. package/dist/api/encoder.d.ts +1509 -0
  31. package/dist/api/encoder.js +2619 -0
  32. package/dist/api/encoder.js.map +1 -0
  33. package/dist/api/filter-complex.d.ts +828 -0
  34. package/dist/api/filter-complex.js +1661 -0
  35. package/dist/api/filter-complex.js.map +1 -0
  36. package/dist/api/filter-presets.d.ts +800 -0
  37. package/dist/api/filter-presets.js +1554 -0
  38. package/dist/api/filter-presets.js.map +1 -0
  39. package/dist/api/filter.d.ts +1339 -0
  40. package/dist/api/filter.js +2075 -0
  41. package/dist/api/filter.js.map +1 -0
  42. package/dist/api/fmp4-stream.d.ts +797 -0
  43. package/dist/api/fmp4-stream.js +1428 -0
  44. package/dist/api/fmp4-stream.js.map +1 -0
  45. package/dist/api/hardware.d.ts +677 -0
  46. package/dist/api/hardware.js +1300 -0
  47. package/dist/api/hardware.js.map +1 -0
  48. package/dist/api/index.d.ts +21 -0
  49. package/dist/api/index.js +38 -0
  50. package/dist/api/index.js.map +1 -0
  51. package/dist/api/io-stream.d.ts +308 -0
  52. package/dist/api/io-stream.js +358 -0
  53. package/dist/api/io-stream.js.map +1 -0
  54. package/dist/api/muxer.d.ts +1311 -0
  55. package/dist/api/muxer.js +2672 -0
  56. package/dist/api/muxer.js.map +1 -0
  57. package/dist/api/pipeline.d.ts +801 -0
  58. package/dist/api/pipeline.js +1344 -0
  59. package/dist/api/pipeline.js.map +1 -0
  60. package/dist/api/probe.d.ts +128 -0
  61. package/dist/api/probe.js +227 -0
  62. package/dist/api/probe.js.map +1 -0
  63. package/dist/api/rtp-stream.d.ts +497 -0
  64. package/dist/api/rtp-stream.js +1131 -0
  65. package/dist/api/rtp-stream.js.map +1 -0
  66. package/dist/api/scaler.d.ts +561 -0
  67. package/dist/api/scaler.js +918 -0
  68. package/dist/api/scaler.js.map +1 -0
  69. package/dist/api/types.d.ts +17 -0
  70. package/dist/api/types.js +2 -0
  71. package/dist/api/types.js.map +1 -0
  72. package/dist/api/utilities/async-queue.d.ts +149 -0
  73. package/dist/api/utilities/async-queue.js +254 -0
  74. package/dist/api/utilities/async-queue.js.map +1 -0
  75. package/dist/api/utilities/audio-sample.d.ts +117 -0
  76. package/dist/api/utilities/audio-sample.js +112 -0
  77. package/dist/api/utilities/audio-sample.js.map +1 -0
  78. package/dist/api/utilities/audio-transcode.d.ts +20 -0
  79. package/dist/api/utilities/audio-transcode.js +27 -0
  80. package/dist/api/utilities/audio-transcode.js.map +1 -0
  81. package/dist/api/utilities/channel-layout.d.ts +76 -0
  82. package/dist/api/utilities/channel-layout.js +80 -0
  83. package/dist/api/utilities/channel-layout.js.map +1 -0
  84. package/dist/api/utilities/codec-format.d.ts +87 -0
  85. package/dist/api/utilities/codec-format.js +117 -0
  86. package/dist/api/utilities/codec-format.js.map +1 -0
  87. package/dist/api/utilities/context-options.d.ts +25 -0
  88. package/dist/api/utilities/context-options.js +23 -0
  89. package/dist/api/utilities/context-options.js.map +1 -0
  90. package/dist/api/utilities/electron-shared-texture.d.ts +368 -0
  91. package/dist/api/utilities/electron-shared-texture.js +540 -0
  92. package/dist/api/utilities/electron-shared-texture.js.map +1 -0
  93. package/dist/api/utilities/image.d.ts +207 -0
  94. package/dist/api/utilities/image.js +213 -0
  95. package/dist/api/utilities/image.js.map +1 -0
  96. package/dist/api/utilities/index.d.ts +14 -0
  97. package/dist/api/utilities/index.js +27 -0
  98. package/dist/api/utilities/index.js.map +1 -0
  99. package/dist/api/utilities/live-decoding.d.ts +15 -0
  100. package/dist/api/utilities/live-decoding.js +32 -0
  101. package/dist/api/utilities/live-decoding.js.map +1 -0
  102. package/dist/api/utilities/media-type.d.ts +49 -0
  103. package/dist/api/utilities/media-type.js +53 -0
  104. package/dist/api/utilities/media-type.js.map +1 -0
  105. package/dist/api/utilities/packet-age-watchdog.d.ts +198 -0
  106. package/dist/api/utilities/packet-age-watchdog.js +594 -0
  107. package/dist/api/utilities/packet-age-watchdog.js.map +1 -0
  108. package/dist/api/utilities/pixel-format.d.ts +89 -0
  109. package/dist/api/utilities/pixel-format.js +97 -0
  110. package/dist/api/utilities/pixel-format.js.map +1 -0
  111. package/dist/api/utilities/sample-format.d.ts +129 -0
  112. package/dist/api/utilities/sample-format.js +141 -0
  113. package/dist/api/utilities/sample-format.js.map +1 -0
  114. package/dist/api/utilities/scale-size.d.ts +51 -0
  115. package/dist/api/utilities/scale-size.js +55 -0
  116. package/dist/api/utilities/scale-size.js.map +1 -0
  117. package/dist/api/utilities/scheduler.d.ts +138 -0
  118. package/dist/api/utilities/scheduler.js +98 -0
  119. package/dist/api/utilities/scheduler.js.map +1 -0
  120. package/dist/api/utilities/streaming.d.ts +186 -0
  121. package/dist/api/utilities/streaming.js +309 -0
  122. package/dist/api/utilities/streaming.js.map +1 -0
  123. package/dist/api/utilities/timestamp.d.ts +193 -0
  124. package/dist/api/utilities/timestamp.js +206 -0
  125. package/dist/api/utilities/timestamp.js.map +1 -0
  126. package/dist/api/utilities/video-transcode.d.ts +218 -0
  127. package/dist/api/utilities/video-transcode.js +624 -0
  128. package/dist/api/utilities/video-transcode.js.map +1 -0
  129. package/dist/api/utilities/whisper-model.d.ts +330 -0
  130. package/dist/api/utilities/whisper-model.js +587 -0
  131. package/dist/api/utilities/whisper-model.js.map +1 -0
  132. package/dist/api/utils.d.ts +19 -0
  133. package/dist/api/utils.js +39 -0
  134. package/dist/api/utils.js.map +1 -0
  135. package/dist/api/webrtc-stream.d.ts +294 -0
  136. package/dist/api/webrtc-stream.js +546 -0
  137. package/dist/api/webrtc-stream.js.map +1 -0
  138. package/dist/api/whisper.d.ts +326 -0
  139. package/dist/api/whisper.js +402 -0
  140. package/dist/api/whisper.js.map +1 -0
  141. package/dist/constants/bsf-options.d.ts +364 -0
  142. package/dist/constants/bsf-options.js +7 -0
  143. package/dist/constants/bsf-options.js.map +1 -0
  144. package/dist/constants/channel-layouts.d.ts +53 -0
  145. package/dist/constants/channel-layouts.js +57 -0
  146. package/dist/constants/channel-layouts.js.map +1 -0
  147. package/dist/constants/constants.d.ts +2435 -0
  148. package/dist/constants/constants.js +1989 -0
  149. package/dist/constants/constants.js.map +1 -0
  150. package/dist/constants/decoders.d.ts +651 -0
  151. package/dist/constants/decoders.js +641 -0
  152. package/dist/constants/decoders.js.map +1 -0
  153. package/dist/constants/encoders.d.ts +314 -0
  154. package/dist/constants/encoders.js +309 -0
  155. package/dist/constants/encoders.js.map +1 -0
  156. package/dist/constants/filter-options.d.ts +12099 -0
  157. package/dist/constants/filter-options.js +7 -0
  158. package/dist/constants/filter-options.js.map +1 -0
  159. package/dist/constants/format-options.d.ts +4319 -0
  160. package/dist/constants/format-options.js +7 -0
  161. package/dist/constants/format-options.js.map +1 -0
  162. package/dist/constants/formats.d.ts +18 -0
  163. package/dist/constants/formats.js +7 -0
  164. package/dist/constants/formats.js.map +1 -0
  165. package/dist/constants/hardware.d.ts +26 -0
  166. package/dist/constants/hardware.js +27 -0
  167. package/dist/constants/hardware.js.map +1 -0
  168. package/dist/constants/index.d.ts +10 -0
  169. package/dist/constants/index.js +6 -0
  170. package/dist/constants/index.js.map +1 -0
  171. package/dist/constants/options.d.ts +6217 -0
  172. package/dist/constants/options.js +7 -0
  173. package/dist/constants/options.js.map +1 -0
  174. package/dist/ffmpeg/index.d.ts +101 -0
  175. package/dist/ffmpeg/index.js +161 -0
  176. package/dist/ffmpeg/index.js.map +1 -0
  177. package/dist/ffmpeg/version.d.ts +6 -0
  178. package/dist/ffmpeg/version.js +7 -0
  179. package/dist/ffmpeg/version.js.map +1 -0
  180. package/dist/index.d.ts +4 -0
  181. package/dist/index.js +9 -0
  182. package/dist/index.js.map +1 -0
  183. package/dist/lib/audio-fifo.d.ts +399 -0
  184. package/dist/lib/audio-fifo.js +431 -0
  185. package/dist/lib/audio-fifo.js.map +1 -0
  186. package/dist/lib/binding.d.ts +242 -0
  187. package/dist/lib/binding.js +102 -0
  188. package/dist/lib/binding.js.map +1 -0
  189. package/dist/lib/bitstream-filter-context.d.ts +381 -0
  190. package/dist/lib/bitstream-filter-context.js +443 -0
  191. package/dist/lib/bitstream-filter-context.js.map +1 -0
  192. package/dist/lib/bitstream-filter.d.ts +140 -0
  193. package/dist/lib/bitstream-filter.js +154 -0
  194. package/dist/lib/bitstream-filter.js.map +1 -0
  195. package/dist/lib/codec-context.d.ts +1069 -0
  196. package/dist/lib/codec-context.js +1336 -0
  197. package/dist/lib/codec-context.js.map +1 -0
  198. package/dist/lib/codec-parameters.d.ts +664 -0
  199. package/dist/lib/codec-parameters.js +813 -0
  200. package/dist/lib/codec-parameters.js.map +1 -0
  201. package/dist/lib/codec-parser.d.ts +201 -0
  202. package/dist/lib/codec-parser.js +213 -0
  203. package/dist/lib/codec-parser.js.map +1 -0
  204. package/dist/lib/codec.d.ts +617 -0
  205. package/dist/lib/codec.js +746 -0
  206. package/dist/lib/codec.js.map +1 -0
  207. package/dist/lib/device.d.ts +294 -0
  208. package/dist/lib/device.js +326 -0
  209. package/dist/lib/device.js.map +1 -0
  210. package/dist/lib/dictionary.d.ts +333 -0
  211. package/dist/lib/dictionary.js +372 -0
  212. package/dist/lib/dictionary.js.map +1 -0
  213. package/dist/lib/error.d.ts +311 -0
  214. package/dist/lib/error.js +395 -0
  215. package/dist/lib/error.js.map +1 -0
  216. package/dist/lib/fifo.d.ts +416 -0
  217. package/dist/lib/fifo.js +453 -0
  218. package/dist/lib/fifo.js.map +1 -0
  219. package/dist/lib/filter-context.d.ts +714 -0
  220. package/dist/lib/filter-context.js +783 -0
  221. package/dist/lib/filter-context.js.map +1 -0
  222. package/dist/lib/filter-graph-segment.d.ts +161 -0
  223. package/dist/lib/filter-graph-segment.js +172 -0
  224. package/dist/lib/filter-graph-segment.js.map +1 -0
  225. package/dist/lib/filter-graph.d.ts +641 -0
  226. package/dist/lib/filter-graph.js +704 -0
  227. package/dist/lib/filter-graph.js.map +1 -0
  228. package/dist/lib/filter-inout.d.ts +202 -0
  229. package/dist/lib/filter-inout.js +261 -0
  230. package/dist/lib/filter-inout.js.map +1 -0
  231. package/dist/lib/filter.d.ts +243 -0
  232. package/dist/lib/filter.js +272 -0
  233. package/dist/lib/filter.js.map +1 -0
  234. package/dist/lib/format-context.d.ts +1335 -0
  235. package/dist/lib/format-context.js +1455 -0
  236. package/dist/lib/format-context.js.map +1 -0
  237. package/dist/lib/frame-utils.d.ts +116 -0
  238. package/dist/lib/frame-utils.js +98 -0
  239. package/dist/lib/frame-utils.js.map +1 -0
  240. package/dist/lib/frame.d.ts +1315 -0
  241. package/dist/lib/frame.js +1535 -0
  242. package/dist/lib/frame.js.map +1 -0
  243. package/dist/lib/hardware-device-context.d.ts +362 -0
  244. package/dist/lib/hardware-device-context.js +383 -0
  245. package/dist/lib/hardware-device-context.js.map +1 -0
  246. package/dist/lib/hardware-frames-context.d.ts +418 -0
  247. package/dist/lib/hardware-frames-context.js +471 -0
  248. package/dist/lib/hardware-frames-context.js.map +1 -0
  249. package/dist/lib/index.d.ts +35 -0
  250. package/dist/lib/index.js +60 -0
  251. package/dist/lib/index.js.map +1 -0
  252. package/dist/lib/input-format.d.ts +249 -0
  253. package/dist/lib/input-format.js +306 -0
  254. package/dist/lib/input-format.js.map +1 -0
  255. package/dist/lib/io-context.d.ts +698 -0
  256. package/dist/lib/io-context.js +771 -0
  257. package/dist/lib/io-context.js.map +1 -0
  258. package/dist/lib/log.d.ts +174 -0
  259. package/dist/lib/log.js +184 -0
  260. package/dist/lib/log.js.map +1 -0
  261. package/dist/lib/native-types.d.ts +1024 -0
  262. package/dist/lib/native-types.js +2 -0
  263. package/dist/lib/native-types.js.map +1 -0
  264. package/dist/lib/option.d.ts +953 -0
  265. package/dist/lib/option.js +1607 -0
  266. package/dist/lib/option.js.map +1 -0
  267. package/dist/lib/output-format.d.ts +222 -0
  268. package/dist/lib/output-format.js +259 -0
  269. package/dist/lib/output-format.js.map +1 -0
  270. package/dist/lib/packet.d.ts +521 -0
  271. package/dist/lib/packet.js +613 -0
  272. package/dist/lib/packet.js.map +1 -0
  273. package/dist/lib/rational.d.ts +251 -0
  274. package/dist/lib/rational.js +278 -0
  275. package/dist/lib/rational.js.map +1 -0
  276. package/dist/lib/software-resample-context.d.ts +552 -0
  277. package/dist/lib/software-resample-context.js +592 -0
  278. package/dist/lib/software-resample-context.js.map +1 -0
  279. package/dist/lib/software-scale-context.d.ts +344 -0
  280. package/dist/lib/software-scale-context.js +366 -0
  281. package/dist/lib/software-scale-context.js.map +1 -0
  282. package/dist/lib/stream.d.ts +383 -0
  283. package/dist/lib/stream.js +524 -0
  284. package/dist/lib/stream.js.map +1 -0
  285. package/dist/lib/sync-queue.d.ts +179 -0
  286. package/dist/lib/sync-queue.js +197 -0
  287. package/dist/lib/sync-queue.js.map +1 -0
  288. package/dist/lib/types.d.ts +34 -0
  289. package/dist/lib/types.js +2 -0
  290. package/dist/lib/types.js.map +1 -0
  291. package/dist/lib/utilities.d.ts +1198 -0
  292. package/dist/lib/utilities.js +1302 -0
  293. package/dist/lib/utilities.js.map +1 -0
  294. package/dist/utils/electron.d.ts +49 -0
  295. package/dist/utils/electron.js +63 -0
  296. package/dist/utils/electron.js.map +1 -0
  297. package/dist/utils/index.d.ts +6 -0
  298. package/dist/utils/index.js +7 -0
  299. package/dist/utils/index.js.map +1 -0
  300. package/dist/utils/libc.d.ts +11 -0
  301. package/dist/utils/libc.js +35 -0
  302. package/dist/utils/libc.js.map +1 -0
  303. package/dist/utils/variant.d.ts +26 -0
  304. package/dist/utils/variant.js +31 -0
  305. package/dist/utils/variant.js.map +1 -0
  306. package/dist/webrtc/index.d.ts +4 -0
  307. package/dist/webrtc/index.js +7 -0
  308. package/dist/webrtc/index.js.map +1 -0
  309. package/install/check.js +124 -0
  310. package/install/ffmpeg.js +66 -0
  311. package/package.json +167 -4
@@ -0,0 +1,1311 @@
1
+ import { Writable } from 'node:stream';
2
+ import { FormatContext } from '../lib/format-context.js';
3
+ import { Packet } from '../lib/packet.js';
4
+ import { Encoder } from './encoder.js';
5
+ import type { MuxerFormat, MuxerOptionsFor } from '../constants/index.js';
6
+ import type { OutputFormat, Stream } from '../lib/index.js';
7
+ import type { BitStreamFilterAPI } from './bitstream-filter.js';
8
+ import type { Demuxer, RTPDemuxer } from './demuxer.js';
9
+ import type { IOOutputCallbacks } from './io-stream.js';
10
+ import type { ContextOptions } from './utilities/context-options.js';
11
+ /**
12
+ * Observer for the packets a Muxer accepts for writing.
13
+ *
14
+ * @internal
15
+ */
16
+ export interface MuxerPacketObserver {
17
+ /** A packet with payload was accepted; throwing fails the write like a muxing error. */
18
+ onPacket(streamIndex: number): void;
19
+ /**
20
+ * An accepted packet of this stream will not reach the output (dropped, or rejected by libavformat).
21
+ * A libavformat error for an earlier, buffered packet is reported against the packet submitted with it.
22
+ */
23
+ onPacketRejected(streamIndex: number): void;
24
+ }
25
+ /**
26
+ * Options for Muxer creation.
27
+ */
28
+ export interface MuxerOptions<F extends MuxerFormat | (string & {}) = MuxerFormat | (string & {})> {
29
+ /**
30
+ * Input media for automatic metadata and property copying.
31
+ *
32
+ * When provided, Muxer will automatically copy:
33
+ * - Container-level metadata (title, artist, etc.)
34
+ * - Stream-level metadata
35
+ * - Disposition flags (DEFAULT, FORCED, etc.)
36
+ * - Duration hints for encoding
37
+ *
38
+ * This matches FFmpeg CLI behavior which copies metadata by default.
39
+ */
40
+ input?: Demuxer | RTPDemuxer;
41
+ /**
42
+ * Preferred output format.
43
+ *
44
+ * If not specified, format is guessed from file extension.
45
+ * Use this to override automatic format detection.
46
+ *
47
+ * Matches FFmpeg CLI's -f option.
48
+ *
49
+ * When given as a literal (e.g. `'mp4'`), `options` is strongly typed to that
50
+ * muxer's known options plus the generic AVFormatContext options.
51
+ */
52
+ format?: F;
53
+ /**
54
+ * Buffer size for I/O operations.
55
+ *
56
+ * This option controls the size of the internal buffer used for
57
+ * reading and writing data.
58
+ *
59
+ * @default 32768 (32 KB, matches FFmpeg CLI default)
60
+ */
61
+ bufferSize?: number;
62
+ /**
63
+ * Maximum packet size for I/O operations.
64
+ *
65
+ * This option controls the maximum size of individual packets
66
+ * for protocols that require specific packet sizes (e.g., RTP with MTU constraints).
67
+ *
68
+ * Matches FFmpeg's max_packet_size in AVIOContext.
69
+ *
70
+ * @default 1200
71
+ */
72
+ maxPacketSize?: number;
73
+ /**
74
+ * Exit immediately on first write error.
75
+ *
76
+ * When enabled, the muxer will terminate on the first write error.
77
+ * When disabled, errors are logged but processing continues.
78
+ * Timestamp discontinuities the muxer refuses to write (see
79
+ * {@link MuxerOptions.dtsBackwardThreshold} and
80
+ * {@link MuxerOptions.dtsForwardThreshold}) are thrown either way.
81
+ *
82
+ * @default true
83
+ */
84
+ exitOnError?: boolean;
85
+ /**
86
+ * Backward DTS jump in seconds above which writing a packet fails.
87
+ *
88
+ * Audio and video DTS must not decrease, so a packet behind the stream's last
89
+ * written DTS is clamped forward. After a large backward jump (a live source
90
+ * restarting its clock) every following packet is clamped to one tick past the
91
+ * previous one until the source catches up again, collapsing the timeline for
92
+ * as long as the jump. With a threshold set, such a packet is rejected with an
93
+ * error instead, so the owner can restart on a fresh timeline. Smaller jumps
94
+ * are still clamped. `0` disables the check.
95
+ *
96
+ * Independent of this option, MP4/MOV-family outputs always reject a DTS step
97
+ * or packet duration that their 32-bit sample durations cannot store (INT_MAX
98
+ * ticks or more), where movenc would otherwise collapse the step to one tick
99
+ * or abort the process. Without an edit list (fragmented output without
100
+ * `delay_moov`) they also reject the first packet of a stream that starts
101
+ * more than `max_interleave_delta` (10 s) after the others and ends before
102
+ * the output's start, which movenc cannot store either.
103
+ *
104
+ * @default 0
105
+ */
106
+ dtsBackwardThreshold?: number;
107
+ /**
108
+ * Forward DTS jump in seconds, beyond the real time that passed, above which
109
+ * writing a packet fails.
110
+ *
111
+ * For a source read in real time, timestamps advance with the clock: a gap
112
+ * in the stream comes with a matching wait for the packet after it. A packet
113
+ * whose DTS runs further ahead than the time that passed is a
114
+ * discontinuity (a live source restarting its clock behind a restreamer),
115
+ * and writing it would leave a sample spanning the jump. With a threshold
116
+ * set, such a packet is rejected with an error before it reaches the
117
+ * output, so the owner can restart on a fresh timeline. Real time is
118
+ * measured per audio/video stream from when its packets are passed to
119
+ * writePacket(), and a packet is compared with the stream's last 128 to 256
120
+ * packets, so frames a parser or encoder held back during a gap do not make
121
+ * the end of the gap look like a jump. A stream's first packet is not
122
+ * checked, and a packet without DTS is measured by its PTS. Use it only for
123
+ * sources read in real time: a file read faster than real time has its gaps
124
+ * without the wait. `0` disables the check.
125
+ *
126
+ * @default 0
127
+ */
128
+ dtsForwardThreshold?: number;
129
+ /**
130
+ * Maximum number of packets to buffer per stream in the sync queue.
131
+ *
132
+ * Matches FFmpeg CLI's -max_muxing_queue_size option.
133
+ * Limits memory usage when encoders are still initializing.
134
+ * Takes effect after muxingQueueDataThreshold is reached.
135
+ * If exceeded, an error is thrown.
136
+ *
137
+ * @default 128 (same as FFmpeg CLI)
138
+ */
139
+ maxMuxingQueueSize?: number;
140
+ /**
141
+ * Threshold in bytes after which maxMuxingQueueSize takes effect.
142
+ *
143
+ * Matches FFmpeg CLI's -muxing_queue_data_threshold option.
144
+ * Once this threshold is reached, maxMuxingQueueSize limit applies.
145
+ * This is an intelligent system: small streams (audio) can buffer many packets,
146
+ * large streams (video) are limited by packet count.
147
+ *
148
+ * @default 52428800 (50 MB, same as FFmpeg CLI)
149
+ */
150
+ muxingQueueDataThreshold?: number;
151
+ /**
152
+ * Maximum buffering duration in seconds for sync queue interleaving.
153
+ *
154
+ * Matches FFmpeg CLI's -shortest_buf_duration option.
155
+ * Controls how much buffering is allowed in the native sync queue
156
+ * for packet interleaving across multiple streams.
157
+ *
158
+ * @default 10 (same as FFmpeg CLI)
159
+ */
160
+ syncQueueBufferDuration?: number;
161
+ /**
162
+ * Start time offset in seconds for output timestamps.
163
+ *
164
+ * Matches FFmpeg CLI's -ss (output) option.
165
+ * Subtracts this offset from all packet timestamps.
166
+ * Use for trimming from start of stream.
167
+ *
168
+ * @default AV_NOPTS_VALUE (no offset)
169
+ */
170
+ startTime?: number;
171
+ /**
172
+ * Whether to copy initial non-keyframe packets in streamcopy mode.
173
+ *
174
+ * Matches FFmpeg CLI's -copyinkf option.
175
+ * If false (default), packets before first keyframe are skipped.
176
+ * If true, all packets from start are copied.
177
+ *
178
+ * @default false
179
+ */
180
+ copyInitialNonkeyframes?: boolean;
181
+ /**
182
+ * Copy or discard frames before start time.
183
+ *
184
+ * Matches FFmpeg CLI's -copypriorss option.
185
+ * Controls whether packets before the start time are copied:
186
+ * - -1 (default): Use FFmpeg's internal ts_copy_start calculation
187
+ * - 0: Discard packets before start time
188
+ * - 1: Copy all packets regardless of start time
189
+ *
190
+ * @default -1
191
+ */
192
+ copyPriorStart?: number;
193
+ /**
194
+ * Use synchronous packet queue for interleaving.
195
+ *
196
+ * When true and there are stream copy streams present, enables FFmpeg's
197
+ * sync queue for proper interleaving of packets based on timestamps.
198
+ *
199
+ * The sync queue is only activated when both conditions are met:
200
+ * - `useSyncQueue` is `true`
201
+ * - Output contains at least one stream copy stream
202
+ *
203
+ * This includes scenarios with:
204
+ * - Only stream copy streams (e.g., 1 streamcopy stream)
205
+ * - Mixed streams (e.g., 1 streamcopy + 1 encoded stream)
206
+ *
207
+ * For outputs with only encoded streams, the sync queue is not used.
208
+ *
209
+ * @default true
210
+ */
211
+ useSyncQueue?: boolean;
212
+ /**
213
+ * Use asynchronous write queue to prevent race conditions.
214
+ *
215
+ * When true and there are multiple streams (> 1), all write operations
216
+ * are serialized through an async queue, preventing concurrent access
217
+ * to AVFormatContext which can cause "Packet duration out of range"
218
+ * errors with parallel encoding.
219
+ *
220
+ * The async queue is only activated when both conditions are met:
221
+ * - `useAsyncWrite` is `true`
222
+ * - Output has more than one stream
223
+ *
224
+ * For single-stream outputs, writes are performed directly without
225
+ * queuing, regardless of this setting.
226
+ *
227
+ * @default true
228
+ */
229
+ useAsyncWrite?: boolean;
230
+ /**
231
+ * FFmpeg format options passed directly to the output.
232
+ *
233
+ * Key-value pairs of FFmpeg AVFormatContext / muxer-private options, applied
234
+ * before avformat_write_header(). When `format` is a known literal, these are
235
+ * typed to that muxer's options (autocomplete + value typing); arbitrary keys
236
+ * remain allowed so protocol/other options still pass.
237
+ */
238
+ options?: MuxerOptionsFor<F>;
239
+ /**
240
+ * Configure the underlying format context just before the header is written.
241
+ *
242
+ * Called with the output {@link FormatContext} once, after all streams have
243
+ * been initialized (their parameters, metadata, and disposition copied from
244
+ * the source) and immediately before `avformat_write_header`. Use it to set
245
+ * any container- or stream-level field with full type safety — for example
246
+ * per-stream metadata (language/title) or disposition that should not be
247
+ * overwritten by the source. Settings applied here take precedence because
248
+ * they run after the source values are copied.
249
+ *
250
+ * @example
251
+ * ```typescript
252
+ * import { Dictionary } from 'node-av';
253
+ *
254
+ * await Muxer.open('out.mp4', {
255
+ * configure: (fmt) => {
256
+ * fmt.streams[1].metadata = Dictionary.fromObject({ language: 'eng' });
257
+ * },
258
+ * });
259
+ * ```
260
+ */
261
+ configure?: (context: FormatContext) => void;
262
+ /**
263
+ * Fields to set on the underlying format context.
264
+ *
265
+ * A typed, declarative bag for any writable {@link FormatContext} field. Applied
266
+ * once, after all streams are initialized (their parameters, metadata and
267
+ * disposition copied from the source) and immediately before
268
+ * `avformat_write_header`, so values here take precedence. The allowed keys are
269
+ * derived from the class, so every writable field is available and correctly
270
+ * typed. For per-stream or computed changes use {@link MuxerOptions.configure}.
271
+ *
272
+ * @example
273
+ * ```typescript
274
+ * await Muxer.open('out.mp4', {
275
+ * context: {
276
+ * startTime: 0n,
277
+ * },
278
+ * });
279
+ * ```
280
+ */
281
+ context?: ContextOptions<FormatContext>;
282
+ /**
283
+ * AbortSignal for cancellation.
284
+ *
285
+ * When aborted, async methods throw AbortError.
286
+ */
287
+ signal?: AbortSignal;
288
+ }
289
+ /**
290
+ * High-level muxer for writing and muxing media files.
291
+ *
292
+ * Provides simplified access to media muxing and file writing operations.
293
+ * Automatically manages header and trailer writing - header is written on first packet,
294
+ * trailer is written on close. Supports lazy initialization for both encoders and streams.
295
+ * Handles stream configuration, packet writing, and format management.
296
+ * Supports files, URLs, and custom I/O with automatic cleanup.
297
+ * Essential component for media encoding pipelines and transcoding.
298
+ *
299
+ * @example
300
+ * ```typescript
301
+ * import { Muxer } from 'node-av/api';
302
+ *
303
+ * // Create output file
304
+ * await using output = await Muxer.open('output.mp4');
305
+ *
306
+ * // Add streams from encoders
307
+ * const videoIdx = output.addStream(videoEncoder);
308
+ * const audioIdx = output.addStream(audioEncoder);
309
+ *
310
+ * // Write packets - header written automatically on first packet
311
+ * await output.writePacket(packet, videoIdx);
312
+ *
313
+ * // Close - trailer written automatically
314
+ * // (automatic with await using)
315
+ * ```
316
+ *
317
+ * @example
318
+ * ```typescript
319
+ * // Stream copy
320
+ * await using input = await Demuxer.open('input.mp4');
321
+ * await using output = await Muxer.open('output.mp4');
322
+ *
323
+ * // Copy stream configuration
324
+ * const videoIdx = output.addStream(input.video());
325
+ *
326
+ * // Process packets - header/trailer handled automatically
327
+ * for await (const packet of input.packets()) {
328
+ * await output.writePacket(packet, videoIdx);
329
+ * packet.free();
330
+ * }
331
+ * ```
332
+ *
333
+ * @see {@link Demuxer} For reading media files
334
+ * @see {@link Encoder} For encoding frames to packets
335
+ * @see {@link FormatContext} For low-level API
336
+ */
337
+ export declare class Muxer implements AsyncDisposable, Disposable {
338
+ private formatContext;
339
+ private options;
340
+ private _streams;
341
+ private ioContext?;
342
+ private customIO;
343
+ private headerWritten;
344
+ private headerWritePromise?;
345
+ private trailerWritten;
346
+ private isClosed;
347
+ private syncQueue?;
348
+ private sqPacket?;
349
+ private containerMetadataCopied;
350
+ private writeQueue?;
351
+ private writeWorkerPromise?;
352
+ private writeWorkerError?;
353
+ private signal?;
354
+ private movSampleLimit;
355
+ private tsNonStrict;
356
+ private movZeroStart;
357
+ private interleaveDeltaUs;
358
+ private trailerDiscarded;
359
+ private forwardThresholdMs;
360
+ private clock;
361
+ private packetObserver?;
362
+ /**
363
+ * @param options - Media output options
364
+ *
365
+ * @throws {RangeError} If dtsBackwardThreshold or dtsForwardThreshold is not a finite number >= 0
366
+ *
367
+ * @internal
368
+ */
369
+ private constructor();
370
+ /**
371
+ * Open muxer for writing.
372
+ *
373
+ * Creates and configures output context for muxing.
374
+ * Automatically creates directories for file output.
375
+ * Supports files, URLs, and custom I/O callbacks.
376
+ *
377
+ * Direct mapping to avformat_alloc_output_context2() and avio_open2().
378
+ *
379
+ * @param target - File path, URL, or I/O callbacks
380
+ *
381
+ * @param options - Output configuration options
382
+ *
383
+ * @returns Opened muxer instance
384
+ *
385
+ * @throws {Error} If format required for custom I/O
386
+ *
387
+ * @throws {RangeError} If dtsBackwardThreshold or dtsForwardThreshold is not a finite number >= 0
388
+ *
389
+ * @throws {FFmpegError} If allocation or opening fails
390
+ *
391
+ * @example
392
+ * ```typescript
393
+ * // Create file output
394
+ * await using output = await Muxer.open('output.mp4');
395
+ * ```
396
+ *
397
+ * @example
398
+ * ```typescript
399
+ * // Create output with specific format
400
+ * await using output = await Muxer.open('output.ts', {
401
+ * format: 'mpegts'
402
+ * });
403
+ * ```
404
+ *
405
+ * @example
406
+ * ```typescript
407
+ * // Custom I/O callbacks - async streaming to web destination
408
+ * const callbacks = {
409
+ * write: async (buffer: Buffer) => {
410
+ * await streamWriter.write(buffer);
411
+ * return buffer.length;
412
+ * }
413
+ * };
414
+ *
415
+ * await using output = await Muxer.open(callbacks, {
416
+ * format: 'mp4',
417
+ * bufferSize: 8192
418
+ * });
419
+ * ```
420
+ *
421
+ * @example
422
+ * ```typescript
423
+ * // Custom I/O callbacks - synchronous buffering
424
+ * const chunks: Buffer[] = [];
425
+ * const callbacks = {
426
+ * write: (buffer: Buffer) => {
427
+ * chunks.push(Buffer.from(buffer));
428
+ * return buffer.length;
429
+ * }
430
+ * };
431
+ *
432
+ * await using output = await Muxer.open(callbacks, { format: 'mp4' });
433
+ * ```
434
+ *
435
+ * @see {@link MuxerOptions} For configuration options
436
+ * @see {@link IOOutputCallbacks} For custom I/O interface
437
+ */
438
+ static open<const F extends MuxerFormat | (string & {}) = MuxerFormat | (string & {})>(target: string, options?: MuxerOptions<F>): Promise<Muxer>;
439
+ static open<const F extends MuxerFormat | (string & {})>(target: IOOutputCallbacks, options: MuxerOptions<F> & {
440
+ format: F;
441
+ }): Promise<Muxer>;
442
+ static open<const F extends MuxerFormat | (string & {})>(target: Writable, options: MuxerOptions<F> & {
443
+ format: F;
444
+ }): Promise<Muxer>;
445
+ /**
446
+ * Open muxer for writing synchronously.
447
+ * Synchronous version of open.
448
+ *
449
+ * Creates and configures output context for muxing.
450
+ * Automatically creates directories for file output.
451
+ * Supports files, URLs, and custom I/O callbacks.
452
+ *
453
+ * Direct mapping to avformat_alloc_output_context2() and avio_open2().
454
+ *
455
+ * @param target - File path, URL, or I/O callbacks
456
+ *
457
+ * @param options - Output configuration options
458
+ *
459
+ * @returns Opened muxer instance
460
+ *
461
+ * @throws {Error} If format required for custom I/O
462
+ *
463
+ * @throws {RangeError} If dtsBackwardThreshold or dtsForwardThreshold is not a finite number >= 0
464
+ *
465
+ * @throws {FFmpegError} If allocation or opening fails
466
+ *
467
+ * @example
468
+ * ```typescript
469
+ * // Create file output
470
+ * using output = Muxer.openSync('output.mp4');
471
+ * ```
472
+ *
473
+ * @example
474
+ * ```typescript
475
+ * // Create output with specific format
476
+ * using output = Muxer.openSync('output.ts', {
477
+ * format: 'mpegts'
478
+ * });
479
+ * ```
480
+ *
481
+ * @see {@link open} For async version
482
+ */
483
+ static openSync<const F extends MuxerFormat | (string & {}) = MuxerFormat | (string & {})>(target: string, options?: MuxerOptions<F>): Muxer;
484
+ static openSync<const F extends MuxerFormat | (string & {})>(target: IOOutputCallbacks, options: MuxerOptions<F> & {
485
+ format: F;
486
+ }): Muxer;
487
+ static openSync<const F extends MuxerFormat | (string & {})>(target: Writable, options: MuxerOptions<F> & {
488
+ format: F;
489
+ }): Muxer;
490
+ /**
491
+ * Check if output is open.
492
+ *
493
+ * @example
494
+ * ```typescript
495
+ * if (!output.isOutputOpen) {
496
+ * console.log('Output is not open');
497
+ * }
498
+ * ```
499
+ */
500
+ get isOpen(): boolean;
501
+ /**
502
+ * Check if output is initialized.
503
+ *
504
+ * All streams have been initialized.
505
+ * This occurs after the first packet has been written to each stream.
506
+ *
507
+ * @example
508
+ * ```typescript
509
+ * if (!output.isOutputInitialized) {
510
+ * console.log('Output is not initialized');
511
+ * }
512
+ * ```
513
+ */
514
+ get streamsInitialized(): boolean;
515
+ /**
516
+ * Get all streams in the media.
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * for (const stream of output.streams) {
521
+ * console.log(`Stream ${stream.index}: ${stream.codecpar.codecType}`);
522
+ * }
523
+ * ```
524
+ */
525
+ get streams(): Stream[];
526
+ /**
527
+ * Get format name.
528
+ *
529
+ * Returns 'unknown' if output is closed or format is not available.
530
+ *
531
+ * @example
532
+ * ```typescript
533
+ * console.log(`Format: ${output.formatName}`); // "mov,mp4,m4a,3gp,3g2,mj2"
534
+ * ```
535
+ */
536
+ get formatName(): string;
537
+ /**
538
+ * Get format long name.
539
+ *
540
+ * Returns 'Unknown Format' if output is closed or format is not available.
541
+ *
542
+ * @example
543
+ * ```typescript
544
+ * console.log(`Format: ${output.formatLongName}`); // "QuickTime / MOV"
545
+ * ```
546
+ */
547
+ get formatLongName(): string;
548
+ /**
549
+ * Get MIME type of the output format.
550
+ *
551
+ * Returns format's native MIME type.
552
+ * Returns null if output is closed or format is not available.
553
+ *
554
+ * @example
555
+ * ```typescript
556
+ * console.log(mp4Output.mimeType); // "video/mp4"
557
+ * ```
558
+ */
559
+ get mimeType(): string | null;
560
+ /**
561
+ * Add a stream to the output (encoder-only mode).
562
+ *
563
+ * Configures output stream from encoder. Stream is initialized lazily from first encoded frame.
564
+ * Use this when generating frames programmatically without an input stream.
565
+ *
566
+ * @param encoder - Encoder for encoding frames to packets
567
+ *
568
+ * @param options - Stream configuration options
569
+ *
570
+ * @param options.inputStream - Optional input stream for metadata/properties
571
+ *
572
+ * @returns Stream index for packet writing
573
+ *
574
+ * @throws {Error} If called after packets have been written or output closed
575
+ *
576
+ * @example
577
+ * ```typescript
578
+ * // Encoder-only (e.g., frame generator)
579
+ * const encoder = await Encoder.create(FF_ENCODER_LIBX264);
580
+ * const streamIdx = output.addStream(encoder);
581
+ * ```
582
+ *
583
+ * @example
584
+ * ```typescript
585
+ * // Encoder with input stream for metadata
586
+ * const streamIdx = output.addStream(encoder, {
587
+ * inputStream: input.video()
588
+ * });
589
+ * ```
590
+ */
591
+ addStream(encoder: Encoder, options?: {
592
+ inputStream?: Stream;
593
+ bsf?: BitStreamFilterAPI;
594
+ }): number;
595
+ /**
596
+ * Add a stream to the output (stream copy or transcoding mode).
597
+ *
598
+ * Configures output stream from input stream and optional encoder.
599
+ * Must be called before writing any packets.
600
+ * Returns stream index for packet writing.
601
+ *
602
+ * Automatically copies from input stream:
603
+ * - Codec parameters (stream copy mode)
604
+ * - Metadata
605
+ * - Disposition flags
606
+ * - Frame rates and aspect ratios
607
+ * - Duration hints
608
+ * - HDR/Dolby Vision side data (coded_side_data)
609
+ *
610
+ * When encoder is provided:
611
+ * - Stream is initialized lazily from first encoded frame
612
+ * - Metadata and disposition copied from input stream
613
+ * - Duration hint used for muxer
614
+ *
615
+ * Direct mapping to avformat_new_stream().
616
+ *
617
+ * @param stream - Input stream (source for properties/metadata)
618
+ *
619
+ * @param options - Stream configuration options
620
+ *
621
+ * @param options.encoder - Optional encoder for transcoding
622
+ *
623
+ * @returns Stream index for packet writing
624
+ *
625
+ * @throws {Error} If called after packets have been written or output closed
626
+ *
627
+ * @example
628
+ * ```typescript
629
+ * // Stream copy
630
+ * const videoIdx = output.addStream(input.video());
631
+ * const audioIdx = output.addStream(input.audio());
632
+ * ```
633
+ *
634
+ * @example
635
+ * ```typescript
636
+ * // With encoding
637
+ * const videoIdx = output.addStream(input.video(), {
638
+ * encoder: videoEncoder
639
+ * });
640
+ * ```
641
+ *
642
+ * @see {@link writePacket} For writing packets to streams
643
+ * @see {@link Encoder} For transcoding source
644
+ */
645
+ addStream(stream: Stream, options?: {
646
+ encoder?: Encoder;
647
+ bsf?: BitStreamFilterAPI;
648
+ }): number;
649
+ /**
650
+ * Get output stream by index.
651
+ *
652
+ * Returns the stream at the specified index.
653
+ * Use the stream index returned by addStream().
654
+ *
655
+ * @param index - Stream index (returned by addStream)
656
+ *
657
+ * @returns Stream or undefined if index is invalid
658
+ *
659
+ * @example
660
+ * ```typescript
661
+ * const output = await Muxer.open('output.mp4');
662
+ * const videoIdx = output.addStream(encoder);
663
+ *
664
+ * // Get the output stream to inspect codec parameters
665
+ * const stream = output.getStream(videoIdx);
666
+ * if (stream) {
667
+ * console.log(`Output codec: ${stream.codecpar.codecId}`);
668
+ * }
669
+ * ```
670
+ *
671
+ * @see {@link addStream} For adding streams
672
+ * @see {@link video} For getting video streams
673
+ * @see {@link audio} For getting audio streams
674
+ */
675
+ getStream(index: number): Stream | undefined;
676
+ /**
677
+ * Get video stream by index.
678
+ *
679
+ * Returns the nth video stream (0-based index).
680
+ * Returns undefined if stream doesn't exist.
681
+ *
682
+ * @param index - Video stream index (default: 0)
683
+ *
684
+ * @returns Video stream or undefined
685
+ *
686
+ * @example
687
+ * ```typescript
688
+ * const output = await Muxer.open('output.mp4');
689
+ * output.addStream(videoEncoder);
690
+ *
691
+ * // Get first video stream
692
+ * const videoStream = output.video();
693
+ * if (videoStream) {
694
+ * console.log(`Video output: ${videoStream.codecpar.width}x${videoStream.codecpar.height}`);
695
+ * }
696
+ * ```
697
+ *
698
+ * @see {@link audio} For audio streams
699
+ * @see {@link getStream} For direct stream access
700
+ */
701
+ video(index?: number): Stream | undefined;
702
+ /**
703
+ * Get audio stream by index.
704
+ *
705
+ * Returns the nth audio stream (0-based index).
706
+ * Returns undefined if stream doesn't exist.
707
+ *
708
+ * @param index - Audio stream index (default: 0)
709
+ *
710
+ * @returns Audio stream or undefined
711
+ *
712
+ * @example
713
+ * ```typescript
714
+ * const output = await Muxer.open('output.mp4');
715
+ * output.addStream(audioEncoder);
716
+ *
717
+ * // Get first audio stream
718
+ * const audioStream = output.audio();
719
+ * if (audioStream) {
720
+ * console.log(`Audio output: ${audioStream.codecpar.sampleRate}Hz`);
721
+ * }
722
+ * ```
723
+ *
724
+ * @see {@link video} For video streams
725
+ * @see {@link getStream} For direct stream access
726
+ */
727
+ audio(index?: number): Stream | undefined;
728
+ /**
729
+ * Get output format.
730
+ *
731
+ * Returns the output format used for muxing.
732
+ * May be null if format context not initialized.
733
+ *
734
+ * @returns Output format or null
735
+ *
736
+ * @example
737
+ * ```typescript
738
+ * const output = await Muxer.open('output.mp4');
739
+ * const format = output.outputFormat();
740
+ * if (format) {
741
+ * console.log(`Output format: ${format.name}`);
742
+ * }
743
+ * ```
744
+ *
745
+ * @see {@link OutputFormat} For format details
746
+ */
747
+ outputFormat(): OutputFormat | null;
748
+ /**
749
+ * Write a packet to the output.
750
+ *
751
+ * Writes muxed packet to the specified stream.
752
+ * Automatically handles:
753
+ * - Stream initialization on first packet (lazy initialization)
754
+ * - Codec parameter configuration from encoder or input stream
755
+ * - Header writing on first packet
756
+ * - Timestamp rescaling between source and output timebases
757
+ * - Sync queue for proper interleaving
758
+ *
759
+ * For encoder sources, the encoder must have processed at least one frame
760
+ * before packets can be written (encoder must be initialized).
761
+ *
762
+ * Uses FFmpeg CLI's sync queue pattern: buffers packets per stream and writes
763
+ * them in DTS order using av_compare_ts for timebase-aware comparison.
764
+ *
765
+ * To signal EOF for a stream, pass null as the packet.
766
+ * This tells the muxer that no more packets will be sent for this stream.
767
+ * The trailer is written only when close() is called.
768
+ *
769
+ * Direct mapping to avformat_write_header() (on first packet) and av_interleaved_write_frame().
770
+ *
771
+ * @param packet - Packet to write (or null to signal EOF for the stream)
772
+ *
773
+ * @param streamIndex - Target stream index
774
+ *
775
+ * @throws {Error} If stream invalid or encoder not initialized
776
+ *
777
+ * @throws {Error} On a timestamp discontinuity the output cannot take (see {@link MuxerOptions.dtsBackwardThreshold}).
778
+ * With the background write queue (more than one stream) it surfaces from a later writePacket() or close().
779
+ *
780
+ * @throws {FFmpegError} If write fails
781
+ *
782
+ * @example
783
+ * ```typescript
784
+ * // Write encoded packet - header written automatically on first packet
785
+ * const packet = await encoder.encode(frame);
786
+ * if (packet) {
787
+ * await output.writePacket(packet, videoIdx);
788
+ * packet.free();
789
+ * }
790
+ * ```
791
+ *
792
+ * @example
793
+ * ```typescript
794
+ * // Stream copy with packet processing
795
+ * for await (const packet of input.packets()) {
796
+ * if (packet.streamIndex === inputVideoIdx) {
797
+ * await output.writePacket(packet, outputVideoIdx);
798
+ * }
799
+ * packet.free();
800
+ * }
801
+ * ```
802
+ *
803
+ * @see {@link addStream} For adding streams
804
+ */
805
+ writePacket(packet: Packet | null | undefined, streamIndex: number): Promise<void>;
806
+ /**
807
+ * Write a packet to the output synchronously.
808
+ * Synchronous version of writePacket.
809
+ *
810
+ * Writes muxed packet to the specified stream.
811
+ * Automatically handles:
812
+ * - Stream initialization on first packet (lazy initialization)
813
+ * - Codec parameter configuration from encoder or input stream
814
+ * - Header writing on first packet
815
+ * - Timestamp rescaling between source and output timebases
816
+ * - Sync queue for proper interleaving
817
+ *
818
+ * For encoder sources, the encoder must have processed at least one frame
819
+ * before packets can be written (encoder must be initialized).
820
+ *
821
+ * Uses FFmpeg CLI's sync queue pattern: buffers packets per stream and writes
822
+ * them in DTS order using av_compare_ts for timebase-aware comparison.
823
+ *
824
+ * To signal EOF for a stream, pass null as the packet.
825
+ * This tells the muxer that no more packets will be sent for this stream.
826
+ * The trailer is written only when close() is called.
827
+ *
828
+ * Direct mapping to avformat_write_header() (on first packet) and av_interleaved_write_frame().
829
+ *
830
+ * @param packet - Packet to write (or null/undefined to signal EOF)
831
+ *
832
+ * @param streamIndex - Target stream index
833
+ *
834
+ * @throws {Error} If stream invalid or encoder not initialized
835
+ *
836
+ * @throws {Error} On a timestamp discontinuity the output cannot take (see {@link MuxerOptions.dtsBackwardThreshold})
837
+ *
838
+ * @throws {FFmpegError} If write fails
839
+ *
840
+ * @example
841
+ * ```typescript
842
+ * // Write encoded packet - header written automatically on first packet
843
+ * const packet = encoder.encodeSync(frame);
844
+ * if (packet) {
845
+ * output.writePacketSync(packet, videoIdx);
846
+ * packet.free();
847
+ * }
848
+ * ```
849
+ *
850
+ * @example
851
+ * ```typescript
852
+ * // Stream copy with packet processing
853
+ * for (const packet of input.packetsSync()) {
854
+ * if (packet.streamIndex === inputVideoIdx) {
855
+ * output.writePacketSync(packet, outputVideoIdx);
856
+ * }
857
+ * packet.free();
858
+ * }
859
+ * ```
860
+ *
861
+ * @see {@link writePacket} For async version
862
+ */
863
+ writePacketSync(packet: Packet | null | undefined, streamIndex: number): void;
864
+ /**
865
+ * Close muxer and free resources.
866
+ *
867
+ * Automatically writes trailer if header was written.
868
+ * Closes the output file and releases all resources.
869
+ * Safe to call multiple times.
870
+ * Automatically called by Symbol.asyncDispose.
871
+ *
872
+ * @example
873
+ * ```typescript
874
+ * const output = await Muxer.open('output.mp4');
875
+ * try {
876
+ * // Use output - trailer written automatically on close
877
+ * } finally {
878
+ * await output.close();
879
+ * }
880
+ * ```
881
+ *
882
+ * @throws {Error} If a background write failed and was not yet observed by the caller (resources are still released; a second close() is a no-op)
883
+ *
884
+ * @see {@link Symbol.asyncDispose} For automatic cleanup
885
+ */
886
+ close(): Promise<void>;
887
+ /**
888
+ * Close muxer and free resources synchronously.
889
+ * Synchronous version of close.
890
+ *
891
+ * Automatically writes trailer if header was written.
892
+ * Closes the output file and releases all resources.
893
+ * Safe to call multiple times.
894
+ * Automatically called by Symbol.dispose.
895
+ *
896
+ * @example
897
+ * ```typescript
898
+ * const output = Muxer.openSync('output.mp4');
899
+ * try {
900
+ * // Use output - trailer written automatically on close
901
+ * } finally {
902
+ * output.closeSync();
903
+ * }
904
+ * ```
905
+ *
906
+ * @see {@link close} For async version
907
+ */
908
+ closeSync(): void;
909
+ /**
910
+ * Get underlying format context.
911
+ *
912
+ * Returns the internal format context for advanced operations.
913
+ *
914
+ * @returns Format context
915
+ *
916
+ * @internal
917
+ */
918
+ getFormatContext(): FormatContext;
919
+ /**
920
+ * Follow the packets this muxer accepts for writing.
921
+ *
922
+ * The observer hears about every packet with payload once it is accepted
923
+ * (before it waits in the pre-mux queue or reaches libavformat) and about
924
+ * every such packet that is dropped later, so together with the output it
925
+ * knows what the muxer holds. close() detaches it.
926
+ *
927
+ * @param observer - Observer, or undefined to detach
928
+ *
929
+ * @internal
930
+ */
931
+ setPacketObserver(observer: MuxerPacketObserver | undefined): void;
932
+ /**
933
+ * Replace the clock that stamps packet arrival times for the dtsForwardThreshold check.
934
+ *
935
+ * Lets tests drive real time deterministically. Set it before the first packet.
936
+ *
937
+ * @param clock - Monotonic time in ms
938
+ *
939
+ * @internal
940
+ */
941
+ setClock(clock: () => number): void;
942
+ /**
943
+ * Make close() skip the trailer.
944
+ *
945
+ * For owners that drop whatever the muxer still emits, such as FMP4Stream
946
+ * after a failed session: the trailer would only push libavformat's backlog
947
+ * into the void, and movenc asserts on some track states a failed session
948
+ * can leave behind. The backlog is freed with the format context instead.
949
+ *
950
+ * @internal
951
+ */
952
+ discardOnClose(): void;
953
+ /**
954
+ * Announce a packet the muxer has accepted to the packet observer.
955
+ *
956
+ * @param pkt - The muxer's clone of the packet
957
+ *
958
+ * @param streamIndex - Output stream index
959
+ *
960
+ * @returns True when the observer now tracks the packet
961
+ *
962
+ * @throws {Error} If the observer fails the write (the clone is freed)
963
+ *
964
+ * @internal
965
+ */
966
+ private announcePacket;
967
+ /**
968
+ * Apply shared pre-header setup for writePacket and writePacketSync.
969
+ *
970
+ * Configures sync queues, dispositions and container metadata, then applies
971
+ * user-provided context options and the configure callback. Must run
972
+ * immediately before writing the header so both variants stay in sync.
973
+ *
974
+ * @internal
975
+ */
976
+ private prepareHeaderWrite;
977
+ /**
978
+ * Read the muxing setup libavformat settles while writing the header.
979
+ *
980
+ * movenc decides on edit lists only then: without one (fragmented output
981
+ * without delay_moov) it shifts the output to start at 0 and puts each
982
+ * track's first sample there, which {@link checkMovLateStart} guards.
983
+ *
984
+ * @internal
985
+ */
986
+ private readHeaderSetup;
987
+ /**
988
+ * Setup sync queues based on stream configuration.
989
+ *
990
+ * Called before writing header.
991
+ * Muxing sync queue is created only if nb_interleaved > nb_av_enc
992
+ * (i.e., when there are streamcopy streams).
993
+ *
994
+ * All streams are added as non-limiting (FFmpeg default without -shortest),
995
+ * which means no timestamp-based synchronization - frames are output immediately.
996
+ *
997
+ * @internal
998
+ */
999
+ private setupSyncQueues;
1000
+ /**
1001
+ * Whether any stream still holds packets (or an EOF marker) in its pre-mux queue.
1002
+ *
1003
+ * @returns True if a pre-mux queue is not empty
1004
+ *
1005
+ * @internal
1006
+ */
1007
+ private hasPreMuxPackets;
1008
+ /**
1009
+ * Flush all PreMuxQueues in DTS-sorted order.
1010
+ *
1011
+ * Implements FFmpeg's PreMuxQueue flush algorithm from mux_task_start().
1012
+ * Repeatedly finds the stream with the earliest DTS packet and sends it:
1013
+ * - WITH SyncQueue: Sends to SyncQueue for interleaving
1014
+ * - WITHOUT SyncQueue: Writes directly to muxer
1015
+ * NULL packets (EOF markers) and packets with AV_NOPTS_VALUE have priority (sent first).
1016
+ *
1017
+ * @internal
1018
+ */
1019
+ private flushPreMuxQueues;
1020
+ /**
1021
+ * Flush all PreMuxQueues in DTS-sorted order (synchronous version).
1022
+ *
1023
+ * Implements FFmpeg's PreMuxQueue flush algorithm from mux_task_start().
1024
+ * Repeatedly finds the stream with the earliest DTS packet and sends it:
1025
+ * - WITH SyncQueue: Sends to SyncQueue for interleaving
1026
+ * - WITHOUT SyncQueue: Writes directly to muxer
1027
+ * NULL packets (EOF markers) and packets with AV_NOPTS_VALUE have priority (sent first).
1028
+ *
1029
+ * @internal
1030
+ */
1031
+ private flushPreMuxQueuesSync;
1032
+ /**
1033
+ * Write a packet to the output.
1034
+ *
1035
+ * @param pkt - Packet to write
1036
+ *
1037
+ * @param streamInfo - Stream description
1038
+ *
1039
+ * @param streamIndex - Stream index
1040
+ *
1041
+ * @param arrival - When the packet reached the muxer (ms on the arrival clock)
1042
+ *
1043
+ * @internal
1044
+ */
1045
+ private write;
1046
+ /**
1047
+ * Internal write implementation.
1048
+ * Called either directly or through the write worker.
1049
+ *
1050
+ * @param pkt - Packet to write
1051
+ *
1052
+ * @param streamInfo - Stream description
1053
+ *
1054
+ * @param streamIndex - Stream index
1055
+ *
1056
+ * @param arrival - When the packet reached the muxer (ms on the arrival clock)
1057
+ *
1058
+ * @internal
1059
+ */
1060
+ private writeInternal;
1061
+ /**
1062
+ * Start background worker for async write queue.
1063
+ * Processes write jobs sequentially to prevent race conditions.
1064
+ *
1065
+ * @internal
1066
+ */
1067
+ private startWriteWorker;
1068
+ /**
1069
+ * Write a packet to the output synchronously.
1070
+ * Synchronous version of write.
1071
+ *
1072
+ * @param pkt - Packet to write
1073
+ *
1074
+ * @param streamInfo - Stream description
1075
+ *
1076
+ * @param streamIndex - Stream index
1077
+ *
1078
+ * @param arrival - When the packet reached the muxer (ms on the arrival clock)
1079
+ *
1080
+ * @internal
1081
+ */
1082
+ private writeSync;
1083
+ /**
1084
+ * Streamcopy packet filtering and timestamp offset.
1085
+ *
1086
+ * Applies streamcopy-specific logic before muxing:
1087
+ * 1. Recording time limit check
1088
+ * 2. Skip non-keyframe packets at start (unless copyInitialNonkeyframes)
1089
+ * 3. Skip packets before ts_copy_start (unless copyPriorStart)
1090
+ * 4. Skip packets before startTime
1091
+ * 5. Apply start_time timestamp offset
1092
+ *
1093
+ * @param pkt - Packet to process
1094
+ *
1095
+ * @param streamInfo - Stream description
1096
+ *
1097
+ * @param streamIndex - Stream index
1098
+ *
1099
+ * @returns true if packet should be written, false if packet should be skipped
1100
+ *
1101
+ * @throws {Error} If recording time limit reached
1102
+ *
1103
+ * @internal
1104
+ */
1105
+ /**
1106
+ * Apply the configured `startTime` offset to an encoded packet, per stream.
1107
+ *
1108
+ * `startTime` exists to strip a device's boot-relative timestamp base (e.g. the
1109
+ * mach uptime avfoundation reports). But not every stream of an output carries
1110
+ * that base (e.g. zero-based audio next to device video), so subtracting a large
1111
+ * device startTime from such a stream would push its timestamps hugely negative and
1112
+ * produce a broken/overflowed edit list that strict players (QuickTime) reject. The
1113
+ * effective offset is therefore decided once on the stream's first packet and
1114
+ * clamped to what the stream actually carries —
1115
+ * `min(startTime, max(0, firstPts))`: boot-relative streams normalize to zero,
1116
+ * already-zero-based streams are left untouched.
1117
+ *
1118
+ * @param packet - Cloned packet to adjust in place
1119
+ *
1120
+ * @param streamInfo - Per-stream muxing state
1121
+ *
1122
+ * @internal
1123
+ */
1124
+ private applyStartTimeOffset;
1125
+ private ofStreamcopy;
1126
+ /**
1127
+ * Fix packet timestamps before muxing.
1128
+ *
1129
+ * Performs timestamp corrections:
1130
+ * 1. Rescales timestamps to output timebase (av_rescale_delta for audio streamcopy)
1131
+ * 2. Sets pkt.timeBase to output stream timebase
1132
+ * 3. Rejects backward jumps beyond dtsBackwardThreshold
1133
+ * 4. Fixes invalid DTS > PTS relationships
1134
+ * 5. Enforces monotonic DTS (never decreasing), shrinking a clamped packet's duration to the clamped step
1135
+ * 6. Rejects forward jumps that run ahead of real time beyond dtsForwardThreshold
1136
+ * 7. Rejects DTS steps/durations a movenc output cannot store, and a late stream's first packet before its start
1137
+ *
1138
+ * The stream's last muxed DTS only advances when the packet is accepted and
1139
+ * carries a DTS.
1140
+ *
1141
+ * @param pkt - Packet to fix
1142
+ *
1143
+ * @param streamInfo - Stream description
1144
+ *
1145
+ * @param streamIndex - Stream index
1146
+ *
1147
+ * @param arrival - When the packet reached the muxer (ms on the arrival clock)
1148
+ *
1149
+ * @throws {Error} On a rejected timestamp discontinuity
1150
+ *
1151
+ * @internal
1152
+ */
1153
+ private muxFixupTs;
1154
+ /**
1155
+ * Reject a packet whose DTS lies further behind the stream's last muxed DTS
1156
+ * than the configured dtsBackwardThreshold.
1157
+ *
1158
+ * Expects the DTS already rescaled to the output stream time base. No-op when
1159
+ * the threshold is unset or 0.
1160
+ *
1161
+ * @param dts - Packet DTS in the output time base
1162
+ *
1163
+ * @param lastMuxDts - The stream's last muxed DTS
1164
+ *
1165
+ * @param timeBase - Output stream time base
1166
+ *
1167
+ * @param streamIndex - Stream index
1168
+ *
1169
+ * @throws {Error} If the backward jump exceeds the threshold
1170
+ *
1171
+ * @internal
1172
+ */
1173
+ private checkBackwardDts;
1174
+ /**
1175
+ * Reject a packet whose DTS runs further ahead of real time than the
1176
+ * configured dtsForwardThreshold.
1177
+ *
1178
+ * Tracks per stream how real time and media time move apart (the offset) and
1179
+ * compares the packet's offset with the lowest one of the stream's recent
1180
+ * packets, see FORWARD_WINDOW_BUCKET. A gap in a live source leaves the
1181
+ * offset level, since the wait comes with it; a jump lowers it by the size
1182
+ * of the jump. The stream's first packet only sets the starting point.
1183
+ *
1184
+ * @param ts - Final packet DTS (PTS without DTS) in the output time base
1185
+ *
1186
+ * @param arrival - When the packet reached the muxer (ms on the arrival clock)
1187
+ *
1188
+ * @param streamInfo - Stream description
1189
+ *
1190
+ * @param streamIndex - Stream index
1191
+ *
1192
+ * @returns The packet's offset, for {@link recordForwardDts} once the packet is accepted
1193
+ *
1194
+ * @throws {Error} If the DTS runs ahead of real time by more than the threshold
1195
+ *
1196
+ * @internal
1197
+ */
1198
+ private checkForwardDts;
1199
+ /**
1200
+ * Make an accepted packet the reference of the stream's next forward check.
1201
+ *
1202
+ * @param state - The stream's forward check state
1203
+ *
1204
+ * @param ts - The packet's DTS (PTS without DTS) in the output time base
1205
+ *
1206
+ * @param offset - The packet's offset from {@link checkForwardDts}
1207
+ *
1208
+ * @param arrival - When the packet reached the muxer (ms on the arrival clock)
1209
+ *
1210
+ * @internal
1211
+ */
1212
+ private recordForwardDts;
1213
+ /**
1214
+ * Reject a packet whose DTS step or duration a movenc output cannot store.
1215
+ *
1216
+ * Runs after the monotonic clamp, on the DTS movenc will see. Steps are
1217
+ * measured against the stream's last muxed DTS.
1218
+ *
1219
+ * @param dts - Final packet DTS, or its PTS for a packet without DTS
1220
+ *
1221
+ * @param duration - Final packet duration
1222
+ *
1223
+ * @param lastMuxDts - The stream's last muxed DTS
1224
+ *
1225
+ * @param timeBase - Output stream time base
1226
+ *
1227
+ * @param streamIndex - Stream index
1228
+ *
1229
+ * @throws {Error} If the step or duration reaches INT_MAX ticks
1230
+ *
1231
+ * @internal
1232
+ */
1233
+ private checkMovSampleDuration;
1234
+ /**
1235
+ * Reject a stream's first packet that ends before the output's start.
1236
+ *
1237
+ * Without an edit list movenc puts each track's first sample at the output's
1238
+ * start, so a first packet that ends before it becomes a sample of negative
1239
+ * duration, and movenc aborts the process (av_assert0 in
1240
+ * get_cluster_duration) at the next fragment or the trailer unless a second
1241
+ * sample reaches it first. libavformat sets that start from the lowest DTS
1242
+ * it holds when it writes its first packet. It holds every packet until each
1243
+ * stream has sent one or its queue spans max_interleave_delta, so only a
1244
+ * stream that starts that much later than the others can land before it.
1245
+ *
1246
+ * @param ts - Packet DTS (PTS without DTS) in the output time base
1247
+ *
1248
+ * @param duration - Packet duration
1249
+ *
1250
+ * @param timeBase - Output stream time base
1251
+ *
1252
+ * @param streamIndex - Stream index
1253
+ *
1254
+ * @throws {Error} If the packet ends before a start libavformat may already have set
1255
+ *
1256
+ * @internal
1257
+ */
1258
+ private checkMovLateStart;
1259
+ /**
1260
+ * Copy container metadata from input to output.
1261
+ *
1262
+ * Automatically copies global metadata from input Demuxer to output format context.
1263
+ * Only copies once (on first call). Removes duration/creation_time metadata.
1264
+ *
1265
+ * @internal
1266
+ */
1267
+ private copyContainerMetadata;
1268
+ /**
1269
+ * Auto-set DEFAULT disposition for first stream of each type.
1270
+ *
1271
+ * FFmpeg automatically sets DEFAULT flag for the first stream of each type
1272
+ * if no stream of that type has DEFAULT set yet.
1273
+ *
1274
+ * @internal
1275
+ */
1276
+ private updateDefaultDisposition;
1277
+ /**
1278
+ * Dispose of muxer.
1279
+ *
1280
+ * Implements AsyncDisposable interface for automatic cleanup.
1281
+ * Equivalent to calling close().
1282
+ *
1283
+ * @example
1284
+ * ```typescript
1285
+ * {
1286
+ * await using output = await Muxer.open('output.mp4');
1287
+ * // Use output...
1288
+ * } // Automatically closed
1289
+ * ```
1290
+ *
1291
+ * @see {@link close} For manual cleanup
1292
+ */
1293
+ [Symbol.asyncDispose](): Promise<void>;
1294
+ /**
1295
+ * Dispose of muxer synchronously.
1296
+ *
1297
+ * Implements Disposable interface for automatic cleanup.
1298
+ * Equivalent to calling closeSync().
1299
+ *
1300
+ * @example
1301
+ * ```typescript
1302
+ * {
1303
+ * using output = Muxer.openSync('output.mp4');
1304
+ * // Use output...
1305
+ * } // Automatically closed
1306
+ * ```
1307
+ *
1308
+ * @see {@link closeSync} For manual cleanup
1309
+ */
1310
+ [Symbol.dispose](): void;
1311
+ }