@adminide-stack/yantra-mobile 12.0.121 → 12.0.123-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/lib/features/apps/appArt.js +1 -1
  2. package/lib/features/apps/appArt.js.map +1 -1
  3. package/lib/features/apps/mobileAppCatalog.js +15 -11
  4. package/lib/features/apps/mobileAppCatalog.js.map +1 -1
  5. package/lib/features/canvas/CanvasAgentChatPane.js +82 -20
  6. package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
  7. package/lib/features/canvas/CanvasBoardsGrid.js +291 -100
  8. package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
  9. package/lib/features/canvas/CanvasEditToolsPanel.js +105 -12
  10. package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
  11. package/lib/features/canvas/CanvasExperience.js +266 -68
  12. package/lib/features/canvas/CanvasExperience.js.map +1 -1
  13. package/lib/features/canvas/CanvasGeneratePanel.js +204 -66
  14. package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
  15. package/lib/features/canvas/CanvasLibrarySheet.js +31 -13
  16. package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -1
  17. package/lib/features/canvas/CanvasModelPicker.js +176 -0
  18. package/lib/features/canvas/CanvasModelPicker.js.map +1 -0
  19. package/lib/features/canvas/CanvasTasksPanel.js +325 -29
  20. package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
  21. package/lib/features/canvas/CanvasTemplatesPanel.js +5 -4
  22. package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -1
  23. package/lib/features/canvas/CanvasToolDock.js +137 -61
  24. package/lib/features/canvas/CanvasToolDock.js.map +1 -1
  25. package/lib/features/canvas/FrameExtractorExperience.js +33 -2
  26. package/lib/features/canvas/FrameExtractorExperience.js.map +1 -1
  27. package/lib/features/canvas/GeneratorReferenceSlots.js +197 -0
  28. package/lib/features/canvas/GeneratorReferenceSlots.js.map +1 -0
  29. package/lib/features/canvas/NativeCanvasViewer.js +89 -11
  30. package/lib/features/canvas/NativeCanvasViewer.js.map +1 -1
  31. package/lib/features/canvas/PromoContextFields.js +55 -2
  32. package/lib/features/canvas/PromoContextFields.js.map +1 -1
  33. package/lib/features/canvas/SetStudioExperience.js +323 -13
  34. package/lib/features/canvas/SetStudioExperience.js.map +1 -1
  35. package/lib/features/canvas/VideoEditExperience.js +1 -53
  36. package/lib/features/canvas/VideoEditExperience.js.map +1 -1
  37. package/lib/features/canvas/VideoEditorExperience.js +697 -506
  38. package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
  39. package/lib/features/canvas/VideoGeneratorExperience.js +22 -5
  40. package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
  41. package/lib/features/canvas/canvasAgentChat.js +125 -11
  42. package/lib/features/canvas/canvasAgentChat.js.map +1 -1
  43. package/lib/features/canvas/canvasCore.js +117 -12
  44. package/lib/features/canvas/canvasCore.js.map +1 -1
  45. package/lib/features/canvas/canvasEditOps.js +148 -111
  46. package/lib/features/canvas/canvasEditOps.js.map +1 -1
  47. package/lib/features/canvas/canvasTaskSync.js +235 -0
  48. package/lib/features/canvas/canvasTaskSync.js.map +1 -0
  49. package/lib/features/canvas/canvasTasks.js +98 -11
  50. package/lib/features/canvas/canvasTasks.js.map +1 -1
  51. package/lib/features/canvas/createTiles.js +247 -0
  52. package/lib/features/canvas/createTiles.js.map +1 -0
  53. package/lib/features/canvas/deepLinks.js +83 -0
  54. package/lib/features/canvas/deepLinks.js.map +1 -0
  55. package/lib/features/canvas/frameExtract.js +13 -1
  56. package/lib/features/canvas/frameExtract.js.map +1 -1
  57. package/lib/features/canvas/generationModels.js +36 -8
  58. package/lib/features/canvas/generationModels.js.map +1 -1
  59. package/lib/features/canvas/generatorCommands.js +106 -0
  60. package/lib/features/canvas/generatorCommands.js.map +1 -0
  61. package/lib/features/canvas/generatorReferences.js +82 -0
  62. package/lib/features/canvas/generatorReferences.js.map +1 -0
  63. package/lib/features/canvas/homeWork.js +74 -0
  64. package/lib/features/canvas/homeWork.js.map +1 -0
  65. package/lib/features/canvas/linksRpc.js +130 -0
  66. package/lib/features/canvas/linksRpc.js.map +1 -0
  67. package/lib/features/canvas/mediaRecheck.js +176 -0
  68. package/lib/features/canvas/mediaRecheck.js.map +1 -0
  69. package/lib/features/canvas/mediaUrls.js +258 -0
  70. package/lib/features/canvas/mediaUrls.js.map +1 -0
  71. package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
  72. package/lib/features/canvas/promoProjectImport.js +80 -13
  73. package/lib/features/canvas/promoProjectImport.js.map +1 -1
  74. package/lib/features/canvas/promoVideo.js +106 -15
  75. package/lib/features/canvas/promoVideo.js.map +1 -1
  76. package/lib/features/canvas/reframe.js +228 -0
  77. package/lib/features/canvas/reframe.js.map +1 -0
  78. package/lib/features/canvas/serverTasks.js +697 -0
  79. package/lib/features/canvas/serverTasks.js.map +1 -0
  80. package/lib/features/canvas/set/SetViewportWebView.js +207 -28
  81. package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
  82. package/lib/features/canvas/set/agent/prompt.js +66 -0
  83. package/lib/features/canvas/set/agent/prompt.js.map +1 -0
  84. package/lib/features/canvas/set/agent/setOps.js +203 -0
  85. package/lib/features/canvas/set/agent/setOps.js.map +1 -0
  86. package/lib/features/canvas/set/agent/setTurn.js +128 -0
  87. package/lib/features/canvas/set/agent/setTurn.js.map +1 -0
  88. package/lib/features/canvas/set/agent/snapshot.js +43 -0
  89. package/lib/features/canvas/set/agent/snapshot.js.map +1 -0
  90. package/lib/features/canvas/set/agent/tools.js +580 -0
  91. package/lib/features/canvas/set/agent/tools.js.map +1 -0
  92. package/lib/features/canvas/set/setProject.js +43 -4
  93. package/lib/features/canvas/set/setProject.js.map +1 -1
  94. package/lib/features/canvas/set/supplyLibrary.js +397 -0
  95. package/lib/features/canvas/set/supplyLibrary.js.map +1 -0
  96. package/lib/features/canvas/storageLibrary.js +113 -52
  97. package/lib/features/canvas/storageLibrary.js.map +1 -1
  98. package/lib/features/canvas/studioCatalog.js +15 -2
  99. package/lib/features/canvas/studioCatalog.js.map +1 -1
  100. package/lib/features/canvas/studioLooks.js +1 -8
  101. package/lib/features/canvas/studioLooks.js.map +1 -1
  102. package/lib/features/canvas/useBoardMediaRefresh.js +66 -0
  103. package/lib/features/canvas/useBoardMediaRefresh.js.map +1 -0
  104. package/lib/features/canvas/useMediaSource.js +84 -0
  105. package/lib/features/canvas/useMediaSource.js.map +1 -0
  106. package/lib/features/canvas/video3d.js +11 -10
  107. package/lib/features/canvas/video3d.js.map +1 -1
  108. package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +46 -0
  109. package/lib/features/canvas/videoEditor/BlurBoxOverlay.js.map +1 -0
  110. package/lib/features/canvas/videoEditor/ExportTaskCard.js +134 -0
  111. package/lib/features/canvas/videoEditor/ExportTaskCard.js.map +1 -0
  112. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +45 -7
  113. package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
  114. package/lib/features/canvas/videoEditor/agent/agentLoop.js +4 -2
  115. package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -1
  116. package/lib/features/canvas/videoEditor/agent/attachments.js +304 -0
  117. package/lib/features/canvas/videoEditor/agent/attachments.js.map +1 -0
  118. package/lib/features/canvas/videoEditor/agent/brainClient.js +3 -2
  119. package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -1
  120. package/lib/features/canvas/videoEditor/agent/cutTools.js +207 -7
  121. package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -1
  122. package/lib/features/canvas/videoEditor/blurBox.js +34 -0
  123. package/lib/features/canvas/videoEditor/blurBox.js.map +1 -0
  124. package/lib/features/canvas/videoEditor/compileTimeline.js +668 -0
  125. package/lib/features/canvas/videoEditor/compileTimeline.js.map +1 -0
  126. package/lib/features/canvas/videoEditor/editorModel.js +56 -22
  127. package/lib/features/canvas/videoEditor/editorModel.js.map +1 -1
  128. package/lib/features/canvas/videoEditor/exportPipeline.js +77 -0
  129. package/lib/features/canvas/videoEditor/exportPipeline.js.map +1 -0
  130. package/lib/features/canvas/videoEditor/exportRenderer.js +19 -12
  131. package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -1
  132. package/lib/features/canvas/videoEditor/exportTask.js +216 -0
  133. package/lib/features/canvas/videoEditor/exportTask.js.map +1 -0
  134. package/lib/features/canvas/videoEditor/formWidgets.js +142 -0
  135. package/lib/features/canvas/videoEditor/formWidgets.js.map +1 -0
  136. package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js +195 -0
  137. package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js.map +1 -0
  138. package/lib/features/canvas/videoEditor/produce/produceScenes.js +158 -0
  139. package/lib/features/canvas/videoEditor/produce/produceScenes.js.map +1 -0
  140. package/lib/features/canvas/videoEditor/remoteMediaClient.js +17 -5
  141. package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -1
  142. package/lib/features/canvas/videoEditor/renderTimeline.js +207 -0
  143. package/lib/features/canvas/videoEditor/renderTimeline.js.map +1 -0
  144. package/lib/features/canvas/videoEditor/renewLinks.js +64 -0
  145. package/lib/features/canvas/videoEditor/renewLinks.js.map +1 -0
  146. package/lib/features/canvas/videoEditor/sceneLayers.js +101 -0
  147. package/lib/features/canvas/videoEditor/sceneLayers.js.map +1 -0
  148. package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js +283 -0
  149. package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js.map +1 -0
  150. package/lib/features/canvas/videoEditor/tools/catalog.js +576 -0
  151. package/lib/features/canvas/videoEditor/tools/catalog.js.map +1 -0
  152. package/lib/features/canvas/videoEditor/videoProjectsStore.js +27 -3
  153. package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -1
  154. package/lib/features/webbuilder/WebBuilderExperience.js +29 -1
  155. package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
  156. package/lib/features/webbuilder/buildFragments.js +8 -4
  157. package/lib/features/webbuilder/buildFragments.js.map +1 -1
  158. package/lib/features/webbuilder/codezenHandoff.js +108 -0
  159. package/lib/features/webbuilder/codezenHandoff.js.map +1 -0
  160. package/lib/features/webbuilder/workflow.js.map +1 -1
  161. package/lib/hooks/useChatApi.js +1 -2
  162. package/lib/hooks/useChatApi.js.map +1 -1
  163. package/lib/screens/CanvasBoard/index.js +12 -1
  164. package/lib/screens/CanvasBoard/index.js.map +1 -1
  165. package/lib/screens/Home/HomeScreen.js.map +1 -1
  166. package/lib/screens/Home/components/HomeSuggestions.js +3 -3
  167. package/lib/screens/Home/components/HomeSuggestions.js.map +1 -1
  168. package/lib/screens/WebBuilder/index.js +4 -2
  169. package/lib/screens/WebBuilder/index.js.map +1 -1
  170. package/lib/screens/WebBuilderNative/index.js +29 -2
  171. package/lib/screens/WebBuilderNative/index.js.map +1 -1
  172. package/lib/screens/WebBuilderNative/useWebBuilderHost.js +30 -6
  173. package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
  174. package/package.json +4 -4
  175. /package/lib/assets/apps/{paper2poster.webp → poster.webp} +0 -0
@@ -0,0 +1,576 @@
1
+ import {resultUrl}from'../mediaActions.js';var __defProp = Object.defineProperty;
2
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
3
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
4
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
5
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
6
+ var __spreadValues = (a, b) => {
7
+ for (var prop in b || (b = {}))
8
+ if (__hasOwnProp.call(b, prop))
9
+ __defNormalProp(a, prop, b[prop]);
10
+ if (__getOwnPropSymbols)
11
+ for (var prop of __getOwnPropSymbols(b)) {
12
+ if (__propIsEnum.call(b, prop))
13
+ __defNormalProp(a, prop, b[prop]);
14
+ }
15
+ return a;
16
+ };
17
+ const TOOL_GROUPS = ["Extract", "Convert", "Combine", "Clean up"];
18
+ const one = (...accepts) => [{
19
+ label: "Input",
20
+ accepts
21
+ }];
22
+ const many = (label, accepts, min = 2) => [{
23
+ label,
24
+ accepts,
25
+ many: true,
26
+ min
27
+ }];
28
+ const VIDEO = "yantra-video-editing";
29
+ const AUDIO = "yantra-audio-editing";
30
+ const payload = (raw) => raw.data && typeof raw.data === "object" ? raw.data : raw;
31
+ async function op(ctx, connector, action, src, params) {
32
+ const raw = await ctx.run(connector, action, __spreadValues(__spreadValues({
33
+ input_url: src
34
+ }, params), ctx.keep ? {} : {
35
+ ephemeral: true
36
+ }));
37
+ if (raw.successful === false) throw new Error(String(raw.error || `${action} failed`));
38
+ return resultUrl(payload(raw), action);
39
+ }
40
+ const videoOp = (ctx, action, src, params = {}) => op(ctx, VIDEO, `YANTRA_VIDEO_EDIT_${action}`, src, params);
41
+ const audioOp = (ctx, action, src, params = {}) => op(ctx, AUDIO, `YANTRA_AUDIO_EDIT_${action}`, src, params);
42
+ function baseName(input) {
43
+ return input.name.replace(/\.[^./]+$/, "") || "media";
44
+ }
45
+ function outputName(input, suffix, url, fallbackExt2) {
46
+ var _a, _b;
47
+ const ext = (_b = (_a = /\.([a-z0-9]{2,5})$/i.exec(url.split(/[?#]/)[0])) == null ? void 0 : _a[1]) != null ? _b : fallbackExt2;
48
+ return `${baseName(input)}-${suffix}.${ext.toLowerCase()}`;
49
+ }
50
+ function stamp(secs, sep) {
51
+ const ms = Math.max(0, Math.round(secs * 1e3));
52
+ const two = (n) => String(n).padStart(2, "0");
53
+ return `${two(Math.floor(ms / 36e5))}:${two(Math.floor(ms / 6e4) % 60)}:${two(Math.floor(ms / 1e3) % 60)}${sep}${String(ms % 1e3).padStart(3, "0")}`;
54
+ }
55
+ function formatTranscript(segments, format) {
56
+ if (format === "txt") return `${segments.map((s) => s.text.trim()).join("\n")}
57
+ `;
58
+ const sep = format === "srt" ? "," : ".";
59
+ const cues = segments.map((s, i) => `${format === "srt" ? `${i + 1}
60
+ ` : ""}${stamp(s.start, sep)} --> ${stamp(s.end, sep)}
61
+ ${s.text.trim()}`);
62
+ return `${format === "vtt" ? "WEBVTT\n\n" : ""}${cues.join("\n\n")}
63
+ `;
64
+ }
65
+ function formatBytes(n) {
66
+ return n >= 1048576 ? `${(n / 1048576).toFixed(1)} MB` : `${Math.max(1, Math.round(n / 1024))} KB`;
67
+ }
68
+ function probeRows(info) {
69
+ var _a, _b, _c, _d;
70
+ const durationMs = typeof info.duration_ms === "number" ? info.duration_ms : typeof info.duration === "number" ? info.duration * 1e3 : void 0;
71
+ const rows = [["Duration", durationMs !== void 0 ? `${(durationMs / 1e3).toFixed(2)} s` : void 0], ["Resolution", info.width && info.height ? `${info.width} \xD7 ${info.height}` : void 0], ["Frame rate", info.fps ? `${info.fps} fps` : void 0], ["Video codec", info.video_codec ? String(info.video_codec) : void 0], ["Audio codec", ((_a = info.audio_codec) != null ? _a : info.codec) ? String((_b = info.audio_codec) != null ? _b : info.codec) : void 0], ["Sample rate", info.sample_rate ? `${info.sample_rate} Hz` : void 0], ["Channels", info.channels ? String(info.channels) : void 0], ["Bitrate", typeof info.bitrate === "number" ? `${Math.round(info.bitrate / 1e3)} kbps` : void 0], ["File size", typeof info.size_bytes === "number" ? formatBytes(info.size_bytes) : void 0], ["Container", ((_c = info.format_name) != null ? _c : info.format) ? String((_d = info.format_name) != null ? _d : info.format) : void 0]];
72
+ return rows.filter((r) => r[1] !== void 0);
73
+ }
74
+ const evenDown = (n) => Math.max(2, Math.floor(n / 2) * 2);
75
+ function scaledSize(width, height, shortSide) {
76
+ const scale = Math.min(1, shortSide / Math.min(width, height));
77
+ return {
78
+ width: evenDown(width * scale),
79
+ height: evenDown(height * scale)
80
+ };
81
+ }
82
+ const PLATFORM_FORMATS = [{
83
+ id: "reel",
84
+ ratio: "9:16",
85
+ label: "Reel or Story",
86
+ size: {
87
+ width: 1080,
88
+ height: 1920
89
+ }
90
+ }, {
91
+ id: "feed-post",
92
+ ratio: "4:5",
93
+ label: "Feed post",
94
+ size: {
95
+ width: 1080,
96
+ height: 1350
97
+ }
98
+ }, {
99
+ id: "square-post",
100
+ ratio: "1:1",
101
+ label: "Square post",
102
+ size: {
103
+ width: 1080,
104
+ height: 1080
105
+ }
106
+ }, {
107
+ id: "widescreen",
108
+ ratio: "16:9",
109
+ label: "Widescreen",
110
+ size: {
111
+ width: 1920,
112
+ height: 1080
113
+ }
114
+ }];
115
+ function reframeParams(formatId, fit) {
116
+ var _a;
117
+ const format = (_a = PLATFORM_FORMATS.find((f) => f.id === formatId)) != null ? _a : PLATFORM_FORMATS[0];
118
+ const params = {
119
+ width: format.size.width,
120
+ height: format.size.height,
121
+ fit: fit === "crop" ? "cover" : fit === "stack" ? "stack" : "contain"
122
+ };
123
+ if (fit === "stack" || fit === "match") params.background = "auto";
124
+ else if (fit === "blur") params.background = "blur";
125
+ else if (fit === "black") Object.assign(params, {
126
+ background: "color",
127
+ color: "black"
128
+ });
129
+ else if (fit === "crop") Object.assign(params, {
130
+ focus_x: 0.5,
131
+ focus_y: 0.5
132
+ });
133
+ return params;
134
+ }
135
+ function transcriptSegments(raw) {
136
+ const d = payload(raw);
137
+ const segments = Array.isArray(d.segments) ? d.segments.map((s) => {
138
+ var _a;
139
+ return {
140
+ start: Number(s.start) || 0,
141
+ end: Number(s.end) || 0,
142
+ text: String((_a = s.text) != null ? _a : "")
143
+ };
144
+ }).filter((s) => s.text.trim()) : [];
145
+ if (segments.length) return segments;
146
+ const text = typeof d.text === "string" ? d.text : typeof d.transcript === "string" ? d.transcript : "";
147
+ return text.trim() ? [{
148
+ start: 0,
149
+ end: Number(d.duration) || 0,
150
+ text
151
+ }] : [];
152
+ }
153
+ const fallbackExt = (media) => media.type === "audio" ? "mp3" : "mp4";
154
+ const fileResult = async (media, suffix, url) => {
155
+ const done = await url;
156
+ return {
157
+ kind: "file",
158
+ url: done,
159
+ type: media.type,
160
+ name: outputName(media, suffix, done, fallbackExt(media))
161
+ };
162
+ };
163
+ const LOUDNESS = [{
164
+ value: "-14",
165
+ label: "-14 LUFS, streaming"
166
+ }, {
167
+ value: "-16",
168
+ label: "-16 LUFS, podcast"
169
+ }, {
170
+ value: "-23",
171
+ label: "-23 LUFS, broadcast"
172
+ }];
173
+ const LANGUAGES = [{
174
+ value: "auto",
175
+ label: "Detect"
176
+ }, {
177
+ value: "en",
178
+ label: "English"
179
+ }, {
180
+ value: "hi",
181
+ label: "Hindi"
182
+ }, {
183
+ value: "es",
184
+ label: "Spanish"
185
+ }, {
186
+ value: "fr",
187
+ label: "French"
188
+ }, {
189
+ value: "de",
190
+ label: "German"
191
+ }];
192
+ const TOOLS = [{
193
+ id: "extract-audio",
194
+ group: "Extract",
195
+ label: "Extract audio",
196
+ hint: "Pull the soundtrack out as an audio file",
197
+ inputs: one("video"),
198
+ run: async (ctx, [video]) => {
199
+ const url = await videoOp(ctx, "EXTRACT_AUDIO", video.src);
200
+ return {
201
+ kind: "file",
202
+ url,
203
+ type: "audio",
204
+ name: outputName(video, "audio", url, "mp3")
205
+ };
206
+ }
207
+ }, {
208
+ id: "transcript",
209
+ group: "Extract",
210
+ label: "Transcript",
211
+ hint: "Speech to text, as subtitles (SRT/VTT) or plain text",
212
+ inputs: one("video", "audio"),
213
+ fields: [{
214
+ key: "format",
215
+ label: "Format",
216
+ kind: "select",
217
+ default: "srt",
218
+ options: [{
219
+ value: "srt",
220
+ label: "SRT"
221
+ }, {
222
+ value: "vtt",
223
+ label: "WebVTT"
224
+ }, {
225
+ value: "txt",
226
+ label: "Plain text"
227
+ }]
228
+ }, {
229
+ key: "language",
230
+ label: "Language",
231
+ kind: "select",
232
+ default: "auto",
233
+ options: LANGUAGES
234
+ }],
235
+ run: async (ctx, [media], values) => {
236
+ const language = values.language === "auto" ? void 0 : String(values.language);
237
+ const raw = await ctx.run("yantra-video-clip", "YANTRA_VIDEO_CLIP_TRANSCRIBE", __spreadValues({
238
+ video_url: media.src
239
+ }, language ? {
240
+ language
241
+ } : {}));
242
+ if (raw.successful === false) throw new Error(String(raw.error || "Transcribe failed"));
243
+ const segments = transcriptSegments(raw);
244
+ if (!segments.length) throw new Error("No speech was found in this clip.");
245
+ const format = values.format;
246
+ return {
247
+ kind: "text",
248
+ text: formatTranscript(segments, format),
249
+ name: outputName(media, "transcript", "", format)
250
+ };
251
+ }
252
+ }, {
253
+ id: "media-info",
254
+ group: "Extract",
255
+ label: "Media info",
256
+ hint: "Duration, resolution, codecs and size",
257
+ inputs: one("video", "audio"),
258
+ // The audio probe reads video files too (web: the video probe's binary is missing on the pod).
259
+ run: async (ctx, [media]) => {
260
+ const raw = await ctx.run(AUDIO, "YANTRA_AUDIO_EDIT_PROBE", {
261
+ input_url: media.src
262
+ });
263
+ if (raw.successful === false) throw new Error(String(raw.error || "Probe failed"));
264
+ return {
265
+ kind: "info",
266
+ rows: probeRows(payload(raw))
267
+ };
268
+ }
269
+ }, {
270
+ id: "thumbnail",
271
+ group: "Extract",
272
+ label: "Frame at time",
273
+ hint: "One still from an exact moment",
274
+ inputs: one("video"),
275
+ fields: [{
276
+ key: "time",
277
+ label: "Time",
278
+ kind: "number",
279
+ default: 0,
280
+ min: 0,
281
+ step: 0.5,
282
+ unit: "s"
283
+ }],
284
+ run: async (ctx, [video], values) => {
285
+ const time = Number(values.time);
286
+ const url = await videoOp(ctx, "THUMBNAIL", video.src, {
287
+ time_secs: time
288
+ });
289
+ return {
290
+ kind: "file",
291
+ url,
292
+ type: "image",
293
+ name: outputName(video, `${time}s`, url, "jpg")
294
+ };
295
+ }
296
+ }, {
297
+ id: "gif",
298
+ group: "Extract",
299
+ label: "GIF",
300
+ hint: "Turn a clip into an animated GIF",
301
+ inputs: one("video"),
302
+ fields: [{
303
+ key: "fps",
304
+ label: "Frame rate",
305
+ kind: "number",
306
+ default: 12,
307
+ min: 1,
308
+ max: 30,
309
+ step: 1,
310
+ unit: "fps"
311
+ }, {
312
+ key: "width",
313
+ label: "Width",
314
+ kind: "number",
315
+ default: 480,
316
+ min: 120,
317
+ max: 1280,
318
+ step: 40,
319
+ unit: "px"
320
+ }],
321
+ run: async (ctx, [video], values) => {
322
+ const url = await videoOp(ctx, "GIF_EXPORT", video.src, {
323
+ fps: Number(values.fps),
324
+ width: Number(values.width)
325
+ });
326
+ return {
327
+ kind: "file",
328
+ url,
329
+ type: "image",
330
+ name: outputName(video, "gif", url, "gif")
331
+ };
332
+ }
333
+ }, {
334
+ id: "contact-sheet",
335
+ group: "Extract",
336
+ label: "Contact sheet",
337
+ hint: "A grid of stills across the whole clip",
338
+ inputs: one("video"),
339
+ fields: [{
340
+ key: "cols",
341
+ label: "Columns",
342
+ kind: "number",
343
+ default: 4,
344
+ min: 1,
345
+ max: 8,
346
+ step: 1
347
+ }, {
348
+ key: "rows",
349
+ label: "Rows",
350
+ kind: "number",
351
+ default: 4,
352
+ min: 1,
353
+ max: 8,
354
+ step: 1
355
+ }],
356
+ run: async (ctx, [video], values) => {
357
+ const url = await videoOp(ctx, "CONTACT_SHEET", video.src, {
358
+ cols: Number(values.cols),
359
+ rows: Number(values.rows),
360
+ thumb_width: 320
361
+ });
362
+ return {
363
+ kind: "file",
364
+ url,
365
+ type: "image",
366
+ name: outputName(video, "sheet", url, "jpg")
367
+ };
368
+ }
369
+ }, {
370
+ id: "compress",
371
+ group: "Convert",
372
+ label: "Compress / resize",
373
+ hint: "A smaller file, optionally a smaller frame",
374
+ inputs: one("video"),
375
+ fields: [{
376
+ key: "size",
377
+ label: "Size",
378
+ kind: "select",
379
+ default: "720",
380
+ options: [{
381
+ value: "original",
382
+ label: "Keep size"
383
+ }, {
384
+ value: "1080",
385
+ label: "1080p"
386
+ }, {
387
+ value: "720",
388
+ label: "720p"
389
+ }, {
390
+ value: "480",
391
+ label: "480p"
392
+ }]
393
+ }, {
394
+ key: "codec",
395
+ label: "Codec",
396
+ kind: "select",
397
+ default: "h264",
398
+ options: [{
399
+ value: "h264",
400
+ label: "H.264"
401
+ }, {
402
+ value: "hevc",
403
+ label: "H.265 (smaller)"
404
+ }]
405
+ }],
406
+ run: async (ctx, [video], values) => {
407
+ const params = {
408
+ codec: values.codec
409
+ };
410
+ if (values.size !== "original") {
411
+ const raw = await ctx.run(AUDIO, "YANTRA_AUDIO_EDIT_PROBE", {
412
+ input_url: video.src
413
+ });
414
+ const info = payload(raw);
415
+ const width = Number(info.width);
416
+ const height = Number(info.height);
417
+ if (!(width > 0 && height > 0)) throw new Error("Could not read the video's frame size");
418
+ const size = scaledSize(width, height, Number(values.size));
419
+ params.resolution = `${size.width}x${size.height}`;
420
+ }
421
+ return fileResult(video, "compressed", videoOp(ctx, "TRANSCODE", video.src, params));
422
+ }
423
+ }, {
424
+ id: "audio-format",
425
+ group: "Convert",
426
+ label: "Convert audio",
427
+ hint: "Change an audio file's format, or pull a video's sound into one",
428
+ inputs: one("audio", "video"),
429
+ fields: [{
430
+ key: "format",
431
+ label: "Format",
432
+ kind: "select",
433
+ default: "mp3",
434
+ options: ["mp3", "wav", "m4a", "ogg", "flac"].map((f) => ({
435
+ value: f,
436
+ label: f.toUpperCase()
437
+ }))
438
+ }],
439
+ run: async (ctx, [media], values) => {
440
+ const url = await audioOp(ctx, "CONVERT", media.src, {
441
+ format: values.format
442
+ });
443
+ return {
444
+ kind: "file",
445
+ url,
446
+ type: "audio",
447
+ name: outputName(media, "converted", url, String(values.format))
448
+ };
449
+ }
450
+ }, {
451
+ id: "aspect",
452
+ group: "Convert",
453
+ label: "Change aspect",
454
+ hint: "Resize for a Reel, a feed post or YouTube, at the size each one asks for",
455
+ inputs: one("video"),
456
+ fields: [{
457
+ key: "format",
458
+ label: "For",
459
+ kind: "select",
460
+ default: "reel",
461
+ options: PLATFORM_FORMATS.map((f) => ({
462
+ value: f.id,
463
+ label: `${f.label} \xB7 ${f.ratio}`
464
+ }))
465
+ }, {
466
+ key: "fit",
467
+ label: "Fit",
468
+ kind: "select",
469
+ default: "match",
470
+ options: [{
471
+ value: "match",
472
+ label: "Fit, backdrop in the bars"
473
+ }, {
474
+ value: "blur",
475
+ label: "Fit, blurred bars"
476
+ }, {
477
+ value: "black",
478
+ label: "Fit, black bars"
479
+ }, {
480
+ value: "crop",
481
+ label: "Crop to fill"
482
+ }, {
483
+ value: "stack",
484
+ label: "Stack for vertical"
485
+ }]
486
+ }],
487
+ run: async (ctx, [video], values) => fileResult(video, String(values.format), videoOp(ctx, "REFRAME", video.src, reframeParams(String(values.format), values.fit)))
488
+ }, {
489
+ id: "merge-video",
490
+ group: "Combine",
491
+ label: "Merge videos",
492
+ hint: "Join clips end to end, in order",
493
+ inputs: many("Clips", ["video"]),
494
+ run: async (ctx, [first, ...rest]) => fileResult(first, "merged", videoOp(ctx, "CONCAT", first.src, {
495
+ input_urls: rest.map((c) => c.src),
496
+ reencode: true
497
+ }))
498
+ }, {
499
+ id: "merge-audio",
500
+ group: "Combine",
501
+ label: "Merge audio",
502
+ hint: "Join tracks end to end, in order",
503
+ inputs: many("Tracks", ["audio"]),
504
+ fields: [{
505
+ key: "crossfade",
506
+ label: "Crossfade",
507
+ kind: "number",
508
+ default: 0,
509
+ min: 0,
510
+ max: 5e3,
511
+ step: 250,
512
+ unit: "ms"
513
+ }],
514
+ run: async (ctx, [first, ...rest], values) => fileResult(first, "merged", audioOp(ctx, "CONCAT", first.src, {
515
+ input_urls: rest.map((c) => c.src),
516
+ crossfade_ms: Number(values.crossfade)
517
+ }))
518
+ }, {
519
+ id: "mix-audio",
520
+ group: "Combine",
521
+ label: "Mix audio",
522
+ hint: "Layer tracks on top of each other",
523
+ inputs: many("Tracks", ["audio"]),
524
+ fields: [{
525
+ key: "duration",
526
+ label: "Length",
527
+ kind: "select",
528
+ default: "longest",
529
+ options: [{
530
+ value: "longest",
531
+ label: "Longest"
532
+ }, {
533
+ value: "shortest",
534
+ label: "Shortest"
535
+ }, {
536
+ value: "first",
537
+ label: "First track"
538
+ }]
539
+ }],
540
+ run: async (ctx, [first, ...rest], values) => fileResult(first, "mix", audioOp(ctx, "MIX", first.src, {
541
+ input_urls: rest.map((c) => c.src),
542
+ duration: values.duration,
543
+ normalize: true
544
+ }))
545
+ }, {
546
+ id: "normalize",
547
+ group: "Clean up",
548
+ label: "Normalize loudness",
549
+ hint: "Even out the volume to a standard level",
550
+ inputs: one("video", "audio"),
551
+ fields: [{
552
+ key: "target",
553
+ label: "Target",
554
+ kind: "select",
555
+ default: "-14",
556
+ options: LOUDNESS
557
+ }],
558
+ run: async (ctx, [media], values) => {
559
+ const params = {
560
+ i: Number(values.target)
561
+ };
562
+ return fileResult(media, "normalized", media.type === "audio" ? audioOp(ctx, "NORMALIZE", media.src, params) : videoOp(ctx, "AUDIO_NORMALIZE", media.src, params));
563
+ }
564
+ }];
565
+ function defaultValues(tool) {
566
+ var _a;
567
+ return Object.fromEntries(((_a = tool.fields) != null ? _a : []).map((f) => [f.key, f.default]));
568
+ }
569
+ function inputsReady(tool, chosen) {
570
+ return tool.inputs.every((slot, i) => {
571
+ var _a, _b;
572
+ const picked = (_a = chosen[i]) != null ? _a : [];
573
+ const ok = picked.every((p) => slot.accepts.includes(p.type));
574
+ return ok && (slot.many ? picked.length >= ((_b = slot.min) != null ? _b : 2) : picked.length === 1);
575
+ });
576
+ }export{PLATFORM_FORMATS,TOOLS,TOOL_GROUPS,baseName,defaultValues,formatTranscript,inputsReady,outputName,probeRows,reframeParams,scaledSize,transcriptSegments};//# sourceMappingURL=catalog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalog.js","sources":["../../../../../src/features/canvas/videoEditor/tools/catalog.ts"],"sourcesContent":["/**\n * The editor's Tools drawer - native twin of web editors/video-editor/tools/catalog.ts.\n * Pure data + param builders (tested); each tool's `run` drives connector ops\n * through the host RunMediaAction. One-off utilities on library media, not\n * timeline edits: their results land back in the editor's media library.\n */\nimport { resultUrl, type RunMediaAction } from '../mediaActions';\n\nexport type MediaKind = 'video' | 'audio' | 'image';\n\nexport interface ToolInput {\n src: string;\n name: string;\n type: MediaKind;\n}\n\nexport type ToolField =\n | {\n key: string;\n label: string;\n kind: 'number';\n default: number;\n min?: number;\n max?: number;\n step?: number;\n unit?: string;\n }\n | { key: string; label: string; kind: 'select'; default: string; options: Array<{ value: string; label: string }> }\n | { key: string; label: string; kind: 'toggle'; default: boolean };\n\nexport type ToolValues = Record<string, number | string | boolean>;\n\nexport type ToolResult =\n | { kind: 'file'; url: string; name: string; type: MediaKind }\n | { kind: 'text'; text: string; name: string }\n | { kind: 'info'; rows: Array<[string, string]> };\n\nexport type ToolGroup = 'Extract' | 'Convert' | 'Combine' | 'Clean up';\nexport const TOOL_GROUPS: ToolGroup[] = ['Extract', 'Convert', 'Combine', 'Clean up'];\n\nexport interface InputSlot {\n label: string;\n accepts: MediaKind[];\n many?: boolean;\n min?: number;\n}\n\nexport interface ToolContext {\n run: RunMediaAction;\n /** false sends `ephemeral`, so the output stays out of the library listing. */\n keep: boolean;\n}\n\nexport interface ToolDef {\n id: string;\n group: ToolGroup;\n label: string;\n hint: string;\n inputs: InputSlot[];\n fields?: ToolField[];\n run: (ctx: ToolContext, inputs: ToolInput[], values: ToolValues) => Promise<ToolResult>;\n}\n\nconst one = (...accepts: MediaKind[]): InputSlot[] => [{ label: 'Input', accepts }];\nconst many = (label: string, accepts: MediaKind[], min = 2): InputSlot[] => [{ label, accepts, many: true, min }];\n\nconst VIDEO = 'yantra-video-editing';\nconst AUDIO = 'yantra-audio-editing';\n\nconst payload = (raw: Record<string, unknown>): Record<string, unknown> =>\n (raw.data && typeof raw.data === 'object' ? raw.data : raw) as Record<string, unknown>;\n\nasync function op(\n ctx: ToolContext,\n connector: typeof VIDEO | typeof AUDIO,\n action: string,\n src: string,\n params: Record<string, unknown>,\n): Promise<string> {\n const raw = await ctx.run(connector, action, {\n input_url: src,\n ...params,\n ...(ctx.keep ? {} : { ephemeral: true }),\n });\n if (raw.successful === false) throw new Error(String(raw.error || `${action} failed`));\n return resultUrl(payload(raw), action);\n}\n\nconst videoOp = (ctx: ToolContext, action: string, src: string, params: Record<string, unknown> = {}) =>\n op(ctx, VIDEO, `YANTRA_VIDEO_EDIT_${action}`, src, params);\nconst audioOp = (ctx: ToolContext, action: string, src: string, params: Record<string, unknown> = {}) =>\n op(ctx, AUDIO, `YANTRA_AUDIO_EDIT_${action}`, src, params);\n\n// ── Pure helpers (exported for tests) ──────────────────────────────────────\n\nexport function baseName(input: Pick<ToolInput, 'name'>): string {\n return input.name.replace(/\\.[^./]+$/, '') || 'media';\n}\n\nexport function outputName(input: Pick<ToolInput, 'name'>, suffix: string, url: string, fallbackExt: string): string {\n const ext = /\\.([a-z0-9]{2,5})$/i.exec(url.split(/[?#]/)[0])?.[1] ?? fallbackExt;\n return `${baseName(input)}-${suffix}.${ext.toLowerCase()}`;\n}\n\nexport interface TranscriptSegment {\n start: number;\n end: number;\n text: string;\n}\nexport type TranscriptFormat = 'txt' | 'srt' | 'vtt';\n\nfunction stamp(secs: number, sep: ',' | '.'): string {\n const ms = Math.max(0, Math.round(secs * 1000));\n const two = (n: number) => String(n).padStart(2, '0');\n return `${two(Math.floor(ms / 3_600_000))}:${two(Math.floor(ms / 60_000) % 60)}:${two(Math.floor(ms / 1000) % 60)}${sep}${String(ms % 1000).padStart(3, '0')}`;\n}\n\nexport function formatTranscript(segments: TranscriptSegment[], format: TranscriptFormat): string {\n if (format === 'txt') return `${segments.map((s) => s.text.trim()).join('\\n')}\\n`;\n const sep = format === 'srt' ? ',' : '.';\n const cues = segments.map(\n (s, i) =>\n `${format === 'srt' ? `${i + 1}\\n` : ''}${stamp(s.start, sep)} --> ${stamp(s.end, sep)}\\n${s.text.trim()}`,\n );\n return `${format === 'vtt' ? 'WEBVTT\\n\\n' : ''}${cues.join('\\n\\n')}\\n`;\n}\n\nfunction formatBytes(n: number): string {\n return n >= 1_048_576 ? `${(n / 1_048_576).toFixed(1)} MB` : `${Math.max(1, Math.round(n / 1024))} KB`;\n}\n\nexport function probeRows(info: Record<string, unknown>): Array<[string, string]> {\n const durationMs =\n typeof info.duration_ms === 'number'\n ? info.duration_ms\n : typeof info.duration === 'number'\n ? info.duration * 1000\n : undefined;\n const rows: Array<[string, string | undefined]> = [\n ['Duration', durationMs !== undefined ? `${(durationMs / 1000).toFixed(2)} s` : undefined],\n ['Resolution', info.width && info.height ? `${info.width} × ${info.height}` : undefined],\n ['Frame rate', info.fps ? `${info.fps} fps` : undefined],\n ['Video codec', info.video_codec ? String(info.video_codec) : undefined],\n ['Audio codec', (info.audio_codec ?? info.codec) ? String(info.audio_codec ?? info.codec) : undefined],\n ['Sample rate', info.sample_rate ? `${info.sample_rate} Hz` : undefined],\n ['Channels', info.channels ? String(info.channels) : undefined],\n ['Bitrate', typeof info.bitrate === 'number' ? `${Math.round(info.bitrate / 1000)} kbps` : undefined],\n ['File size', typeof info.size_bytes === 'number' ? formatBytes(info.size_bytes) : undefined],\n ['Container', (info.format_name ?? info.format) ? String(info.format_name ?? info.format) : undefined],\n ];\n return rows.filter((r): r is [string, string] => r[1] !== undefined);\n}\n\nconst evenDown = (n: number) => Math.max(2, Math.floor(n / 2) * 2);\n\n/** Scale so the short side is at most `shortSide`, on even pixels. */\nexport function scaledSize(width: number, height: number, shortSide: number): { width: number; height: number } {\n const scale = Math.min(1, shortSide / Math.min(width, height));\n return { width: evenDown(width * scale), height: evenDown(height * scale) };\n}\n\n/** web PLATFORM_FORMATS - the sizes each platform asks for. */\nexport const PLATFORM_FORMATS = [\n { id: 'reel', ratio: '9:16', label: 'Reel or Story', size: { width: 1080, height: 1920 } },\n { id: 'feed-post', ratio: '4:5', label: 'Feed post', size: { width: 1080, height: 1350 } },\n { id: 'square-post', ratio: '1:1', label: 'Square post', size: { width: 1080, height: 1080 } },\n { id: 'widescreen', ratio: '16:9', label: 'Widescreen', size: { width: 1920, height: 1080 } },\n] as const;\n\nexport type AspectFit = 'stack' | 'match' | 'blur' | 'black' | 'crop';\n\n/** YANTRA_VIDEO_EDIT_REFRAME params for a platform + fit (web reframeClipParams, centred). */\nexport function reframeParams(formatId: string, fit: AspectFit): Record<string, unknown> {\n const format = PLATFORM_FORMATS.find((f) => f.id === formatId) ?? PLATFORM_FORMATS[0];\n const params: Record<string, unknown> = {\n width: format.size.width,\n height: format.size.height,\n fit: fit === 'crop' ? 'cover' : fit === 'stack' ? 'stack' : 'contain',\n };\n if (fit === 'stack' || fit === 'match') params.background = 'auto';\n else if (fit === 'blur') params.background = 'blur';\n else if (fit === 'black') Object.assign(params, { background: 'color', color: 'black' });\n else if (fit === 'crop') Object.assign(params, { focus_x: 0.5, focus_y: 0.5 });\n return params;\n}\n\n/** Read transcript segments from a TRANSCRIBE answer (video-clip `segments`, or a bare `text`). */\nexport function transcriptSegments(raw: Record<string, unknown>): TranscriptSegment[] {\n const d = payload(raw);\n const segments = Array.isArray(d.segments)\n ? (d.segments as Array<Record<string, unknown>>)\n .map((s) => ({ start: Number(s.start) || 0, end: Number(s.end) || 0, text: String(s.text ?? '') }))\n .filter((s) => s.text.trim())\n : [];\n if (segments.length) return segments;\n const text = typeof d.text === 'string' ? d.text : typeof d.transcript === 'string' ? d.transcript : '';\n return text.trim() ? [{ start: 0, end: Number(d.duration) || 0, text }] : [];\n}\n\nconst fallbackExt = (media: ToolInput) => (media.type === 'audio' ? 'mp3' : 'mp4');\nconst fileResult = async (media: ToolInput, suffix: string, url: Promise<string>): Promise<ToolResult> => {\n const done = await url;\n return { kind: 'file', url: done, type: media.type, name: outputName(media, suffix, done, fallbackExt(media)) };\n};\n\nconst LOUDNESS = [\n { value: '-14', label: '-14 LUFS, streaming' },\n { value: '-16', label: '-16 LUFS, podcast' },\n { value: '-23', label: '-23 LUFS, broadcast' },\n];\n\nconst LANGUAGES = [\n { value: 'auto', label: 'Detect' },\n { value: 'en', label: 'English' },\n { value: 'hi', label: 'Hindi' },\n { value: 'es', label: 'Spanish' },\n { value: 'fr', label: 'French' },\n { value: 'de', label: 'German' },\n];\n\nexport const TOOLS: ToolDef[] = [\n {\n id: 'extract-audio',\n group: 'Extract',\n label: 'Extract audio',\n hint: 'Pull the soundtrack out as an audio file',\n inputs: one('video'),\n run: async (ctx, [video]) => {\n const url = await videoOp(ctx, 'EXTRACT_AUDIO', video.src);\n return { kind: 'file', url, type: 'audio', name: outputName(video, 'audio', url, 'mp3') };\n },\n },\n {\n id: 'transcript',\n group: 'Extract',\n label: 'Transcript',\n hint: 'Speech to text, as subtitles (SRT/VTT) or plain text',\n inputs: one('video', 'audio'),\n fields: [\n {\n key: 'format',\n label: 'Format',\n kind: 'select',\n default: 'srt',\n options: [\n { value: 'srt', label: 'SRT' },\n { value: 'vtt', label: 'WebVTT' },\n { value: 'txt', label: 'Plain text' },\n ],\n },\n { key: 'language', label: 'Language', kind: 'select', default: 'auto', options: LANGUAGES },\n ],\n run: async (ctx, [media], values) => {\n const language = values.language === 'auto' ? undefined : String(values.language);\n const raw = await ctx.run('yantra-video-clip', 'YANTRA_VIDEO_CLIP_TRANSCRIBE', {\n video_url: media.src,\n ...(language ? { language } : {}),\n });\n if (raw.successful === false) throw new Error(String(raw.error || 'Transcribe failed'));\n const segments = transcriptSegments(raw);\n if (!segments.length) throw new Error('No speech was found in this clip.');\n const format = values.format as TranscriptFormat;\n return {\n kind: 'text',\n text: formatTranscript(segments, format),\n name: outputName(media, 'transcript', '', format),\n };\n },\n },\n {\n id: 'media-info',\n group: 'Extract',\n label: 'Media info',\n hint: 'Duration, resolution, codecs and size',\n inputs: one('video', 'audio'),\n // The audio probe reads video files too (web: the video probe's binary is missing on the pod).\n run: async (ctx, [media]) => {\n const raw = await ctx.run(AUDIO, 'YANTRA_AUDIO_EDIT_PROBE', { input_url: media.src });\n if (raw.successful === false) throw new Error(String(raw.error || 'Probe failed'));\n return { kind: 'info', rows: probeRows(payload(raw)) };\n },\n },\n {\n id: 'thumbnail',\n group: 'Extract',\n label: 'Frame at time',\n hint: 'One still from an exact moment',\n inputs: one('video'),\n fields: [{ key: 'time', label: 'Time', kind: 'number', default: 0, min: 0, step: 0.5, unit: 's' }],\n run: async (ctx, [video], values) => {\n const time = Number(values.time);\n const url = await videoOp(ctx, 'THUMBNAIL', video.src, { time_secs: time });\n return { kind: 'file', url, type: 'image', name: outputName(video, `${time}s`, url, 'jpg') };\n },\n },\n {\n id: 'gif',\n group: 'Extract',\n label: 'GIF',\n hint: 'Turn a clip into an animated GIF',\n inputs: one('video'),\n fields: [\n { key: 'fps', label: 'Frame rate', kind: 'number', default: 12, min: 1, max: 30, step: 1, unit: 'fps' },\n { key: 'width', label: 'Width', kind: 'number', default: 480, min: 120, max: 1280, step: 40, unit: 'px' },\n ],\n run: async (ctx, [video], values) => {\n const url = await videoOp(ctx, 'GIF_EXPORT', video.src, {\n fps: Number(values.fps),\n width: Number(values.width),\n });\n return { kind: 'file', url, type: 'image', name: outputName(video, 'gif', url, 'gif') };\n },\n },\n {\n id: 'contact-sheet',\n group: 'Extract',\n label: 'Contact sheet',\n hint: 'A grid of stills across the whole clip',\n inputs: one('video'),\n fields: [\n { key: 'cols', label: 'Columns', kind: 'number', default: 4, min: 1, max: 8, step: 1 },\n { key: 'rows', label: 'Rows', kind: 'number', default: 4, min: 1, max: 8, step: 1 },\n ],\n run: async (ctx, [video], values) => {\n const url = await videoOp(ctx, 'CONTACT_SHEET', video.src, {\n cols: Number(values.cols),\n rows: Number(values.rows),\n thumb_width: 320,\n });\n return { kind: 'file', url, type: 'image', name: outputName(video, 'sheet', url, 'jpg') };\n },\n },\n {\n id: 'compress',\n group: 'Convert',\n label: 'Compress / resize',\n hint: 'A smaller file, optionally a smaller frame',\n inputs: one('video'),\n fields: [\n {\n key: 'size',\n label: 'Size',\n kind: 'select',\n default: '720',\n options: [\n { value: 'original', label: 'Keep size' },\n { value: '1080', label: '1080p' },\n { value: '720', label: '720p' },\n { value: '480', label: '480p' },\n ],\n },\n {\n key: 'codec',\n label: 'Codec',\n kind: 'select',\n default: 'h264',\n options: [\n { value: 'h264', label: 'H.264' },\n { value: 'hevc', label: 'H.265 (smaller)' },\n ],\n },\n ],\n run: async (ctx, [video], values) => {\n const params: Record<string, unknown> = { codec: values.codec };\n if (values.size !== 'original') {\n const raw = await ctx.run(AUDIO, 'YANTRA_AUDIO_EDIT_PROBE', { input_url: video.src });\n const info = payload(raw);\n const width = Number(info.width);\n const height = Number(info.height);\n if (!(width > 0 && height > 0)) throw new Error(\"Could not read the video's frame size\");\n const size = scaledSize(width, height, Number(values.size));\n params.resolution = `${size.width}x${size.height}`;\n }\n return fileResult(video, 'compressed', videoOp(ctx, 'TRANSCODE', video.src, params));\n },\n },\n {\n id: 'audio-format',\n group: 'Convert',\n label: 'Convert audio',\n hint: \"Change an audio file's format, or pull a video's sound into one\",\n inputs: one('audio', 'video'),\n fields: [\n {\n key: 'format',\n label: 'Format',\n kind: 'select',\n default: 'mp3',\n options: ['mp3', 'wav', 'm4a', 'ogg', 'flac'].map((f) => ({ value: f, label: f.toUpperCase() })),\n },\n ],\n run: async (ctx, [media], values) => {\n const url = await audioOp(ctx, 'CONVERT', media.src, { format: values.format });\n return {\n kind: 'file',\n url,\n type: 'audio',\n name: outputName(media, 'converted', url, String(values.format)),\n };\n },\n },\n {\n id: 'aspect',\n group: 'Convert',\n label: 'Change aspect',\n hint: 'Resize for a Reel, a feed post or YouTube, at the size each one asks for',\n inputs: one('video'),\n fields: [\n {\n key: 'format',\n label: 'For',\n kind: 'select',\n default: 'reel',\n options: PLATFORM_FORMATS.map((f) => ({ value: f.id, label: `${f.label} · ${f.ratio}` })),\n },\n {\n key: 'fit',\n label: 'Fit',\n kind: 'select',\n default: 'match',\n options: [\n { value: 'match', label: 'Fit, backdrop in the bars' },\n { value: 'blur', label: 'Fit, blurred bars' },\n { value: 'black', label: 'Fit, black bars' },\n { value: 'crop', label: 'Crop to fill' },\n { value: 'stack', label: 'Stack for vertical' },\n ],\n },\n ],\n run: async (ctx, [video], values) =>\n fileResult(\n video,\n String(values.format),\n videoOp(ctx, 'REFRAME', video.src, reframeParams(String(values.format), values.fit as AspectFit)),\n ),\n },\n {\n id: 'merge-video',\n group: 'Combine',\n label: 'Merge videos',\n hint: 'Join clips end to end, in order',\n inputs: many('Clips', ['video']),\n run: async (ctx, [first, ...rest]) =>\n fileResult(\n first,\n 'merged',\n videoOp(ctx, 'CONCAT', first.src, { input_urls: rest.map((c) => c.src), reencode: true }),\n ),\n },\n {\n id: 'merge-audio',\n group: 'Combine',\n label: 'Merge audio',\n hint: 'Join tracks end to end, in order',\n inputs: many('Tracks', ['audio']),\n fields: [\n {\n key: 'crossfade',\n label: 'Crossfade',\n kind: 'number',\n default: 0,\n min: 0,\n max: 5000,\n step: 250,\n unit: 'ms',\n },\n ],\n run: async (ctx, [first, ...rest], values) =>\n fileResult(\n first,\n 'merged',\n audioOp(ctx, 'CONCAT', first.src, {\n input_urls: rest.map((c) => c.src),\n crossfade_ms: Number(values.crossfade),\n }),\n ),\n },\n {\n id: 'mix-audio',\n group: 'Combine',\n label: 'Mix audio',\n hint: 'Layer tracks on top of each other',\n inputs: many('Tracks', ['audio']),\n fields: [\n {\n key: 'duration',\n label: 'Length',\n kind: 'select',\n default: 'longest',\n options: [\n { value: 'longest', label: 'Longest' },\n { value: 'shortest', label: 'Shortest' },\n { value: 'first', label: 'First track' },\n ],\n },\n ],\n run: async (ctx, [first, ...rest], values) =>\n fileResult(\n first,\n 'mix',\n audioOp(ctx, 'MIX', first.src, {\n input_urls: rest.map((c) => c.src),\n duration: values.duration,\n normalize: true,\n }),\n ),\n },\n {\n id: 'normalize',\n group: 'Clean up',\n label: 'Normalize loudness',\n hint: 'Even out the volume to a standard level',\n inputs: one('video', 'audio'),\n fields: [{ key: 'target', label: 'Target', kind: 'select', default: '-14', options: LOUDNESS }],\n run: async (ctx, [media], values) => {\n const params = { i: Number(values.target) };\n return fileResult(\n media,\n 'normalized',\n media.type === 'audio'\n ? audioOp(ctx, 'NORMALIZE', media.src, params)\n : videoOp(ctx, 'AUDIO_NORMALIZE', media.src, params),\n );\n },\n },\n];\n\n/** Defaults for a tool's fields. */\nexport function defaultValues(tool: Pick<ToolDef, 'fields'>): ToolValues {\n return Object.fromEntries((tool.fields ?? []).map((f) => [f.key, f.default]));\n}\n\n/** Whether the chosen inputs satisfy a tool's slots. */\nexport function inputsReady(tool: Pick<ToolDef, 'inputs'>, chosen: ToolInput[][]): boolean {\n return tool.inputs.every((slot, i) => {\n const picked = chosen[i] ?? [];\n const ok = picked.every((p) => slot.accepts.includes(p.type));\n return ok && (slot.many ? picked.length >= (slot.min ?? 2) : picked.length === 1);\n });\n}\n"],"names":["fallbackExt"],"mappings":"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"}