@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.
- package/lib/features/apps/appArt.js +1 -1
- package/lib/features/apps/appArt.js.map +1 -1
- package/lib/features/apps/mobileAppCatalog.js +15 -11
- package/lib/features/apps/mobileAppCatalog.js.map +1 -1
- package/lib/features/canvas/CanvasAgentChatPane.js +82 -20
- package/lib/features/canvas/CanvasAgentChatPane.js.map +1 -1
- package/lib/features/canvas/CanvasBoardsGrid.js +291 -100
- package/lib/features/canvas/CanvasBoardsGrid.js.map +1 -1
- package/lib/features/canvas/CanvasEditToolsPanel.js +105 -12
- package/lib/features/canvas/CanvasEditToolsPanel.js.map +1 -1
- package/lib/features/canvas/CanvasExperience.js +266 -68
- package/lib/features/canvas/CanvasExperience.js.map +1 -1
- package/lib/features/canvas/CanvasGeneratePanel.js +204 -66
- package/lib/features/canvas/CanvasGeneratePanel.js.map +1 -1
- package/lib/features/canvas/CanvasLibrarySheet.js +31 -13
- package/lib/features/canvas/CanvasLibrarySheet.js.map +1 -1
- package/lib/features/canvas/CanvasModelPicker.js +176 -0
- package/lib/features/canvas/CanvasModelPicker.js.map +1 -0
- package/lib/features/canvas/CanvasTasksPanel.js +325 -29
- package/lib/features/canvas/CanvasTasksPanel.js.map +1 -1
- package/lib/features/canvas/CanvasTemplatesPanel.js +5 -4
- package/lib/features/canvas/CanvasTemplatesPanel.js.map +1 -1
- package/lib/features/canvas/CanvasToolDock.js +137 -61
- package/lib/features/canvas/CanvasToolDock.js.map +1 -1
- package/lib/features/canvas/FrameExtractorExperience.js +33 -2
- package/lib/features/canvas/FrameExtractorExperience.js.map +1 -1
- package/lib/features/canvas/GeneratorReferenceSlots.js +197 -0
- package/lib/features/canvas/GeneratorReferenceSlots.js.map +1 -0
- package/lib/features/canvas/NativeCanvasViewer.js +89 -11
- package/lib/features/canvas/NativeCanvasViewer.js.map +1 -1
- package/lib/features/canvas/PromoContextFields.js +55 -2
- package/lib/features/canvas/PromoContextFields.js.map +1 -1
- package/lib/features/canvas/SetStudioExperience.js +323 -13
- package/lib/features/canvas/SetStudioExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditExperience.js +1 -53
- package/lib/features/canvas/VideoEditExperience.js.map +1 -1
- package/lib/features/canvas/VideoEditorExperience.js +697 -506
- package/lib/features/canvas/VideoEditorExperience.js.map +1 -1
- package/lib/features/canvas/VideoGeneratorExperience.js +22 -5
- package/lib/features/canvas/VideoGeneratorExperience.js.map +1 -1
- package/lib/features/canvas/canvasAgentChat.js +125 -11
- package/lib/features/canvas/canvasAgentChat.js.map +1 -1
- package/lib/features/canvas/canvasCore.js +117 -12
- package/lib/features/canvas/canvasCore.js.map +1 -1
- package/lib/features/canvas/canvasEditOps.js +148 -111
- package/lib/features/canvas/canvasEditOps.js.map +1 -1
- package/lib/features/canvas/canvasTaskSync.js +235 -0
- package/lib/features/canvas/canvasTaskSync.js.map +1 -0
- package/lib/features/canvas/canvasTasks.js +98 -11
- package/lib/features/canvas/canvasTasks.js.map +1 -1
- package/lib/features/canvas/createTiles.js +247 -0
- package/lib/features/canvas/createTiles.js.map +1 -0
- package/lib/features/canvas/deepLinks.js +83 -0
- package/lib/features/canvas/deepLinks.js.map +1 -0
- package/lib/features/canvas/frameExtract.js +13 -1
- package/lib/features/canvas/frameExtract.js.map +1 -1
- package/lib/features/canvas/generationModels.js +36 -8
- package/lib/features/canvas/generationModels.js.map +1 -1
- package/lib/features/canvas/generatorCommands.js +106 -0
- package/lib/features/canvas/generatorCommands.js.map +1 -0
- package/lib/features/canvas/generatorReferences.js +82 -0
- package/lib/features/canvas/generatorReferences.js.map +1 -0
- package/lib/features/canvas/homeWork.js +74 -0
- package/lib/features/canvas/homeWork.js.map +1 -0
- package/lib/features/canvas/linksRpc.js +130 -0
- package/lib/features/canvas/linksRpc.js.map +1 -0
- package/lib/features/canvas/mediaRecheck.js +176 -0
- package/lib/features/canvas/mediaRecheck.js.map +1 -0
- package/lib/features/canvas/mediaUrls.js +258 -0
- package/lib/features/canvas/mediaUrls.js.map +1 -0
- package/lib/features/canvas/nativeViewerRegistry.js.map +1 -1
- package/lib/features/canvas/promoProjectImport.js +80 -13
- package/lib/features/canvas/promoProjectImport.js.map +1 -1
- package/lib/features/canvas/promoVideo.js +106 -15
- package/lib/features/canvas/promoVideo.js.map +1 -1
- package/lib/features/canvas/reframe.js +228 -0
- package/lib/features/canvas/reframe.js.map +1 -0
- package/lib/features/canvas/serverTasks.js +697 -0
- package/lib/features/canvas/serverTasks.js.map +1 -0
- package/lib/features/canvas/set/SetViewportWebView.js +207 -28
- package/lib/features/canvas/set/SetViewportWebView.js.map +1 -1
- package/lib/features/canvas/set/agent/prompt.js +66 -0
- package/lib/features/canvas/set/agent/prompt.js.map +1 -0
- package/lib/features/canvas/set/agent/setOps.js +203 -0
- package/lib/features/canvas/set/agent/setOps.js.map +1 -0
- package/lib/features/canvas/set/agent/setTurn.js +128 -0
- package/lib/features/canvas/set/agent/setTurn.js.map +1 -0
- package/lib/features/canvas/set/agent/snapshot.js +43 -0
- package/lib/features/canvas/set/agent/snapshot.js.map +1 -0
- package/lib/features/canvas/set/agent/tools.js +580 -0
- package/lib/features/canvas/set/agent/tools.js.map +1 -0
- package/lib/features/canvas/set/setProject.js +43 -4
- package/lib/features/canvas/set/setProject.js.map +1 -1
- package/lib/features/canvas/set/supplyLibrary.js +397 -0
- package/lib/features/canvas/set/supplyLibrary.js.map +1 -0
- package/lib/features/canvas/storageLibrary.js +113 -52
- package/lib/features/canvas/storageLibrary.js.map +1 -1
- package/lib/features/canvas/studioCatalog.js +15 -2
- package/lib/features/canvas/studioCatalog.js.map +1 -1
- package/lib/features/canvas/studioLooks.js +1 -8
- package/lib/features/canvas/studioLooks.js.map +1 -1
- package/lib/features/canvas/useBoardMediaRefresh.js +66 -0
- package/lib/features/canvas/useBoardMediaRefresh.js.map +1 -0
- package/lib/features/canvas/useMediaSource.js +84 -0
- package/lib/features/canvas/useMediaSource.js.map +1 -0
- package/lib/features/canvas/video3d.js +11 -10
- package/lib/features/canvas/video3d.js.map +1 -1
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js +46 -0
- package/lib/features/canvas/videoEditor/BlurBoxOverlay.js.map +1 -0
- package/lib/features/canvas/videoEditor/ExportTaskCard.js +134 -0
- package/lib/features/canvas/videoEditor/ExportTaskCard.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js +45 -7
- package/lib/features/canvas/videoEditor/agent/AgentCutPane.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/agentLoop.js +4 -2
- package/lib/features/canvas/videoEditor/agent/agentLoop.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/attachments.js +304 -0
- package/lib/features/canvas/videoEditor/agent/attachments.js.map +1 -0
- package/lib/features/canvas/videoEditor/agent/brainClient.js +3 -2
- package/lib/features/canvas/videoEditor/agent/brainClient.js.map +1 -1
- package/lib/features/canvas/videoEditor/agent/cutTools.js +207 -7
- package/lib/features/canvas/videoEditor/agent/cutTools.js.map +1 -1
- package/lib/features/canvas/videoEditor/blurBox.js +34 -0
- package/lib/features/canvas/videoEditor/blurBox.js.map +1 -0
- package/lib/features/canvas/videoEditor/compileTimeline.js +668 -0
- package/lib/features/canvas/videoEditor/compileTimeline.js.map +1 -0
- package/lib/features/canvas/videoEditor/editorModel.js +56 -22
- package/lib/features/canvas/videoEditor/editorModel.js.map +1 -1
- package/lib/features/canvas/videoEditor/exportPipeline.js +77 -0
- package/lib/features/canvas/videoEditor/exportPipeline.js.map +1 -0
- package/lib/features/canvas/videoEditor/exportRenderer.js +19 -12
- package/lib/features/canvas/videoEditor/exportRenderer.js.map +1 -1
- package/lib/features/canvas/videoEditor/exportTask.js +216 -0
- package/lib/features/canvas/videoEditor/exportTask.js.map +1 -0
- package/lib/features/canvas/videoEditor/formWidgets.js +142 -0
- package/lib/features/canvas/videoEditor/formWidgets.js.map +1 -0
- package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js +195 -0
- package/lib/features/canvas/videoEditor/produce/ProduceVideoSheet.js.map +1 -0
- package/lib/features/canvas/videoEditor/produce/produceScenes.js +158 -0
- package/lib/features/canvas/videoEditor/produce/produceScenes.js.map +1 -0
- package/lib/features/canvas/videoEditor/remoteMediaClient.js +17 -5
- package/lib/features/canvas/videoEditor/remoteMediaClient.js.map +1 -1
- package/lib/features/canvas/videoEditor/renderTimeline.js +207 -0
- package/lib/features/canvas/videoEditor/renderTimeline.js.map +1 -0
- package/lib/features/canvas/videoEditor/renewLinks.js +64 -0
- package/lib/features/canvas/videoEditor/renewLinks.js.map +1 -0
- package/lib/features/canvas/videoEditor/sceneLayers.js +101 -0
- package/lib/features/canvas/videoEditor/sceneLayers.js.map +1 -0
- package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js +283 -0
- package/lib/features/canvas/videoEditor/tools/ToolsDrawer.js.map +1 -0
- package/lib/features/canvas/videoEditor/tools/catalog.js +576 -0
- package/lib/features/canvas/videoEditor/tools/catalog.js.map +1 -0
- package/lib/features/canvas/videoEditor/videoProjectsStore.js +27 -3
- package/lib/features/canvas/videoEditor/videoProjectsStore.js.map +1 -1
- package/lib/features/webbuilder/WebBuilderExperience.js +29 -1
- package/lib/features/webbuilder/WebBuilderExperience.js.map +1 -1
- package/lib/features/webbuilder/buildFragments.js +8 -4
- package/lib/features/webbuilder/buildFragments.js.map +1 -1
- package/lib/features/webbuilder/codezenHandoff.js +108 -0
- package/lib/features/webbuilder/codezenHandoff.js.map +1 -0
- package/lib/features/webbuilder/workflow.js.map +1 -1
- package/lib/hooks/useChatApi.js +1 -2
- package/lib/hooks/useChatApi.js.map +1 -1
- package/lib/screens/CanvasBoard/index.js +12 -1
- package/lib/screens/CanvasBoard/index.js.map +1 -1
- package/lib/screens/Home/HomeScreen.js.map +1 -1
- package/lib/screens/Home/components/HomeSuggestions.js +3 -3
- package/lib/screens/Home/components/HomeSuggestions.js.map +1 -1
- package/lib/screens/WebBuilder/index.js +4 -2
- package/lib/screens/WebBuilder/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/index.js +29 -2
- package/lib/screens/WebBuilderNative/index.js.map +1 -1
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js +30 -6
- package/lib/screens/WebBuilderNative/useWebBuilderHost.js.map +1 -1
- package/package.json +4 -4
- /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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"}
|