@nodetool-ai/runtime 0.8.7 → 0.8.9-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 (169) hide show
  1. package/dist/.nodetool-build-stamp +1 -1
  2. package/dist/context.d.ts +6 -2
  3. package/dist/context.d.ts.map +1 -1
  4. package/dist/context.js +13 -24
  5. package/dist/context.js.map +1 -1
  6. package/dist/host-binaries.d.ts +5 -5
  7. package/dist/host-binaries.js +5 -5
  8. package/dist/index.d.ts +2 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +2 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/invocation-account.d.ts +1 -42
  13. package/dist/invocation-account.d.ts.map +1 -1
  14. package/dist/invocation-account.js +1 -59
  15. package/dist/invocation-account.js.map +1 -1
  16. package/dist/media/abort.d.ts +8 -0
  17. package/dist/media/abort.d.ts.map +1 -0
  18. package/dist/media/abort.js +18 -0
  19. package/dist/media/abort.js.map +1 -0
  20. package/dist/media/audio-encoder.d.ts +37 -0
  21. package/dist/media/audio-encoder.d.ts.map +1 -0
  22. package/dist/media/audio-encoder.js +118 -0
  23. package/dist/media/audio-encoder.js.map +1 -0
  24. package/dist/media/audio.d.ts +36 -0
  25. package/dist/media/audio.d.ts.map +1 -0
  26. package/dist/media/audio.js +84 -0
  27. package/dist/media/audio.js.map +1 -0
  28. package/dist/media/av.d.ts +51 -0
  29. package/dist/media/av.d.ts.map +1 -0
  30. package/dist/media/av.js +146 -0
  31. package/dist/media/av.js.map +1 -0
  32. package/dist/media/codecs.d.ts +9 -0
  33. package/dist/media/codecs.d.ts.map +1 -0
  34. package/dist/media/codecs.js +17 -0
  35. package/dist/media/codecs.js.map +1 -0
  36. package/dist/media/concat.d.ts +56 -0
  37. package/dist/media/concat.d.ts.map +1 -0
  38. package/dist/media/concat.js +319 -0
  39. package/dist/media/concat.js.map +1 -0
  40. package/dist/media/convert.d.ts +31 -0
  41. package/dist/media/convert.d.ts.map +1 -0
  42. package/dist/media/convert.js +114 -0
  43. package/dist/media/convert.js.map +1 -0
  44. package/dist/media/decode.d.ts +31 -0
  45. package/dist/media/decode.d.ts.map +1 -0
  46. package/dist/media/decode.js +85 -0
  47. package/dist/media/decode.js.map +1 -0
  48. package/dist/media/filter-graph.d.ts +53 -0
  49. package/dist/media/filter-graph.d.ts.map +1 -0
  50. package/dist/media/filter-graph.js +260 -0
  51. package/dist/media/filter-graph.js.map +1 -0
  52. package/dist/media/frames.d.ts +31 -0
  53. package/dist/media/frames.d.ts.map +1 -0
  54. package/dist/media/frames.js +112 -0
  55. package/dist/media/frames.js.map +1 -0
  56. package/dist/media/index.d.ts +26 -0
  57. package/dist/media/index.d.ts.map +1 -0
  58. package/dist/media/index.js +26 -0
  59. package/dist/media/index.js.map +1 -0
  60. package/dist/media/mux.d.ts +58 -0
  61. package/dist/media/mux.d.ts.map +1 -0
  62. package/dist/media/mux.js +234 -0
  63. package/dist/media/mux.js.map +1 -0
  64. package/dist/media/probe.d.ts +84 -0
  65. package/dist/media/probe.d.ts.map +1 -0
  66. package/dist/media/probe.js +133 -0
  67. package/dist/media/probe.js.map +1 -0
  68. package/dist/media/rgba.d.ts +78 -0
  69. package/dist/media/rgba.d.ts.map +1 -0
  70. package/dist/media/rgba.js +285 -0
  71. package/dist/media/rgba.js.map +1 -0
  72. package/dist/media/testing.d.ts +119 -0
  73. package/dist/media/testing.d.ts.map +1 -0
  74. package/dist/media/testing.js +343 -0
  75. package/dist/media/testing.js.map +1 -0
  76. package/dist/media/transcode.d.ts +17 -0
  77. package/dist/media/transcode.d.ts.map +1 -0
  78. package/dist/media/transcode.js +19 -0
  79. package/dist/media/transcode.js.map +1 -0
  80. package/dist/media/transform.d.ts +61 -0
  81. package/dist/media/transform.d.ts.map +1 -0
  82. package/dist/media/transform.js +371 -0
  83. package/dist/media/transform.js.map +1 -0
  84. package/dist/media/verify.d.ts +17 -0
  85. package/dist/media/verify.d.ts.map +1 -0
  86. package/dist/media/verify.js +65 -0
  87. package/dist/media/verify.js.map +1 -0
  88. package/dist/media-loader.d.ts +8 -0
  89. package/dist/media-loader.d.ts.map +1 -0
  90. package/dist/media-loader.js +10 -0
  91. package/dist/media-loader.js.map +1 -0
  92. package/dist/prefixed-storage-adapter.d.ts.map +1 -1
  93. package/dist/prefixed-storage-adapter.js +1 -1
  94. package/dist/prefixed-storage-adapter.js.map +1 -1
  95. package/dist/providers/anthropic-provider.d.ts +21 -0
  96. package/dist/providers/anthropic-provider.d.ts.map +1 -1
  97. package/dist/providers/anthropic-provider.js +82 -17
  98. package/dist/providers/anthropic-provider.js.map +1 -1
  99. package/dist/providers/claude-agent-provider.js +14 -2
  100. package/dist/providers/claude-agent-provider.js.map +1 -1
  101. package/dist/providers/codex-provider.d.ts +10 -0
  102. package/dist/providers/codex-provider.d.ts.map +1 -1
  103. package/dist/providers/codex-provider.js +29 -3
  104. package/dist/providers/codex-provider.js.map +1 -1
  105. package/dist/providers/data-uri.d.ts +6 -0
  106. package/dist/providers/data-uri.d.ts.map +1 -0
  107. package/dist/providers/data-uri.js +19 -0
  108. package/dist/providers/data-uri.js.map +1 -0
  109. package/dist/providers/dreamina-provider.d.ts +1 -1
  110. package/dist/providers/dreamina-provider.d.ts.map +1 -1
  111. package/dist/providers/dreamina-provider.js +54 -72
  112. package/dist/providers/dreamina-provider.js.map +1 -1
  113. package/dist/providers/fake-provider.js +1 -1
  114. package/dist/providers/gemini-provider.d.ts.map +1 -1
  115. package/dist/providers/gemini-provider.js +23 -0
  116. package/dist/providers/gemini-provider.js.map +1 -1
  117. package/dist/providers/meta-transcription.d.ts +1 -5
  118. package/dist/providers/meta-transcription.d.ts.map +1 -1
  119. package/dist/providers/meta-transcription.js +9 -55
  120. package/dist/providers/meta-transcription.js.map +1 -1
  121. package/dist/providers/node-llama-cpp-trending.generated.js +121 -121
  122. package/dist/providers/node-llama-cpp-trending.generated.js.map +1 -1
  123. package/dist/providers/ollama-provider.d.ts.map +1 -1
  124. package/dist/providers/ollama-provider.js +1 -17
  125. package/dist/providers/ollama-provider.js.map +1 -1
  126. package/dist/providers/openai-provider.d.ts +12 -0
  127. package/dist/providers/openai-provider.d.ts.map +1 -1
  128. package/dist/providers/openai-provider.js +27 -2
  129. package/dist/providers/openai-provider.js.map +1 -1
  130. package/dist/providers/openrouter-provider.js +1 -1
  131. package/dist/providers/openrouter-provider.js.map +1 -1
  132. package/dist/providers/requesty-provider.js +1 -1
  133. package/dist/providers/requesty-provider.js.map +1 -1
  134. package/dist/providers/safe-url.d.ts +1 -69
  135. package/dist/providers/safe-url.d.ts.map +1 -1
  136. package/dist/providers/safe-url.js +1 -284
  137. package/dist/providers/safe-url.js.map +1 -1
  138. package/dist/providers/topaz-provider.d.ts +1 -1
  139. package/dist/providers/topaz-provider.js +1 -1
  140. package/dist/providers/video-frame-fallback.d.ts +1 -1
  141. package/dist/providers/video-frame-fallback.js +4 -4
  142. package/dist/providers/video-frame-fallback.js.map +1 -1
  143. package/dist/providers/video-frames.d.ts +6 -16
  144. package/dist/providers/video-frames.d.ts.map +1 -1
  145. package/dist/providers/video-frames.js +48 -116
  146. package/dist/providers/video-frames.js.map +1 -1
  147. package/dist/python-bridge-base.d.ts +2 -0
  148. package/dist/python-bridge-base.d.ts.map +1 -1
  149. package/dist/python-bridge-base.js +9 -26
  150. package/dist/python-bridge-base.js.map +1 -1
  151. package/dist/storage-workspace.d.ts +1 -61
  152. package/dist/storage-workspace.d.ts.map +1 -1
  153. package/dist/storage-workspace.js +2 -430
  154. package/dist/storage-workspace.js.map +1 -1
  155. package/dist/testing.d.ts.map +1 -1
  156. package/dist/testing.js +57 -1
  157. package/dist/testing.js.map +1 -1
  158. package/dist/trim-video-window.d.ts.map +1 -1
  159. package/dist/trim-video-window.js +2 -32
  160. package/dist/trim-video-window.js.map +1 -1
  161. package/dist/workspace.d.ts +1 -118
  162. package/dist/workspace.d.ts.map +1 -1
  163. package/dist/workspace.js +1 -111
  164. package/dist/workspace.js.map +1 -1
  165. package/dist/yt-dlp-format.d.ts +22 -0
  166. package/dist/yt-dlp-format.d.ts.map +1 -0
  167. package/dist/yt-dlp-format.js +90 -0
  168. package/dist/yt-dlp-format.js.map +1 -0
  169. package/package.json +23 -6
@@ -0,0 +1,146 @@
1
+ /**
2
+ * node-av plumbing shared by the media module: logging, encoder lookup,
3
+ * container names and a file muxer that does not leak descriptors.
4
+ */
5
+ import { closeSync, openSync, readSync, writeSync } from "node:fs";
6
+ import path from "node:path";
7
+ import { AV_LOG_ERROR, AVSEEK_CUR, AVSEEK_END, AVSEEK_SET, AVSEEK_SIZE, Codec, Log, Muxer } from "node-av";
8
+ let logLevelSet = false;
9
+ /**
10
+ * Keep libav quiet unless something failed. Its default level prints every
11
+ * encoder's settings banner to stderr, once per open.
12
+ */
13
+ export function quietLibav() {
14
+ if (logLevelSet)
15
+ return;
16
+ logLevelSet = true;
17
+ Log.setLevel(AV_LOG_ERROR);
18
+ }
19
+ export { abortError, throwIfAborted } from "./abort.js";
20
+ /** The encoder named `name`, or `null` when this build has none. */
21
+ export function findEncoder(name) {
22
+ // SAFETY: `FFEncoderCodec` is node-av's list of known encoder names. A name
23
+ // outside it is a lookup that returns null, which is what callers test for.
24
+ return Codec.findEncoderByName(name);
25
+ }
26
+ /** Container short names for the extensions the server writes. */
27
+ const FORMAT_BY_EXTENSION = {
28
+ ".mp4": "mp4",
29
+ ".m4a": "ipod",
30
+ ".mov": "mov",
31
+ ".webm": "webm",
32
+ ".mkv": "matroska",
33
+ ".wav": "wav",
34
+ ".mp3": "mp3",
35
+ ".ogg": "ogg",
36
+ ".opus": "opus",
37
+ ".flac": "flac",
38
+ ".h264": "h264"
39
+ };
40
+ /** The libav muxer name for `filePath`, from its extension. */
41
+ export function muxerFormatFor(filePath) {
42
+ const format = FORMAT_BY_EXTENSION[path.extname(filePath).toLowerCase()];
43
+ if (!format) {
44
+ throw new Error(`No muxer is configured for ${path.basename(filePath)}`);
45
+ }
46
+ return format;
47
+ }
48
+ /**
49
+ * Open a muxer over a file descriptor this module owns.
50
+ *
51
+ * `Muxer.open(path)` leaks one file descriptor and a few hundred kilobytes on
52
+ * every open and close in node-av 6.1.1 (see risk R6 in
53
+ * docs/ffmpeg-in-process-plan.md), so a server that renders all day runs out of
54
+ * descriptors. Custom IO closes cleanly. The callbacks read and write at an
55
+ * explicit position because MP4 and MOV seek back to rewrite their headers.
56
+ *
57
+ * The callbacks are synchronous on purpose. libav calls them from a libuv
58
+ * pool thread that blocks until the JS callback returns; an async `fs` call
59
+ * inside it needs a pool thread of its own, so as many concurrent muxers as
60
+ * the pool has threads (4 by default) deadlocked the process.
61
+ */
62
+ export async function openFileMuxer(filePath, options = {}) {
63
+ const fd = openSync(filePath, "w+");
64
+ let position = 0;
65
+ let size = 0;
66
+ let muxer;
67
+ try {
68
+ muxer = await Muxer.open({
69
+ write: (buffer) => {
70
+ const written = writeSync(fd, buffer, 0, buffer.length, position);
71
+ position += written;
72
+ size = Math.max(size, position);
73
+ return written;
74
+ },
75
+ // `movflags=+faststart` reads the finished file back to move its index
76
+ // to the front.
77
+ read: (length) => {
78
+ const buffer = Buffer.alloc(length);
79
+ const read = readSync(fd, buffer, 0, length, position);
80
+ if (read === 0)
81
+ return null;
82
+ position += read;
83
+ return buffer.subarray(0, read);
84
+ },
85
+ seek: (offset, whence) => {
86
+ const delta = Number(offset);
87
+ if (whence === AVSEEK_SIZE)
88
+ return size;
89
+ if (whence === AVSEEK_SET)
90
+ position = delta;
91
+ else if (whence === AVSEEK_CUR)
92
+ position += delta;
93
+ else if (whence === AVSEEK_END)
94
+ position = size + delta;
95
+ else
96
+ return -1;
97
+ return position;
98
+ }
99
+ }, {
100
+ format: options.format ?? muxerFormatFor(filePath),
101
+ signal: options.signal,
102
+ options: options.muxerOptions,
103
+ // MOV's `+faststart` re-opens the output by name to read it back.
104
+ configure: (context) => {
105
+ context.url = filePath;
106
+ }
107
+ });
108
+ }
109
+ catch (error) {
110
+ closeSync(fd);
111
+ throw error;
112
+ }
113
+ let closing = null;
114
+ return {
115
+ muxer,
116
+ close() {
117
+ closing ??= (async () => {
118
+ try {
119
+ await muxer.close();
120
+ }
121
+ finally {
122
+ closeSync(fd);
123
+ }
124
+ })();
125
+ return closing;
126
+ }
127
+ };
128
+ }
129
+ /** Seconds from a format or stream start time, or 0 when libav has none. */
130
+ export function startTimeSeconds(startTime, timeBase) {
131
+ // AV_NOPTS_VALUE is INT64_MIN.
132
+ if (startTime <= -(2n ** 62n))
133
+ return 0;
134
+ return (Number(startTime) * timeBase.num) / timeBase.den;
135
+ }
136
+ /** A rational for `value`, exact for integer and NTSC-style rates. */
137
+ export function rationalFor(value) {
138
+ if (Number.isInteger(value))
139
+ return { num: value, den: 1 };
140
+ const ntsc = Math.round(value * 1001);
141
+ if (Math.abs(ntsc / 1001 - value) < 1e-9)
142
+ return { num: ntsc, den: 1001 };
143
+ const scaled = Math.round(value * 1000);
144
+ return { num: scaled, den: 1000 };
145
+ }
146
+ //# sourceMappingURL=av.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"av.js","sourceRoot":"","sources":["../../src/media/av.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EACL,YAAY,EACZ,UAAU,EACV,UAAU,EACV,UAAU,EACV,WAAW,EACX,KAAK,EACL,GAAG,EACH,KAAK,EAGN,MAAM,SAAS,CAAC;AAEjB,IAAI,WAAW,GAAG,KAAK,CAAC;AAExB;;;GAGG;AACH,MAAM,UAAU,UAAU;IACxB,IAAI,WAAW;QAAE,OAAO;IACxB,WAAW,GAAG,IAAI,CAAC;IACnB,GAAG,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;AAC7B,CAAC;AAED,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAExD,oEAAoE;AACpE,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,4EAA4E;IAC5E,4EAA4E;IAC5E,OAAO,KAAK,CAAC,iBAAiB,CAAC,IAAsB,CAAC,CAAC;AACzD,CAAC;AAED,kEAAkE;AAClE,MAAM,mBAAmB,GAA2B;IAClD,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,UAAU;IAClB,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,MAAM;CAChB,CAAC;AAEF,+DAA+D;AAC/D,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,MAAM,MAAM,GAAG,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,CAAC;IACzE,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,8BAA8B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAC3E,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AASD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,QAAgB,EAChB,OAAO,GAAqF,EAAE;IAE9F,MAAM,EAAE,GAAG,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACpC,IAAI,QAAQ,GAAG,CAAC,CAAC;IACjB,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,KAAY,CAAC;IACjB,IAAI,CAAC;QACH,KAAK,GAAG,MAAM,KAAK,CAAC,IAAI,CACtB;YACE,KAAK,EAAE,CAAC,MAAc,EAAU,EAAE;gBAChC,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAClE,QAAQ,IAAI,OAAO,CAAC;gBACpB,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAChC,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,uEAAuE;YACvE,gBAAgB;YAChB,IAAI,EAAE,CAAC,MAAc,EAAiB,EAAE;gBACtC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBACpC,MAAM,IAAI,GAAG,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACvD,IAAI,IAAI,KAAK,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAC5B,QAAQ,IAAI,IAAI,CAAC;gBACjB,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAClC,CAAC;YACD,IAAI,EAAE,CAAC,MAAc,EAAE,MAAoB,EAAU,EAAE;gBACrD,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC7B,IAAI,MAAM,KAAK,WAAW;oBAAE,OAAO,IAAI,CAAC;gBACxC,IAAI,MAAM,KAAK,UAAU;oBAAE,QAAQ,GAAG,KAAK,CAAC;qBACvC,IAAI,MAAM,KAAK,UAAU;oBAAE,QAAQ,IAAI,KAAK,CAAC;qBAC7C,IAAI,MAAM,KAAK,UAAU;oBAAE,QAAQ,GAAG,IAAI,GAAG,KAAK,CAAC;;oBACnD,OAAO,CAAC,CAAC,CAAC;gBACf,OAAO,QAAQ,CAAC;YAClB,CAAC;SACF,EACD;YACE,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,cAAc,CAAC,QAAQ,CAAC;YAClD,MAAM,EAAE,OAAO,CAAC,MAAM;YACtB,OAAO,EAAE,OAAO,CAAC,YAAY;YAC7B,kEAAkE;YAClE,SAAS,EAAE,CAAC,OAAO,EAAE,EAAE;gBACrB,OAAO,CAAC,GAAG,GAAG,QAAQ,CAAC;YACzB,CAAC;SACF,CACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,SAAS,CAAC,EAAE,CAAC,CAAC;QACd,MAAM,KAAK,CAAC;IACd,CAAC;IACD,IAAI,OAAO,GAAyB,IAAI,CAAC;IACzC,OAAO;QACL,KAAK;QACL,KAAK;YACH,OAAO,KAAK,CAAC,KAAK,IAAI,EAAE;gBACtB,IAAI,CAAC;oBACH,MAAM,KAAK,CAAC,KAAK,EAAE,CAAC;gBACtB,CAAC;wBAAS,CAAC;oBACT,SAAS,CAAC,EAAE,CAAC,CAAC;gBAChB,CAAC;YACH,CAAC,CAAC,EAAE,CAAC;YACL,OAAO,OAAO,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAAC,SAAiB,EAAE,QAAsC;IACxF,+BAA+B;IAC/B,IAAI,SAAS,IAAI,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC;QAAE,OAAO,CAAC,CAAC;IACxC,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,GAAG,CAAC;AAC3D,CAAC;AAED,sEAAsE;AACtE,MAAM,UAAU,WAAW,CAAC,KAAa;IACvC,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC;QAAE,OAAO,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAC3D,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACtC,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,GAAG,KAAK,CAAC,GAAG,IAAI;QAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;IAC1E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,CAAC;IACxC,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;AACpC,CAAC"}
@@ -0,0 +1,9 @@
1
+ /** What the bundled libav build can do, asked of node-av directly. */
2
+ /**
3
+ * Whether the bundled libav has encoder `name` (`libx264`, `prores_ks`, ...).
4
+ * Replaces scanning `ffmpeg -encoders`.
5
+ */
6
+ export declare function hasEncoder(name: string, signal?: AbortSignal): Promise<boolean>;
7
+ /** Whether the bundled libav has filter `name` (`xfade`, `drawtext`, ...). */
8
+ export declare function hasFilter(name: string, signal?: AbortSignal): Promise<boolean>;
9
+ //# sourceMappingURL=codecs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codecs.d.ts","sourceRoot":"","sources":["../../src/media/codecs.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAMtE;;;GAGG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAGrF;AAED,8EAA8E;AAC9E,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAGpF"}
@@ -0,0 +1,17 @@
1
+ /** What the bundled libav build can do, asked of node-av directly. */
2
+ import { Filter } from "node-av";
3
+ import { findEncoder, throwIfAborted } from "./av.js";
4
+ /**
5
+ * Whether the bundled libav has encoder `name` (`libx264`, `prores_ks`, ...).
6
+ * Replaces scanning `ffmpeg -encoders`.
7
+ */
8
+ export async function hasEncoder(name, signal) {
9
+ throwIfAborted(signal);
10
+ return findEncoder(name) !== null;
11
+ }
12
+ /** Whether the bundled libav has filter `name` (`xfade`, `drawtext`, ...). */
13
+ export async function hasFilter(name, signal) {
14
+ throwIfAborted(signal);
15
+ return Filter.getByName(name) !== null;
16
+ }
17
+ //# sourceMappingURL=codecs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"codecs.js","sourceRoot":"","sources":["../../src/media/codecs.ts"],"names":[],"mappings":"AAAA,sEAAsE;AAEtE,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEjC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAEtD;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAY,EAAE,MAAoB;IACjE,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,WAAW,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AACpC,CAAC;AAED,8EAA8E;AAC9E,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,IAAY,EAAE,MAAoB;IAChE,cAAc,CAAC,MAAM,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC;AACzC,CAAC"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Normalize clips to one frame size, rate and audio format and write them end
3
+ * to end into one file: the in-process form of encoding a segment per clip
4
+ * with `-vf <filter>` and joining them with the concat demuxer and `-c copy`.
5
+ * Doing it in one pass leaves no segment files and no remux.
6
+ */
7
+ import type { VideoEncoderSpec } from "./rgba.js";
8
+ /** One piece of the output, `durationSec` long. */
9
+ export type ConcatSegment = {
10
+ kind: "video";
11
+ filePath: string;
12
+ /** Source seconds to start at (`-ss` before `-i`). */
13
+ inSec?: number;
14
+ /** Source seconds to stop reading at (`-to` before `-i`). */
15
+ outSec?: number;
16
+ durationSec: number;
17
+ /** Use the clip's own sound; otherwise, or when it has none, silence. */
18
+ withAudio: boolean;
19
+ } | {
20
+ kind: "image";
21
+ filePath: string;
22
+ durationSec: number;
23
+ }
24
+ /** Black picture and silence. */
25
+ | {
26
+ kind: "blank";
27
+ durationSec: number;
28
+ };
29
+ export declare function concatSegments(opts: {
30
+ outPath: string;
31
+ width: number;
32
+ height: number;
33
+ fps: number;
34
+ segments: ConcatSegment[];
35
+ /**
36
+ * A `-vf` chain that fits any picture to `width`x`height`, e.g. scale and
37
+ * pad. A video segment is then resampled to `fps`, and every segment
38
+ * converted to the spec's pixel format.
39
+ */
40
+ videoFilter: string;
41
+ video: VideoEncoderSpec;
42
+ audioCodec: string;
43
+ signal?: AbortSignal;
44
+ }): Promise<void>;
45
+ /**
46
+ * Join files whose streams share codec, size and rate without re-encoding:
47
+ * the in-process form of the concat demuxer with `-c copy`. Each file's
48
+ * packets follow the previous file's, offset by where that file ended. The
49
+ * output takes its stream parameters from the first file.
50
+ */
51
+ export declare function concatCopy(opts: {
52
+ inputPaths: string[];
53
+ outPath: string;
54
+ signal?: AbortSignal;
55
+ }): Promise<void>;
56
+ //# sourceMappingURL=concat.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concat.d.ts","sourceRoot":"","sources":["../../src/media/concat.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0BH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAElD,mDAAmD;AACnD,MAAM,MAAM,aAAa,GACrB;IACE,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;CACpB,GACD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE;AAC1D,iCAAiC;GAC/B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC;AAK3C,wBAAsB,cAAc,CAAC,IAAI,EAAE;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B;;;;OAIG;IACH,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,gBAAgB,CAAC;IACxB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CA0NhB;AAED;;;;;GAKG;AACH,wBAAsB,UAAU,CAAC,IAAI,EAAE;IACrC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2DhB"}
@@ -0,0 +1,319 @@
1
+ /**
2
+ * Normalize clips to one frame size, rate and audio format and write them end
3
+ * to end into one file: the in-process form of encoding a segment per clip
4
+ * with `-vf <filter>` and joining them with the concat demuxer and `-c copy`.
5
+ * Doing it in one pass leaves no segment files and no remux.
6
+ */
7
+ import { AV_NOPTS_VALUE, AV_PIX_FMT_RGBA, AV_SAMPLE_FMT_FLT, avChannelLayoutDefault, Demuxer, Encoder, FilterAPI, Frame, Rational } from "node-av";
8
+ import { AudioEncoder } from "./audio-encoder.js";
9
+ import { abortError, findEncoder, openFileMuxer, quietLibav, rationalFor, startTimeSeconds, throwIfAborted } from "./av.js";
10
+ import { openFilterGraph } from "./filter-graph.js";
11
+ const AUDIO_RATE = 48000;
12
+ const AUDIO_CHANNELS = 2;
13
+ export async function concatSegments(opts) {
14
+ const { signal, fps } = opts;
15
+ throwIfAborted(signal);
16
+ quietLibav();
17
+ const codec = findEncoder(opts.video.codec);
18
+ if (!codec)
19
+ throw new Error(`This libav build has no ${opts.video.codec} encoder`);
20
+ const rate = rationalFor(fps);
21
+ const frameTimeBase = new Rational(rate.den, rate.num);
22
+ const output = await openFileMuxer(opts.outPath, { signal });
23
+ let videoEncoder = null;
24
+ let audioEncoder = null;
25
+ try {
26
+ videoEncoder = await Encoder.create(codec, {
27
+ options: opts.video.options,
28
+ context: { framerate: new Rational(rate.num, rate.den) },
29
+ signal
30
+ });
31
+ const videoIndex = output.muxer.addStream(videoEncoder);
32
+ audioEncoder = await AudioEncoder.create(opts.audioCodec, {
33
+ sampleRate: AUDIO_RATE,
34
+ channels: AUDIO_CHANNELS,
35
+ signal
36
+ });
37
+ const audioIndex = output.muxer.addStream(audioEncoder.encoder);
38
+ const activeVideo = videoEncoder;
39
+ const activeAudio = audioEncoder;
40
+ const writeVideoPackets = async (packets) => {
41
+ for (const packet of packets) {
42
+ await output.muxer.writePacket(packet, videoIndex);
43
+ packet.free();
44
+ }
45
+ };
46
+ const writeAudioPackets = async (packets) => {
47
+ for (const packet of packets) {
48
+ await output.muxer.writePacket(packet, audioIndex);
49
+ packet.free();
50
+ }
51
+ };
52
+ let frameIndex = 0;
53
+ let sampleIndex = 0;
54
+ const pixelFilter = `format=${opts.video.pixelFormat}`;
55
+ /** Encode `frame` as the next output frame. */
56
+ const putFrame = async (frame) => {
57
+ frame.pts = BigInt(frameIndex);
58
+ frame.timeBase = frameTimeBase;
59
+ frameIndex += 1;
60
+ await writeVideoPackets(await activeVideo.encodeAll(frame));
61
+ };
62
+ /** Encode silence until the audio reaches the video. */
63
+ const padAudio = async () => {
64
+ const target = Math.round((frameIndex * AUDIO_RATE * rate.den) / rate.num);
65
+ while (sampleIndex < target) {
66
+ const count = Math.min(4096, target - sampleIndex);
67
+ const silence = Frame.fromAudioBuffer(Buffer.alloc(count * AUDIO_CHANNELS * 4), {
68
+ nbSamples: count,
69
+ format: AV_SAMPLE_FMT_FLT,
70
+ sampleRate: AUDIO_RATE,
71
+ channelLayout: avChannelLayoutDefault(AUDIO_CHANNELS),
72
+ timeBase: { num: 1, den: AUDIO_RATE },
73
+ pts: BigInt(sampleIndex)
74
+ });
75
+ try {
76
+ sampleIndex += count;
77
+ await writeAudioPackets(await activeAudio.encode(silence));
78
+ }
79
+ finally {
80
+ silence.free();
81
+ }
82
+ }
83
+ };
84
+ /** A blank frame at the output size, through the same pixel conversion. */
85
+ const blankFrame = () => Frame.fromVideoBuffer(Buffer.alloc(opts.width * opts.height * 4), {
86
+ width: opts.width,
87
+ height: opts.height,
88
+ format: AV_PIX_FMT_RGBA,
89
+ timeBase: frameTimeBase
90
+ });
91
+ for (const segment of opts.segments) {
92
+ if (signal?.aborted)
93
+ throw abortError(signal);
94
+ const frameCount = Math.ceil(segment.durationSec * fps - 1e-9);
95
+ const segmentStart = frameIndex;
96
+ if (segment.kind === "video") {
97
+ const inSec = segment.inSec && segment.inSec > 0 ? segment.inSec : 0;
98
+ const trims = [
99
+ inSec > 0 ? "trim=start=0" : null,
100
+ segment.outSec !== undefined && segment.outSec > inSec
101
+ ? `trim=end=${segment.outSec - inSec}`
102
+ : null
103
+ ].filter((step) => step !== null);
104
+ const run = await openFilterGraph({
105
+ filePath: segment.filePath,
106
+ kind: "video",
107
+ filter: [...trims, opts.videoFilter, `fps=${fps}`, pixelFilter].join(","),
108
+ seekSec: inSec,
109
+ signal
110
+ });
111
+ if (!run)
112
+ throw new Error(`${segment.filePath} has no video stream`);
113
+ try {
114
+ for await (const frame of run.frames()) {
115
+ try {
116
+ if (frameIndex - segmentStart >= frameCount)
117
+ break;
118
+ await putFrame(frame);
119
+ }
120
+ finally {
121
+ frame.free();
122
+ }
123
+ }
124
+ }
125
+ finally {
126
+ await run.close();
127
+ }
128
+ // The segment's sound: the clip's own, trimmed alike and no longer
129
+ // than the picture it got, else silence.
130
+ const pictureSec = (frameIndex - segmentStart) / fps;
131
+ const audio = segment.withAudio && pictureSec > 0
132
+ ? await openFilterGraph({
133
+ filePath: segment.filePath,
134
+ kind: "audio",
135
+ filter: [
136
+ inSec > 0 ? "atrim=start=0" : null,
137
+ segment.outSec !== undefined && segment.outSec > inSec
138
+ ? `atrim=end=${segment.outSec - inSec}`
139
+ : null,
140
+ `atrim=end=${pictureSec}`,
141
+ `aresample=${AUDIO_RATE}`,
142
+ `aformat=sample_fmts=flt:channel_layouts=stereo`
143
+ ]
144
+ .filter((step) => step !== null)
145
+ .join(","),
146
+ seekSec: inSec,
147
+ signal
148
+ })
149
+ : null;
150
+ if (audio) {
151
+ try {
152
+ for await (const frame of audio.frames()) {
153
+ try {
154
+ frame.pts = BigInt(sampleIndex);
155
+ frame.timeBase = new Rational(1, AUDIO_RATE);
156
+ sampleIndex += frame.nbSamples;
157
+ await writeAudioPackets(await activeAudio.encode(frame));
158
+ }
159
+ finally {
160
+ frame.free();
161
+ }
162
+ }
163
+ }
164
+ finally {
165
+ await audio.close();
166
+ }
167
+ }
168
+ await padAudio();
169
+ }
170
+ else if (segment.kind === "image") {
171
+ const still = await openFilterGraph({
172
+ filePath: segment.filePath,
173
+ kind: "video",
174
+ filter: [opts.videoFilter, pixelFilter].join(","),
175
+ signal
176
+ });
177
+ if (!still)
178
+ throw new Error(`${segment.filePath} has no picture`);
179
+ let picture = null;
180
+ try {
181
+ for await (const frame of still.frames()) {
182
+ picture = frame;
183
+ break;
184
+ }
185
+ }
186
+ finally {
187
+ await still.close();
188
+ }
189
+ if (!picture)
190
+ throw new Error(`${segment.filePath} decoded to no picture`);
191
+ try {
192
+ for (let i = 0; i < frameCount; i++) {
193
+ const copy = picture.clone();
194
+ if (!copy)
195
+ throw new Error("Out of memory copying a still");
196
+ try {
197
+ await putFrame(copy);
198
+ }
199
+ finally {
200
+ copy.free();
201
+ }
202
+ }
203
+ }
204
+ finally {
205
+ picture.free();
206
+ }
207
+ await padAudio();
208
+ }
209
+ else {
210
+ const convert = FilterAPI.create(pixelFilter, { signal });
211
+ try {
212
+ for (let i = 0; i < frameCount; i++) {
213
+ const blank = blankFrame();
214
+ try {
215
+ for (const converted of await convert.processAll(blank)) {
216
+ try {
217
+ await putFrame(converted);
218
+ }
219
+ finally {
220
+ converted.free();
221
+ }
222
+ }
223
+ }
224
+ finally {
225
+ blank.free();
226
+ }
227
+ }
228
+ }
229
+ finally {
230
+ convert.close();
231
+ }
232
+ await padAudio();
233
+ }
234
+ }
235
+ if (frameIndex === 0)
236
+ throw new Error("No segment produced a frame");
237
+ await writeVideoPackets(await activeVideo.encodeAll(null));
238
+ await writeAudioPackets(await activeAudio.flush());
239
+ await output.close();
240
+ }
241
+ finally {
242
+ videoEncoder?.close();
243
+ audioEncoder?.close();
244
+ await output.close();
245
+ }
246
+ }
247
+ /**
248
+ * Join files whose streams share codec, size and rate without re-encoding:
249
+ * the in-process form of the concat demuxer with `-c copy`. Each file's
250
+ * packets follow the previous file's, offset by where that file ended. The
251
+ * output takes its stream parameters from the first file.
252
+ */
253
+ export async function concatCopy(opts) {
254
+ const { signal } = opts;
255
+ throwIfAborted(signal);
256
+ quietLibav();
257
+ if (opts.inputPaths.length === 0)
258
+ throw new Error("Nothing to join");
259
+ const output = await openFileMuxer(opts.outPath, { signal });
260
+ try {
261
+ let outVideo = -1;
262
+ let outAudio = -1;
263
+ let offsetSec = 0;
264
+ for (const [fileIndex, inputPath] of opts.inputPaths.entries()) {
265
+ const demuxer = await Demuxer.open(inputPath, { signal });
266
+ try {
267
+ const video = demuxer.video();
268
+ const audio = demuxer.audio();
269
+ if (fileIndex === 0) {
270
+ if (video)
271
+ outVideo = output.muxer.addStream(video);
272
+ if (audio)
273
+ outAudio = output.muxer.addStream(audio);
274
+ }
275
+ const formatStart = startTimeSeconds(demuxer.getFormatContext().startTime, {
276
+ num: 1,
277
+ den: 1_000_000
278
+ });
279
+ let fileEnd = 0;
280
+ for await (const packet of demuxer.packets()) {
281
+ if (!packet)
282
+ continue;
283
+ try {
284
+ if (signal?.aborted)
285
+ throw abortError(signal);
286
+ const target = video && packet.streamIndex === video.index
287
+ ? outVideo
288
+ : audio && packet.streamIndex === audio.index
289
+ ? outAudio
290
+ : -1;
291
+ if (target < 0)
292
+ continue;
293
+ const timeBase = packet.timeBase;
294
+ const shift = BigInt(Math.round(((offsetSec - formatStart) * timeBase.den) / timeBase.num));
295
+ if (packet.pts !== AV_NOPTS_VALUE) {
296
+ fileEnd = Math.max(fileEnd, (Number(packet.pts + packet.duration) * timeBase.num) / timeBase.den - formatStart);
297
+ packet.pts += shift;
298
+ }
299
+ if (packet.dts !== AV_NOPTS_VALUE)
300
+ packet.dts += shift;
301
+ await output.muxer.writePacket(packet, target);
302
+ }
303
+ finally {
304
+ packet.free();
305
+ }
306
+ }
307
+ offsetSec += fileEnd;
308
+ }
309
+ finally {
310
+ await demuxer.close();
311
+ }
312
+ }
313
+ await output.close();
314
+ }
315
+ finally {
316
+ await output.close();
317
+ }
318
+ }
319
+ //# sourceMappingURL=concat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concat.js","sourceRoot":"","sources":["../../src/media/concat.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Whole-file conversions on Mediabunny: trim with re-encode, and audio to WAV.
3
+ * Mediabunny encodes through `@mediabunny/server`, which runs node-av's codecs.
4
+ */
5
+ import type { MediaSource } from "./probe.js";
6
+ /**
7
+ * Register Mediabunny's Node codecs once per process. Hardware acceleration
8
+ * stays off: a server render must not depend on which GPU the host has, and
9
+ * probing every hardware API on each codec open costs time and log noise.
10
+ */
11
+ export declare function ensureMediabunnyServer(): void;
12
+ /**
13
+ * Re-encode `[startSec, endSec)` of `source` as an MP4 that starts at zero,
14
+ * H.264 and AAC with the index at the front: the in-process form of
15
+ * `ffmpeg -i in -ss S -t D -c:v libx264 -c:a aac -movflags +faststart`.
16
+ */
17
+ export declare function trimVideo(source: MediaSource, startSec: number, endSec: number, options?: {
18
+ signal?: AbortSignal;
19
+ }): Promise<Uint8Array>;
20
+ /**
21
+ * Write `source`'s first audio track to `outPath` as 16-bit PCM WAV, at its own
22
+ * rate and channel count unless `sampleRate` or `channels` say otherwise, as
23
+ * `ffmpeg -i in -vn [-ar R] [-ac C] -acodec pcm_s16le out.wav` did. Throws when
24
+ * the source has no audio track.
25
+ */
26
+ export declare function convertAudioToWav(source: MediaSource, outPath: string, options?: {
27
+ sampleRate?: number;
28
+ channels?: number;
29
+ signal?: AbortSignal;
30
+ }): Promise<void>;
31
+ //# sourceMappingURL=convert.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"convert.d.ts","sourceRoot":"","sources":["../../src/media/convert.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAiBH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C;;;;GAIG;AACH,wBAAgB,sBAAsB,IAAI,IAAI,CAI7C;AA6BD;;;;GAIG;AACH,wBAAsB,SAAS,CAC7B,MAAM,EAAE,WAAW,EACnB,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IAAE,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GACrC,OAAO,CAAC,UAAU,CAAC,CAwBrB;AAED;;;;;GAKG;AACH,wBAAsB,iBAAiB,CACrC,MAAM,EAAE,WAAW,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE;IAAE,UAAU,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAO,GAC7E,OAAO,CAAC,IAAI,CAAC,CA2Bf"}