diff --git a/src/components/ImageStudio.js b/src/components/ImageStudio.js index 3e9daf1..41a462a 100644 --- a/src/components/ImageStudio.js +++ b/src/components/ImageStudio.js @@ -1,6 +1,7 @@ import { muapi } from '../lib/muapi.js'; -import { t2iModels, getAspectRatiosForModel } from '../lib/models.js'; +import { t2iModels, getAspectRatiosForModel, i2iModels, getAspectRatiosForI2IModel, getResolutionsForI2IModel } from '../lib/models.js'; import { AuthModal } from './AuthModal.js'; +import { createUploadPicker } from './UploadPicker.js'; export function ImageStudio() { const container = document.createElement('div'); @@ -10,31 +11,14 @@ export function ImageStudio() { const defaultModel = t2iModels[0]; let selectedModel = defaultModel.id; let selectedModelName = defaultModel.name; - let selectedAr = '1:1'; + let selectedAr = defaultModel.inputs?.aspect_ratio?.default || '1:1'; let dropdownOpen = null; + let uploadedImageUrl = null; + let imageMode = false; // false = t2i models, true = i2i models - // Helper: Get valid resolutions/quality options for a model - const getResolutionsForModel = (modelId) => { - const model = t2iModels.find(m => m.id === modelId); - if (!model) return ['1K']; // Default - - // Check for specific resolution enum - if (model.inputs?.resolution?.enum) { - return model.inputs.resolution.enum.map(r => r.toUpperCase()); - } - - // Check for megapixels enum - if (model.inputs?.megapixels?.enum) { - return model.inputs.megapixels.enum; - } - - // Fallback logic based on common models - if (modelId.includes('flux')) return ['1K']; // Flux usually fixed - if (modelId.includes('midjourney')) return ['1K']; - - // Default set for others if not specified - return ['1K', '2K', '4K']; - }; + const getCurrentModels = () => imageMode ? i2iModels : t2iModels; + const getCurrentAspectRatios = (id) => imageMode ? getAspectRatiosForI2IModel(id) : getAspectRatiosForModel(id); + const getCurrentResolutions = (id) => imageMode ? getResolutionsForI2IModel(id) : []; // ========================================== // 1. HERO SECTION @@ -59,8 +43,8 @@ export function ImageStudio() {
-

Nano Banana Pro

-

Create stunning, high-aesthetic images in seconds

+

Image Studio

+

Transform images with AI — upscale, stylize, animate and more

`; container.appendChild(hero); @@ -78,10 +62,41 @@ export function ImageStudio() { const topRow = document.createElement('div'); topRow.className = 'flex items-start gap-5 px-2'; - topRow.innerHTML = ``; + // --- Image Upload Picker (Image-to-Image) --- + const picker = createUploadPicker({ + anchorContainer: container, + onSelect: ({ url }) => { + uploadedImageUrl = url; + if (!imageMode) { + imageMode = true; + selectedModel = i2iModels[0].id; + selectedModelName = i2iModels[0].name; + selectedAr = getAspectRatiosForI2IModel(selectedModel)[0]; + document.getElementById('model-btn-label').textContent = selectedModelName; + document.getElementById('ar-btn-label').textContent = selectedAr; + const validResolutions = getResolutionsForI2IModel(selectedModel); + qualityBtn.style.display = validResolutions.length > 0 ? 'flex' : 'none'; + if (validResolutions.length > 0) document.getElementById('quality-btn-label').textContent = validResolutions[0]; + } + textarea.placeholder = 'Describe how to transform this image (optional)'; + }, + onClear: () => { + uploadedImageUrl = null; + imageMode = false; + selectedModel = t2iModels[0].id; + selectedModelName = t2iModels[0].name; + selectedAr = getAspectRatiosForModel(selectedModel)[0]; + document.getElementById('model-btn-label').textContent = selectedModelName; + document.getElementById('ar-btn-label').textContent = selectedAr; + qualityBtn.style.display = 'none'; + textarea.placeholder = 'Describe the image you want to create'; + } + }); + topRow.appendChild(picker.trigger); + container.appendChild(picker.panel); const textarea = document.createElement('textarea'); - textarea.placeholder = 'Describe the scene you imagine'; + textarea.placeholder = 'Describe the image you want to create'; textarea.className = 'flex-1 bg-transparent border-none text-white text-base md:text-xl placeholder:text-muted focus:outline-none resize-none pt-2.5 leading-relaxed min-h-[40px] max-h-[150px] md:max-h-[250px] overflow-y-auto custom-scrollbar'; textarea.rows = 1; textarea.oninput = () => { @@ -124,16 +139,12 @@ export function ImageStudio() { const qualityBtn = createControlBtn(` - `, '1K', 'quality-btn'); + `, '720p', 'quality-btn'); controlsLeft.appendChild(modelBtn); controlsLeft.appendChild(arBtn); controlsLeft.appendChild(qualityBtn); - - // Initial Resolution Visibility (only show for models with explicit resolution/megapixels enums) - const initialModel = t2iModels[0]; - const hasInitialRes = initialModel?.inputs?.resolution?.enum || initialModel?.inputs?.megapixels?.enum; - qualityBtn.style.display = hasInitialRes ? 'flex' : 'none'; + qualityBtn.style.display = 'none'; // hidden in t2i mode, shown when i2i model has resolutions const generateBtn = document.createElement('button'); generateBtn.className = 'bg-primary text-black px-6 md:px-8 py-3 md:py-3.5 rounded-xl md:rounded-[1.5rem] font-black text-sm md:text-base hover:shadow-glow hover:scale-105 active:scale-95 transition-all flex items-center justify-center gap-2.5 w-full sm:w-auto shadow-lg'; @@ -175,14 +186,14 @@ export function ImageStudio() { const renderModels = (filter = '') => { list.innerHTML = ''; - const filtered = t2iModels.filter(m => m.name.toLowerCase().includes(filter.toLowerCase()) || m.id.toLowerCase().includes(filter.toLowerCase())); + const filtered = getCurrentModels().filter(m => m.name.toLowerCase().includes(filter.toLowerCase()) || m.id.toLowerCase().includes(filter.toLowerCase())); filtered.forEach(m => { const item = document.createElement('div'); item.className = `flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all border border-transparent hover:border-white/5 ${selectedModel === m.id ? 'bg-white/5 border-white/5' : ''}`; item.innerHTML = `
-
${m.name.charAt(0)}
+
${m.name.charAt(0)}
${m.name}
@@ -193,24 +204,15 @@ export function ImageStudio() { e.stopPropagation(); selectedModel = m.id; selectedModelName = m.name; - // Reset AR to first valid for model - const availableArs = getAspectRatiosForModel(selectedModel); + const availableArs = getCurrentAspectRatios(selectedModel); selectedAr = availableArs[0]; document.getElementById('model-btn-label').textContent = selectedModelName; document.getElementById('ar-btn-label').textContent = selectedAr; - // Show/Hide quality button based on model support (only resolution/megapixels enums) - const model = t2iModels.find(mod => mod.id === selectedModel); - const hasQuality = model?.inputs?.resolution?.enum || model?.inputs?.megapixels?.enum; - qualityBtn.style.display = hasQuality ? 'flex' : 'none'; - - // Reset resolution label if current is not valid for new model - if (hasQuality) { - const validResolutions = getResolutionsForModel(selectedModel); - const currentRes = document.getElementById('quality-btn-label').textContent; - if (!validResolutions.includes(currentRes)) { - document.getElementById('quality-btn-label').textContent = validResolutions[0]; - } + const validResolutions = getCurrentResolutions(selectedModel); + qualityBtn.style.display = validResolutions.length > 0 ? 'flex' : 'none'; + if (validResolutions.length > 0) { + document.getElementById('quality-btn-label').textContent = validResolutions[0]; } closeDropdown(); @@ -231,7 +233,7 @@ export function ImageStudio() { const list = document.createElement('div'); list.className = 'flex flex-col gap-1'; - const availableArs = getAspectRatiosForModel(selectedModel); + const availableArs = getCurrentAspectRatios(selectedModel); availableArs.forEach(r => { const item = document.createElement('div'); item.className = 'flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all group'; @@ -259,8 +261,7 @@ export function ImageStudio() { const list = document.createElement('div'); list.className = 'flex flex-col gap-1'; - // Dynamic resolution options - const options = getResolutionsForModel(selectedModel); + const options = getCurrentResolutions(selectedModel); options.forEach(opt => { const item = document.createElement('div'); @@ -506,6 +507,17 @@ export function ImageStudio() { hero.classList.remove('hidden', 'opacity-0', 'scale-95', '-translate-y-10', 'pointer-events-none'); promptWrapper.classList.remove('hidden', 'opacity-40'); textarea.value = ''; + picker.reset(); + uploadedImageUrl = null; + // Reset to t2i mode + imageMode = false; + selectedModel = t2iModels[0].id; + selectedModelName = t2iModels[0].name; + selectedAr = getAspectRatiosForModel(selectedModel)[0]; + document.getElementById('model-btn-label').textContent = selectedModelName; + document.getElementById('ar-btn-label').textContent = selectedAr; + qualityBtn.style.display = 'none'; + textarea.placeholder = 'Describe the image you want to create'; textarea.focus(); }; @@ -514,30 +526,46 @@ export function ImageStudio() { // ========================================== generateBtn.onclick = async () => { const prompt = textarea.value.trim(); - if (!prompt) return; + if (imageMode) { + if (!uploadedImageUrl) { + alert('Please upload a reference image first.'); + return; + } + } else { + if (!prompt) { + alert('Please enter a prompt to generate an image.'); + return; + } + } - // Lazy API Key Check const apiKey = localStorage.getItem('muapi_key'); if (!apiKey) { - AuthModal(() => { - // Key saved, now trigger generation - generateBtn.click(); - }); + AuthModal(() => generateBtn.click()); return; } - // Animate Out Hero hero.classList.add('opacity-0', 'scale-95', '-translate-y-10', 'pointer-events-none'); - generateBtn.disabled = true; generateBtn.innerHTML = ` Generating...`; try { - const res = await muapi.generateImage({ - prompt, - model: selectedModel, - aspect_ratio: selectedAr - }); + let res; + if (imageMode) { + const genParams = { + model: selectedModel, + image_url: uploadedImageUrl, + aspect_ratio: selectedAr + }; + if (prompt) genParams.prompt = prompt; + res = await muapi.generateI2I(genParams); + } else { + const genParams = { + model: selectedModel, + prompt, + aspect_ratio: selectedAr + }; + res = await muapi.generateImage(genParams); + } console.log('[ImageStudio] Full response:', res); diff --git a/src/components/UploadPicker.js b/src/components/UploadPicker.js new file mode 100644 index 0000000..8957448 --- /dev/null +++ b/src/components/UploadPicker.js @@ -0,0 +1,250 @@ +import { muapi } from '../lib/muapi.js'; +import { AuthModal } from './AuthModal.js'; +import { getUploadHistory, saveUpload, removeUpload, generateThumbnail } from '../lib/uploadHistory.js'; + +/** + * Creates a self-contained upload picker: a trigger button + history panel. + * + * @param {object} options + * @param {HTMLElement} options.anchorContainer - The container element the panel is positioned relative to + * @param {function({ url: string, thumbnail: string }): void} options.onSelect - Called when an image is selected + * @param {function(): void} [options.onClear] - Called when the active selection is removed from history + * @returns {{ trigger: HTMLElement, panel: HTMLElement, reset: function }} + */ +export function createUploadPicker({ anchorContainer, onSelect, onClear }) { + let panelOpen = false; + let selectedEntry = null; // { url, thumbnail } + + // ── Hidden file input ──────────────────────────────────────────────────── + const fileInput = document.createElement('input'); + fileInput.type = 'file'; + fileInput.accept = 'image/*'; + fileInput.className = 'hidden'; + + // ── Trigger button ─────────────────────────────────────────────────────── + const trigger = document.createElement('button'); + trigger.type = 'button'; + trigger.title = 'Reference image'; + trigger.className = 'w-10 h-10 shrink-0 rounded-xl border transition-all flex items-center justify-center relative overflow-hidden mt-1.5 bg-white/5 border-white/10 hover:bg-white/10 hover:border-primary/40 group'; + + // State: icon + const iconState = document.createElement('div'); + iconState.className = 'flex items-center justify-center w-full h-full'; + iconState.innerHTML = ``; + + // State: spinner + const spinnerState = document.createElement('div'); + spinnerState.className = 'hidden items-center justify-center w-full h-full'; + spinnerState.innerHTML = ``; + + // State: thumbnail with checkmark badge + const thumbnailState = document.createElement('div'); + thumbnailState.className = 'hidden w-full h-full'; + const thumbImg = document.createElement('img'); + thumbImg.className = 'w-full h-full object-cover'; + const badge = document.createElement('div'); + badge.className = 'absolute bottom-0.5 right-0.5 w-4 h-4 bg-primary rounded-full flex items-center justify-center'; + badge.innerHTML = ``; + thumbnailState.appendChild(thumbImg); + thumbnailState.appendChild(badge); + + trigger.appendChild(fileInput); + trigger.appendChild(iconState); + trigger.appendChild(spinnerState); + trigger.appendChild(thumbnailState); + + // ── Trigger state helpers ──────────────────────────────────────────────── + const showIcon = () => { + iconState.classList.replace('hidden', 'flex'); + spinnerState.classList.add('hidden'); spinnerState.classList.remove('flex'); + thumbnailState.classList.add('hidden'); thumbnailState.classList.remove('flex'); + trigger.classList.remove('border-primary/60'); + trigger.classList.add('border-white/10'); + }; + + const showSpinner = () => { + iconState.classList.add('hidden'); iconState.classList.remove('flex'); + spinnerState.classList.replace('hidden', 'flex'); + thumbnailState.classList.add('hidden'); thumbnailState.classList.remove('flex'); + }; + + const showThumbnail = (src) => { + thumbImg.src = src; + iconState.classList.add('hidden'); iconState.classList.remove('flex'); + spinnerState.classList.add('hidden'); spinnerState.classList.remove('flex'); + thumbnailState.classList.replace('hidden', 'flex'); + trigger.classList.remove('border-white/10'); + trigger.classList.add('border-primary/60'); + }; + + // ── Panel ──────────────────────────────────────────────────────────────── + const panel = document.createElement('div'); + panel.className = 'absolute z-50 opacity-0 pointer-events-none scale-95 origin-bottom-left glass rounded-3xl p-3 shadow-4xl border border-white/10 w-72 transition-all'; + + const openPanel = () => { + renderPanel(); + panel.classList.remove('opacity-0', 'pointer-events-none', 'scale-95'); + panel.classList.add('opacity-100', 'pointer-events-auto', 'scale-100'); + // Position relative to anchorContainer (matches existing dropdown math) + const btnRect = trigger.getBoundingClientRect(); + const containerRect = anchorContainer.getBoundingClientRect(); + panel.style.left = `${btnRect.left - containerRect.left}px`; + panel.style.bottom = `${containerRect.bottom - btnRect.top + 8}px`; + panelOpen = true; + }; + + const closePanel = () => { + panel.classList.add('opacity-0', 'pointer-events-none', 'scale-95'); + panel.classList.remove('opacity-100', 'pointer-events-auto', 'scale-100'); + panelOpen = false; + }; + + const renderPanel = () => { + panel.innerHTML = ''; + const history = getUploadHistory(); + + // Header + const header = document.createElement('div'); + header.className = 'flex items-center justify-between px-1 pb-3 mb-2 border-b border-white/5'; + header.innerHTML = `Reference Images`; + + const uploadNewBtn = document.createElement('button'); + uploadNewBtn.type = 'button'; + uploadNewBtn.className = 'flex items-center gap-1.5 px-3 py-1.5 bg-primary/10 hover:bg-primary/20 text-primary rounded-xl text-xs font-bold transition-all border border-primary/20'; + uploadNewBtn.innerHTML = ` Upload new`; + uploadNewBtn.onclick = (e) => { e.stopPropagation(); closePanel(); fileInput.click(); }; + header.appendChild(uploadNewBtn); + panel.appendChild(header); + + if (history.length === 0) { + const empty = document.createElement('div'); + empty.className = 'py-6 flex flex-col items-center gap-2 opacity-40'; + empty.innerHTML = ` + + No uploads yet + `; + panel.appendChild(empty); + return; + } + + // Grid of saved uploads + const grid = document.createElement('div'); + grid.className = 'grid grid-cols-3 gap-2 max-h-56 overflow-y-auto custom-scrollbar pr-0.5'; + + history.forEach(entry => { + const isSelected = selectedEntry?.url === entry.uploadedUrl; + + const cell = document.createElement('div'); + cell.className = `relative rounded-xl overflow-hidden border-2 cursor-pointer group/cell aspect-square transition-all ${isSelected ? 'border-primary shadow-glow' : 'border-white/10 hover:border-white/30'}`; + cell.title = entry.name; + + const img = document.createElement('img'); + img.src = entry.thumbnail; + img.className = 'w-full h-full object-cover'; + + // Hover overlay with delete button + const overlay = document.createElement('div'); + overlay.className = 'absolute inset-0 bg-black/60 opacity-0 group-hover/cell:opacity-100 transition-opacity flex items-end justify-end p-1'; + + const delBtn = document.createElement('button'); + delBtn.type = 'button'; + delBtn.className = 'w-5 h-5 bg-red-500/80 hover:bg-red-500 rounded-md flex items-center justify-center transition-colors'; + delBtn.title = 'Remove from history'; + delBtn.innerHTML = ``; + delBtn.onclick = (e) => { + e.stopPropagation(); + removeUpload(entry.id); + if (selectedEntry?.url === entry.uploadedUrl) { + selectedEntry = null; + showIcon(); + onClear?.(); + } + renderPanel(); + }; + overlay.appendChild(delBtn); + + // Selected checkmark badge + if (isSelected) { + const check = document.createElement('div'); + check.className = 'absolute top-1 left-1 w-5 h-5 bg-primary rounded-full flex items-center justify-center'; + check.innerHTML = ``; + cell.appendChild(check); + } + + cell.appendChild(img); + cell.appendChild(overlay); + + cell.onclick = (e) => { + e.stopPropagation(); + selectedEntry = { url: entry.uploadedUrl, thumbnail: entry.thumbnail }; + showThumbnail(entry.thumbnail); + onSelect({ url: entry.uploadedUrl, thumbnail: entry.thumbnail }); + closePanel(); + }; + + grid.appendChild(cell); + }); + + panel.appendChild(grid); + }; + + // ── Trigger click ──────────────────────────────────────────────────────── + trigger.onclick = (e) => { + e.stopPropagation(); + if (panelOpen) closePanel(); + else openPanel(); + }; + + // Close panel on outside click + window.addEventListener('click', closePanel); + + // ── File upload handler ────────────────────────────────────────────────── + fileInput.onchange = async (e) => { + const file = e.target.files[0]; + if (!file) return; + + const apiKey = localStorage.getItem('muapi_key'); + if (!apiKey) { + AuthModal(() => fileInput.click()); + return; + } + + showSpinner(); + + try { + // Upload to API and generate thumbnail in parallel + const [uploadedUrl, thumbnail] = await Promise.all([ + muapi.uploadFile(file), + generateThumbnail(file) + ]); + + const entry = { + id: Date.now().toString(), + name: file.name, + uploadedUrl, + thumbnail, + timestamp: new Date().toISOString() + }; + + saveUpload(entry); + selectedEntry = { url: uploadedUrl, thumbnail }; + showThumbnail(thumbnail); + onSelect({ url: uploadedUrl, thumbnail }); + } catch (err) { + console.error('[UploadPicker] Upload failed:', err); + showIcon(); + alert(`Image upload failed: ${err.message}`); + } + + fileInput.value = ''; + }; + + // ── Public API ─────────────────────────────────────────────────────────── + const reset = () => { + selectedEntry = null; + showIcon(); + closePanel(); + }; + + return { trigger, panel, reset }; +} diff --git a/src/components/VideoStudio.js b/src/components/VideoStudio.js index e49b537..31136af 100644 --- a/src/components/VideoStudio.js +++ b/src/components/VideoStudio.js @@ -1,6 +1,7 @@ import { muapi } from '../lib/muapi.js'; -import { t2vModels, getAspectRatiosForVideoModel, getDurationsForModel, getResolutionsForVideoModel } from '../lib/models.js'; +import { t2vModels, getAspectRatiosForVideoModel, getDurationsForModel, getResolutionsForVideoModel, i2vModels, getAspectRatiosForI2VModel, getDurationsForI2VModel, getResolutionsForI2VModel } from '../lib/models.js'; import { AuthModal } from './AuthModal.js'; +import { createUploadPicker } from './UploadPicker.js'; export function VideoStudio() { const container = document.createElement('div'); @@ -14,6 +15,13 @@ export function VideoStudio() { let selectedDuration = defaultModel.inputs?.duration?.default || 5; let selectedResolution = defaultModel.inputs?.resolution?.default || ''; let dropdownOpen = null; + let uploadedImageUrl = null; + let imageMode = false; // false = t2v models, true = i2v models + + const getCurrentModels = () => imageMode ? i2vModels : t2vModels; + const getCurrentAspectRatios = (id) => imageMode ? getAspectRatiosForI2VModel(id) : getAspectRatiosForVideoModel(id); + const getCurrentDurations = (id) => imageMode ? getDurationsForI2VModel(id) : getDurationsForModel(id); + const getCurrentResolutions = (id) => imageMode ? getResolutionsForI2VModel(id) : getResolutionsForVideoModel(id); // ========================================== // 1. HERO SECTION @@ -38,7 +46,7 @@ export function VideoStudio() {

Video Studio

-

Create stunning AI videos from text in seconds

+

Animate images into stunning AI videos with motion effects

`; container.appendChild(hero); @@ -55,8 +63,35 @@ export function VideoStudio() { const topRow = document.createElement('div'); topRow.className = 'flex items-start gap-5 px-2'; + // --- Image Upload Picker (Image-to-Video) --- + const picker = createUploadPicker({ + anchorContainer: container, + onSelect: ({ url }) => { + uploadedImageUrl = url; + if (!imageMode) { + imageMode = true; + selectedModel = i2vModels[0].id; + selectedModelName = i2vModels[0].name; + document.getElementById('v-model-btn-label').textContent = selectedModelName; + updateControlsForModel(selectedModel); + } + textarea.placeholder = 'Describe the motion or effect (optional)'; + }, + onClear: () => { + uploadedImageUrl = null; + imageMode = false; + selectedModel = t2vModels[0].id; + selectedModelName = t2vModels[0].name; + document.getElementById('v-model-btn-label').textContent = selectedModelName; + updateControlsForModel(selectedModel); + textarea.placeholder = 'Describe the video you want to create'; + } + }); + topRow.appendChild(picker.trigger); + container.appendChild(picker.panel); + const textarea = document.createElement('textarea'); - textarea.placeholder = 'Describe the video you imagine'; + textarea.placeholder = 'Describe the video you want to create'; textarea.className = 'flex-1 bg-transparent border-none text-white text-base md:text-xl placeholder:text-muted focus:outline-none resize-none pt-2.5 leading-relaxed min-h-[40px] max-h-[150px] md:max-h-[250px] overflow-y-auto custom-scrollbar'; textarea.rows = 1; textarea.oninput = () => { @@ -110,7 +145,7 @@ export function VideoStudio() { controlsLeft.appendChild(durationBtn); controlsLeft.appendChild(resolutionBtn); - // Initial visibility + // Initial visibility (t2v mode) const initDurations = getDurationsForModel(defaultModel.id); durationBtn.style.display = initDurations.length > 0 ? 'flex' : 'none'; const initResolutions = getResolutionsForVideoModel(defaultModel.id); @@ -133,11 +168,11 @@ export function VideoStudio() { dropdown.className = 'absolute bottom-[102%] left-2 z-50 transition-all opacity-0 pointer-events-none scale-95 origin-bottom-left glass rounded-3xl p-3 translate-y-2 w-[calc(100vw-3rem)] max-w-xs shadow-4xl border border-white/10 flex flex-col'; const updateControlsForModel = (modelId) => { - const availableArs = getAspectRatiosForVideoModel(modelId); + const availableArs = getCurrentAspectRatios(modelId); selectedAr = availableArs[0]; document.getElementById('v-ar-btn-label').textContent = selectedAr; - const durations = getDurationsForModel(modelId); + const durations = getCurrentDurations(modelId); if (durations.length > 0) { selectedDuration = durations[0]; document.getElementById('v-duration-btn-label').textContent = `${selectedDuration}s`; @@ -146,7 +181,7 @@ export function VideoStudio() { durationBtn.style.display = 'none'; } - const resolutions = getResolutionsForVideoModel(modelId); + const resolutions = getCurrentResolutions(modelId); if (resolutions.length > 0) { selectedResolution = resolutions[0]; document.getElementById('v-resolution-btn-label').textContent = selectedResolution; @@ -180,7 +215,7 @@ export function VideoStudio() { const renderModels = (filter = '') => { list.innerHTML = ''; - const filtered = t2vModels.filter(m => m.name.toLowerCase().includes(filter.toLowerCase()) || m.id.toLowerCase().includes(filter.toLowerCase())); + const filtered = getCurrentModels().filter(m => m.name.toLowerCase().includes(filter.toLowerCase()) || m.id.toLowerCase().includes(filter.toLowerCase())); filtered.forEach(m => { const item = document.createElement('div'); item.className = `flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all border border-transparent hover:border-white/5 ${selectedModel === m.id ? 'bg-white/5 border-white/5' : ''}`; @@ -215,7 +250,7 @@ export function VideoStudio() { dropdown.innerHTML = `
Aspect Ratio
`; const list = document.createElement('div'); list.className = 'flex flex-col gap-1'; - const availableArs = getAspectRatiosForVideoModel(selectedModel); + const availableArs = getCurrentAspectRatios(selectedModel); availableArs.forEach(r => { const item = document.createElement('div'); item.className = 'flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all group'; @@ -243,7 +278,7 @@ export function VideoStudio() { dropdown.innerHTML = `
Duration
`; const list = document.createElement('div'); list.className = 'flex flex-col gap-1'; - const durations = getDurationsForModel(selectedModel); + const durations = getCurrentDurations(selectedModel); durations.forEach(d => { const item = document.createElement('div'); item.className = 'flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all group'; @@ -266,7 +301,7 @@ export function VideoStudio() { dropdown.innerHTML = `
Resolution
`; const list = document.createElement('div'); list.className = 'flex flex-col gap-1'; - const resolutions = getResolutionsForVideoModel(selectedModel); + const resolutions = getCurrentResolutions(selectedModel); resolutions.forEach(r => { const item = document.createElement('div'); item.className = 'flex items-center justify-between p-3.5 hover:bg-white/5 rounded-2xl cursor-pointer transition-all group'; @@ -481,6 +516,15 @@ export function VideoStudio() { hero.classList.remove('hidden', 'opacity-0', 'scale-95', '-translate-y-10', 'pointer-events-none'); promptWrapper.classList.remove('hidden', 'opacity-40'); textarea.value = ''; + picker.reset(); + uploadedImageUrl = null; + // Reset to t2v mode + imageMode = false; + selectedModel = t2vModels[0].id; + selectedModelName = t2vModels[0].name; + document.getElementById('v-model-btn-label').textContent = selectedModelName; + updateControlsForModel(selectedModel); + textarea.placeholder = 'Describe the video you want to create'; textarea.focus(); }; @@ -489,7 +533,17 @@ export function VideoStudio() { // ========================================== generateBtn.onclick = async () => { const prompt = textarea.value.trim(); - if (!prompt) return; + if (imageMode) { + if (!uploadedImageUrl) { + alert('Please upload a start frame image first.'); + return; + } + } else { + if (!prompt) { + alert('Please enter a prompt to generate a video.'); + return; + } + } const apiKey = localStorage.getItem('muapi_key'); if (!apiKey) { @@ -498,27 +552,28 @@ export function VideoStudio() { } hero.classList.add('opacity-0', 'scale-95', '-translate-y-10', 'pointer-events-none'); - generateBtn.disabled = true; generateBtn.innerHTML = ` Generating...`; try { const params = { - prompt, model: selectedModel, aspect_ratio: selectedAr, }; - const durations = getDurationsForModel(selectedModel); + if (prompt) params.prompt = prompt; + if (imageMode && uploadedImageUrl) params.image_url = uploadedImageUrl; + + const durations = getCurrentDurations(selectedModel); if (durations.length > 0) params.duration = selectedDuration; - const resolutions = getResolutionsForVideoModel(selectedModel); + const resolutions = getCurrentResolutions(selectedModel); if (resolutions.length > 0) params.resolution = selectedResolution; - const model = t2vModels.find(m => m.id === selectedModel); + const model = getCurrentModels().find(m => m.id === selectedModel); if (model?.inputs?.quality) params.quality = model.inputs.quality.default; - const res = await muapi.generateVideo(params); + const res = imageMode ? await muapi.generateI2V(params) : await muapi.generateVideo(params); console.log('[VideoStudio] Full response:', res); diff --git a/src/lib/models.js b/src/lib/models.js index 2d86987..b08142d 100644 --- a/src/lib/models.js +++ b/src/lib/models.js @@ -2426,3 +2426,5288 @@ export const getResolutionsForVideoModel = (modelId) => { if (resInput && resInput.enum) return resInput.enum; return []; }; +// Auto-generated from schema_data.json — Image to Image models +export const i2iModels = [ + { + "id": "ai-image-upscaler", + "name": "AI Image Upscaler", + "endpoint": "ai-image-upscale", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "ai-image-face-swap", + "name": "AI Image Face Swap", + "endpoint": "ai-image-face-swap", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "target_index": { + "type": "int", + "title": "Target Index", + "name": "target_index", + "description": "0 = largest face. To switch to another target face - switch to index 1.", + "default": 0, + "minValue": 0, + "maxValue": 10, + "step": 1 + } + } + }, + { + "id": "ai-dress-change", + "name": "AI Dress Change", + "endpoint": "ai-dress-change", + "family": "tools", + "imageField": "model_image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "ai-background-remover", + "name": "AI Background Remover", + "endpoint": "ai-background-remover", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "ai-product-shot", + "name": "AI Product Shot", + "endpoint": "ai-product-shot", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "scene_description": { + "type": "string", + "title": "Scene Description", + "name": "scene_description", + "description": "Text description of the new scene or background for the provided product shot. Bria currently supports prompts in English only, excluding special characters.", + "examples": [ + "on a rock, next to the ocean, dark theme" + ] + } + } + }, + { + "id": "ai-skin-enhancer", + "name": "AI Skin Enhancer", + "endpoint": "ai-skin-enhancer", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "ai-color-photo", + "name": "AI Color Photo", + "endpoint": "ai-color-photo", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "flux-kontext-dev-i2i", + "name": "Flux Kontext Dev I2I", + "endpoint": "flux-kontext-dev-i2i", + "family": "kontext", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image. The length of the prompt must be between 2 and 3000 characters.", + "examples": [ + "A cozy outdoor coffee shop on a small street, people sitting at tables enjoying drinks, a barista serving coffee, leaves gently falling from nearby trees, and soft warm lighting adding a friendly vibe." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "3:2", + "2:3", + "21:9", + "9:21" + ], + "default": "1:1" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "default": 1, + "minValue": 1, + "maxValue": 4, + "step": 1 + } + } + }, + { + "id": "ai-product-photography", + "name": "AI Product Photography", + "endpoint": "ai-product-photography", + "family": "tools", + "imageField": "person_image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Promoting brand in professional look" + ] + } + } + }, + { + "id": "ai-ghibli-style", + "name": "AI Ghibli Style", + "endpoint": "ai-ghibli-style", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "ai-image-extension", + "name": "AI Image Extension", + "endpoint": "ai-image-extension", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "ai-object-eraser", + "name": "AI Object Eraser", + "endpoint": "ai-object-eraser", + "family": "tools", + "imageField": "image_url", + "hasPrompt": false, + "inputs": {} + }, + { + "id": "flux-kontext-pro-i2i", + "name": "Flux Kontext Pro I2I", + "endpoint": "flux-kontext-pro-i2i", + "family": "kontext", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Transform into a digital painting, soft fur texture, dreamy pastel colors" + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "21:9", + "16:21" + ], + "default": "1:1" + } + } + }, + { + "id": "flux-kontext-max-i2i", + "name": "Flux Kontext Max I2I", + "endpoint": "flux-kontext-max-i2i", + "family": "kontext", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Re-render in a luxury studio setting, reflective surface, high contrast shadows, ad campaign look." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "21:9", + "16:21" + ], + "default": "1:1" + } + } + }, + { + "id": "gpt4o-image-to-image", + "name": "GPT-4o Image To Image", + "endpoint": "gpt4o-image-to-image", + "family": "gpt", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Convert this sunny park photo into a snowy winter scene, with snow-covered trees, cloudy skies, and people in winter coats." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "2:3", + "3:2" + ], + "default": "1:1" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "enum": [ + 1, + 2, + 4 + ], + "default": 1 + } + } + }, + { + "id": "gpt4o-edit", + "name": "GPT-4o Edit", + "endpoint": "gpt4o-edit", + "family": "gpt", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Replace the barista with a humanoid robot in a sleek metallic design." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "2:3", + "3:2" + ], + "default": "1:1" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "enum": [ + 1, + 2, + 4 + ], + "default": 1 + } + } + }, + { + "id": "midjourney-v7-image-to-image", + "name": "Midjourney v7 Image To Image", + "endpoint": "midjourney-v7-image-to-image", + "family": "midjourney", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the image", + "examples": [ + "Make the scene sunrise instead of stormy, with soft lighting and a peaceful mood" + ] + }, + "speed": { + "type": "string", + "title": "Speed", + "name": "speed", + "description": "The speed of which corresponds to different speed of Midjourney", + "enum": [ + "relaxed", + "fast", + "turbo" + ], + "default": "relaxed" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "3:4", + "4:3", + "1:2", + "2:1", + "2:3", + "3:2", + "5:6", + "6:5" + ], + "default": "1:1" + }, + "variety": { + "type": "int", + "title": "Variety", + "name": "variety", + "description": "Controls the diversity of generated images. Increment by 5 each time. Higher values create more diverse results. Lower values create more consistent results.", + "default": 5, + "minValue": 0, + "maxValue": 100, + "step": 5 + }, + "stylization": { + "type": "int", + "title": "Stylization", + "name": "stylization", + "description": "Controls the artistic style intensity. Higher values create more stylized results. Lower values create more realistic results.", + "default": 1, + "minValue": 0, + "maxValue": 1000, + "step": 1 + }, + "weirdness": { + "type": "int", + "title": "Weirdness", + "name": "weirdness", + "description": "Controls the creativity and uniqueness. Higher values create more unusual results. Lower values create more conventional results.", + "default": 1, + "minValue": 0, + "maxValue": 3000, + "step": 1 + } + } + }, + { + "id": "bytedance-seededit-v3", + "name": "Bytedance Seededit v3", + "endpoint": "bytedance-seededit-image", + "family": "seedream", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Change the outfit to a red evening gown with elegant styling, matching the reference image's pose and lighting." + ] + } + } + }, + { + "id": "midjourney-v7-style-reference", + "name": "Midjourney v7 Style Reference", + "endpoint": "midjourney-v7-style-reference", + "family": "midjourney", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the image", + "examples": [ + "A futuristic city built on waterfalls, glowing towers in the mist, colorful sky at dusk, cinematic lighting, hyper-detailed architecture." + ] + }, + "speed": { + "type": "string", + "title": "Speed", + "name": "speed", + "description": "The speed of which corresponds to different speed of Midjourney", + "enum": [ + "relaxed", + "fast", + "turbo" + ], + "default": "relaxed" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "3:4", + "4:3", + "1:2", + "2:1", + "2:3", + "3:2", + "5:6", + "6:5" + ], + "default": "1:1" + }, + "variety": { + "type": "int", + "title": "Variety", + "name": "variety", + "description": "Controls the diversity of generated images. Increment by 5 each time. Higher values create more diverse results. Lower values create more consistent results.", + "default": 5, + "minValue": 0, + "maxValue": 100, + "step": 5 + }, + "stylization": { + "type": "int", + "title": "Stylization", + "name": "stylization", + "description": "Controls the artistic style intensity. Higher values create more stylized results. Lower values create more realistic results.", + "default": 1, + "minValue": 0, + "maxValue": 1000, + "step": 1 + }, + "weirdness": { + "type": "int", + "title": "Weirdness", + "name": "weirdness", + "description": "Controls the creativity and uniqueness. Higher values create more unusual results. Lower values create more conventional results.", + "default": 1, + "minValue": 0, + "maxValue": 3000, + "step": 1 + } + } + }, + { + "id": "midjourney-v7-omni-reference", + "name": "Midjourney v7 Omni Reference", + "endpoint": "midjourney-v7-omni-reference", + "family": "midjourney", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the image", + "examples": [ + "A futuristic samurai girl exploring an ancient overgrown temple in a neon-lit jungle, glowing plants surrounding her, mist in the air, cinematic composition." + ] + }, + "speed": { + "type": "string", + "title": "Speed", + "name": "speed", + "description": "The speed of which corresponds to different speed of Midjourney", + "enum": [ + "relaxed", + "fast", + "turbo" + ], + "default": "relaxed" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "3:4", + "4:3", + "1:2", + "2:1", + "2:3", + "3:2", + "5:6", + "6:5" + ], + "default": "1:1" + }, + "weight": { + "type": "int", + "title": "Weight", + "name": "weight", + "description": "Weight allows you to control how much detail from your reference image appears in your new image.", + "default": 100, + "minValue": 1, + "maxValue": 1000, + "step": 1 + }, + "variety": { + "type": "int", + "title": "Variety", + "name": "variety", + "description": "Controls the diversity of generated images. Increment by 5 each time. Higher values create more diverse results. Lower values create more consistent results.", + "default": 5, + "minValue": 0, + "maxValue": 100, + "step": 5 + }, + "stylization": { + "type": "int", + "title": "Stylization", + "name": "stylization", + "description": "Controls the artistic style intensity. Higher values create more stylized results. Lower values create more realistic results.", + "default": 1, + "minValue": 0, + "maxValue": 1000, + "step": 1 + }, + "weirdness": { + "type": "int", + "title": "Weirdness", + "name": "weirdness", + "description": "Controls the creativity and uniqueness. Higher values create more unusual results. Lower values create more conventional results.", + "default": 1, + "minValue": 0, + "maxValue": 3000, + "step": 1 + } + } + }, + { + "id": "minimax-image-01-subject-reference", + "name": "Minimax Image 01 Subject Reference", + "endpoint": "minimax-01-subject-reference", + "family": "minimax", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image (max 1500 characters).", + "examples": [ + "Generate the same person dressed in Renaissance-style attire, standing in a candlelit castle hall with ornate tapestries and warm low lighting." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "3:2", + "2:3", + "21:9" + ], + "default": "1:1" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "default": 1, + "minValue": 1, + "maxValue": 4, + "step": 1 + } + } + }, + { + "id": "ideogram-character", + "name": "Ideogram Character", + "endpoint": "ideogram-character", + "family": "ideogram", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image (max 1500 characters).", + "examples": [ + "Create the same character as a medieval knight standing in a candlelit castle corridor, wearing chainmail and holding a torch." + ] + }, + "render_speed": { + "type": "string", + "title": "Render Speed", + "name": "render_speed", + "description": "The rendering speed to use.", + "enum": [ + "Turbo", + "Balanced", + "Quality" + ], + "default": "Balanced" + }, + "style": { + "type": "string", + "title": "Style", + "name": "style", + "description": "The style type to generate with.", + "enum": [ + "Auto", + "Realistic", + "Fiction" + ], + "default": "Auto" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "1:1" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "default": 1, + "minValue": 1, + "maxValue": 4, + "step": 1 + } + } + }, + { + "id": "flux-pulid", + "name": "Flux Pulid", + "endpoint": "flux-pulid", + "family": "flux", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image (max 1500 characters).", + "examples": [ + "Recreate the same person in a Renaissance-style painting with ornate collar and soft candlelight ambiance." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "1:1" + } + } + }, + { + "id": "qwen-image-edit", + "name": "Qwen Image Edit", + "endpoint": "qwen-image-edit", + "family": "qwen", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Replace the field with a snowy mountain landscape." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "21:9", + "9:21", + "3:2", + "2:3" + ], + "default": "1:1" + } + } + }, + { + "id": "image-effects", + "name": "Image Effects", + "endpoint": "image-effects", + "family": "effects", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "name": { + "type": "string", + "title": "Effect Name", + "name": "name", + "description": "The type of effect to apply to the image.", + "enum": [ + "Acryclic Ornaments", + "Advanced Photography", + "American Comic Style", + "Angel Figurine", + "Blurry Selfie", + "Cyberpunk", + "Exotic Charm", + "Felt 3D Polaroid", + "Felt Keychain", + "Furry Dream Doll", + "Futuristic American Comics", + "Glass Ball", + "In The Stadium", + "Lofi Pixel Character", + "Lying On Fluffy Belly", + "Landscape Mini World", + "My World", + "Plastic Bubble Figure" + ], + "default": "Angel Figurine" + } + } + }, + { + "id": "nano-banana-edit", + "name": "Nano Banana Edit", + "endpoint": "nano-banana-edit", + "family": "nano", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Change her facial expression to a confident smile, and adjust the lighting to dramatic blue and purple hues. Keep her hairstyle and outfit consistent across multiple edits." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "Auto", + "1:1", + "3:4", + "4:3", + "9:16", + "16:9", + "3:2", + "2:3", + "5:4", + "4:5", + "21:9" + ], + "default": "Auto" + } + } + }, + { + "id": "ideogram-v3-reframe", + "name": "Ideogram v3 Reframe", + "endpoint": "ideogram-v3-reframe", + "family": "ideogram", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "1:1" + }, + "render_speed": { + "type": "string", + "title": "Render Speed", + "name": "render_speed", + "description": "The rendering speed to use.", + "enum": [ + "Turbo", + "Balanced", + "Quality" + ], + "default": "Balanced" + }, + "style": { + "type": "string", + "title": "Style", + "name": "style", + "description": "The style type to generate with.", + "enum": [ + "Auto", + "General", + "Realistic", + "Design" + ], + "default": "Auto" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "default": 1, + "minValue": 1, + "maxValue": 4, + "step": 1 + } + } + }, + { + "id": "bytedance-seedream-edit-v4", + "name": "Bytedance Seedream Edit v4", + "endpoint": "bytedance-seedream-edit-v4", + "family": "seedream", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "A tranquil shoreline at dawn where waves turn into glowing ribbons of light, painting the sky with dreamlike hues of violet and gold. A figure walks along the edge, leaving footsteps that bloom into luminous flowers, symbolizing imagination flowing seamlessly into reality." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "3:4", + "4:3", + "2:3", + "3:2", + "21:9" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "Resolution of the output image.", + "enum": [ + "1K", + "2K", + "4K" + ], + "default": "4K" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "default": 1, + "minValue": 1, + "maxValue": 4, + "step": 1 + } + } + }, + { + "id": "nano-banana-effects", + "name": "Nano Banana Effects", + "endpoint": "nano-banana-effects", + "family": "nano", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "name": { + "type": "string", + "title": "Effect Name", + "name": "name", + "description": "The type of effect to apply to the image.", + "enum": [ + "3D Figurine", + "16bit Game Character", + "1920s Decade", + "1950s Decade", + "1970s Decade", + "1980s Decade", + "Action Figure", + "American Gothic Art", + "Egypts Landmark", + "Eiffel Tower Landmark", + "Famous Art", + "Great Wall of China Landmark", + "Mona Lisa Art", + "Persistent Memory Art", + "Statue of Liberty Landmark", + "Taj Mahal Landmark", + "Vincent Van Gogh Art" + ], + "default": "3D Figurine" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "Auto", + "1:1", + "3:4", + "4:3", + "9:16", + "16:9", + "3:2", + "2:3", + "5:4", + "4:5", + "21:9" + ], + "default": "Auto" + } + } + }, + { + "id": "flux-kontext-effects", + "name": "Flux Kontext Effects", + "endpoint": "flux-kontext-effects", + "family": "kontext", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "20 years older" + ] + }, + "name": { + "type": "string", + "title": "Effect Name", + "name": "name", + "description": "The type of effect to apply to the image.", + "enum": [ + "Age Progression", + "Background Change", + "Cartoonify", + "Color Correction", + "Expression Change", + "Face Enhancement", + "Hair Change", + "Object Removal", + "Professional Photo", + "Scene Composition", + "Style Transfer", + "Time of Day", + "Weather Effect" + ], + "default": "Age Progression" + } + } + }, + { + "id": "flux-redux", + "name": "Flux Redux", + "endpoint": "flux-redux", + "family": "flux", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image (max 1500 characters).", + "examples": [ + "Reimagine the forest cabin as a mystical fantasy retreat at twilight, glowing lanterns hanging from the trees, magical fireflies in the air, cinematic atmosphere with enchanted vibes." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "3:2", + "2:3", + "21:9", + "9:21" + ], + "default": "1:1" + }, + "num_images": { + "type": "int", + "title": "Number of images", + "name": "num_images", + "description": "Number of images generated in single request. Each number will charge separately", + "default": 1, + "minValue": 1, + "maxValue": 4, + "step": 1 + } + } + }, + { + "id": "qwen-image-edit-plus", + "name": "Qwen Image Edit Plus", + "endpoint": "qwen-image-edit-plus", + "family": "qwen", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Replace the watch strap with a rich brown leather band, add subtle engravings on the bezel, increase the contrast slightly, and warm the overall lighting to golden-hour tones, keeping reflections realistic." + ] + }, + "width": { + "type": "int", + "title": "Width", + "name": "width", + "description": "Width of the output image.", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + }, + "height": { + "type": "int", + "title": "Height", + "name": "height", + "description": "Height of the output image.", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + } + } + }, + { + "id": "wan2.5-image-edit", + "name": "Wan2.5 Image Edit", + "endpoint": "wan2.5-image-edit", + "family": "wan2.5", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Reimagine the scene under a raging thunderstorm at night: lightning forks across the sky, illuminating the samurai in stark flashes of white light." + ] + }, + "width": { + "type": "int", + "title": "Width", + "name": "width", + "description": "Width of the output image.", + "default": 2048, + "minValue": 384, + "maxValue": 5000, + "step": 1 + }, + "height": { + "type": "int", + "title": "Height", + "name": "height", + "description": "Height of the output image.", + "default": 2048, + "minValue": 384, + "maxValue": 5000, + "step": 1 + } + } + }, + { + "id": "higgsfield-soul-image-to-image", + "name": "Higgsfield Soul Image To Image", + "endpoint": "higgsfield-soul-image-to-image", + "family": "higgsfield", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image (max 1500 characters).", + "examples": [ + "Transform into a cinematic editorial portrait — same woman now in a Parisian café at dusk, with soft neon reflections on the window, elegant lighting, subtle film grain. Style preset: Evening Editorial." + ] + }, + "style": { + "type": "string", + "title": "Style", + "name": "style", + "description": "Choose preset for soul image generation.", + "enum": [ + "Creatures", + "Medieval", + "Spotlight", + "Giant People", + "Red balloon", + "green editorial", + "Subway", + "Library", + "Realistic", + "DigitalCam", + "Grillz Selfie", + "Bleached Brows", + "Sitting on the Street", + "Crossing the street", + "Angel Wings", + "Duplicate", + "cocktail", + "Quiet luxury", + "Fireproof", + "Elevator Mirror", + "360 cam", + "Glitch", + "FashionShow", + "PixeletedFace", + "Sunbathing", + "Paper Face", + "90s Grain", + "Geominimal", + "Foggy Morning", + "Overexposed", + "Sunset beach", + "Giant Accessory", + "RingSelfie", + "Street view", + "90’s Editorial", + "Rhyme & blues", + "2000s Cam", + "CCTV", + "0.5 Outfit", + "Amalfi Summer", + "Bimbocore", + "0.5 Selfie", + "Sand", + "Vintage PhotoBooth", + "afterparty cam", + "Babydoll MakeUp", + "Through The Glass", + "Gallery", + "Eating Food", + "Swords Hill", + "Office beach", + "Help It's Too Big", + "Japandi", + "iPhone", + "Gorpcore", + "Indie sleaze", + "Fairycore", + "Tumblr", + "Avant-garde", + "HairClips", + "birthday mess", + "Clouded Dream", + "Y2K Posters", + "tokyo drift", + "Object Makeup", + "Graffiti", + "Sunburnt", + "hallway noir", + "2000s Fashion", + "Night Beach", + "Movie", + "Long legs", + "7\\", + "General", + "Nail Check", + "Coquette core", + "Mixed Media", + "Selfcare", + "Grunge", + "Double take", + "505room", + "Flight mode", + "Escalator", + "burgundy suit", + "Fisheye", + "Shoe Check", + "Rainy Day", + "Mt. Fuji", + "Sea breeze", + "Invertethereal", + "Y2K", + "Tokyo Streetstyle", + "chrome exit", + "Night rider", + "Artwork", + "Glazed doll skin makeup", + "mount view", + "2049", + "blackout fit", + "Bike mafia", + "static glow", + "Nicotine glow", + "brick shade", + "dmv", + "Fish-eye twin", + "It’s french" + ], + "default": "DigitalCam" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "4:5", + "5:4", + "21:9", + "9:21" + ], + "default": "9:16" + }, + "strength": { + "type": "int", + "title": "Strength", + "name": "strength", + "description": "The strength to use for the style.", + "default": 0.5, + "minValue": 0, + "maxValue": 1, + "step": 0.01 + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The resolution of the output image.", + "enum": [ + "medium", + "high" + ], + "default": "medium" + } + } + }, + { + "id": "reve-image-edit", + "name": "Reve Image Edit", + "endpoint": "reve-image-edit", + "family": "reve", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "A photorealistic fantasy portrait, transforming the woman in the image into an elegant high elf. Give her long, gracefully pointed ears that peek through her hair. Her skin has a subtle, ethereal glow. Replace her white blazer and necklaces with ornate, flowing elven robes made of shimmering silver fabric and intricate leaf patterns. The background is a mystical, twilight forest with glowing magical flora. **CRITICAL:** Maintain her exact original pose, serene smiling expression, and facial structure. Cinematic lighting, masterpiece, hyper-detailed." + ] + } + } + }, + { + "id": "topaz-image-upscale", + "name": "Topaz Image Upscale", + "endpoint": "topaz-image-upscale", + "family": "topaz", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "upscale_factor": { + "type": "string", + "title": "Upscale Factor", + "name": "upscale_factor", + "description": "Factor to upscale the image by (e.g. 2.0 doubles width and height).", + "enum": [ + 1, + 2, + 4, + 8 + ], + "default": 2 + } + } + }, + { + "id": "seedvr2-image-upscale", + "name": "Seedvr2 Image Upscale", + "endpoint": "seedvr2-image-upscale", + "family": "seedvr2", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The target resolution of the generated image.", + "enum": [ + "2k", + "4k", + "8k" + ], + "default": "4k" + } + } + }, + { + "id": "qwen-image-edit-plus-lora", + "name": "Qwen Image Edit Plus Lora", + "endpoint": "qwen-image-edit-plus-lora", + "family": "qwen", + "imageField": "images_list", + "hasPrompt": false, + "inputs": { + "rotate_right_left": { + "type": "int", + "title": "Rotate Right-Left (degrees°)", + "name": "rotate_right_left", + "description": "Rotate camera left (positive) or right (negative) in degrees. Positive values rotate left, negative values rotate right.", + "default": 0, + "minValue": -90, + "maxValue": 90, + "step": 1 + }, + "move_forward": { + "type": "int", + "title": "Move Forward → Close-Up", + "name": "move_forward", + "description": "Move camera forward (0=no movement, 10=close-up)", + "default": 0, + "minValue": 0, + "maxValue": 10, + "step": 0.1 + }, + "vertical_angle": { + "type": "int", + "title": "Vertical Angle (Bird ⬄ Worm)", + "name": "vertical_angle", + "description": "Adjust vertical camera angle (-1=bird's eye view/looking down, 0=neutral, 1=worm's-eye view/looking up)", + "default": 0, + "minValue": -1, + "maxValue": 1, + "step": 0.1 + }, + "wide_angle_lens": { + "type": "boolean", + "title": "Wide-Angle Lens", + "name": "wide_angle_lens", + "description": "Enable wide-angle lens effect", + "default": false + }, + "width": { + "type": "int", + "title": "Width", + "name": "width", + "description": "Width of the output image.", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + }, + "height": { + "type": "int", + "title": "Height", + "name": "height", + "description": "Height of the output image.", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + } + } + }, + { + "id": "nano-banana-pro-edit", + "name": "Nano Banana Pro Edit", + "endpoint": "nano-banana-pro-edit", + "family": "nano", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Keep the same scene and subject, but change the lighting to warm golden sunset tones, remove the neon signs, add soft sunlight beams from the side, enhance surface details, keep reflections subtle and natural." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "3:4", + "4:3", + "9:16", + "16:9", + "3:2", + "2:3", + "5:4", + "4:5", + "21:9" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The target resolution of the generated image.", + "enum": [ + "1k", + "2k", + "4k" + ], + "default": "1k" + } + } + }, + { + "id": "image-passthrough", + "name": "Image Passthrough", + "endpoint": "image-passthrough", + "family": "image", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "make_input": { + "type": "boolean", + "title": "Make Input", + "name": "make_input", + "default": true + } + } + }, + { + "id": "kling-o1-edit-image", + "name": "Kling O1 Edit Image", + "endpoint": "kling-o1-edit-image", + "family": "kling-o1", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Replace the hanging lanterns with floating bioluminescent orbs that emit soft cyan light, keep the garden composition and city reflections unchanged, ensure the orbs cast subtle cyan rim-light on nearby leaves and glass, preserve overall twilight mood and depth of field." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "auto", + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "2:3", + "3:2", + "21:9" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The target resolution of the generated image.", + "enum": [ + "1k", + "2k" + ], + "default": "1k" + } + } + }, + { + "id": "flux-2-dev-edit", + "name": "Flux 2 Dev Edit", + "endpoint": "flux-2-dev-edit", + "family": "flux-2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Replace the floating stained-glass cathedral with a colossal crystal tree glowing from within, while keeping the stormy sky, ocean waves, rainbow reflections, and dramatic lighting intact." + ] + }, + "width": { + "type": "int", + "title": "Width", + "name": "width", + "description": "Width of the output image.", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + }, + "height": { + "type": "int", + "title": "Height", + "name": "height", + "description": "Height of the output image.", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + } + } + }, + { + "id": "flux-2-flex-edit", + "name": "Flux 2 Flex Edit", + "endpoint": "flux-2-flex-edit", + "family": "flux-2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Replace the molten gold in the lower chamber with a swirling vortex of glowing sapphire mist, keep the crystal panels, star map, orbiting metallic rings, and aurora sky unchanged, ensure the new mist casts cool blue highlights and interacts naturally with the surrounding lightning." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "auto", + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "2:3", + "3:2" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The target resolution of the generated image.", + "enum": [ + "1k", + "2k" + ], + "default": "1k" + } + } + }, + { + "id": "flux-2-pro-edit", + "name": "Flux 2 Pro Edit", + "endpoint": "flux-2-pro-edit", + "family": "flux-2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Replace the central spherical chronometer with a floating crystalline lotus emitting soft golden light, keep the asteroid chamber, star charts, cosmic dust streams, and prismatic beams unchanged, ensure the lotus casts warm highlights and seamlessly integrates with the scene’s lighting." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "auto", + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "2:3", + "3:2" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The target resolution of the generated image.", + "enum": [ + "1k", + "2k" + ], + "default": "1k" + } + } + }, + { + "id": "vidu-q2-reference-to-image", + "name": "Vidu Q2 Reference To Image", + "endpoint": "vidu-q2-reference-to-image", + "family": "vidu-q2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Create a new scene where the masked wanderer stands inside an ancient stone observatory illuminated by rotating celestial beams; preserve the character’s clothing style and silhouette while adding glowing runes carved into the walls, mist swirling across the floor, and a dramatic cosmic light shaft from above; cinematic composition, high detail." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "auto", + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "2:3", + "3:2", + "21:9" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The target resolution of the generated image.", + "enum": [ + "1k", + "2k", + "4k" + ], + "default": "1k" + } + } + }, + { + "id": "bytedance-seedream-v4.5-edit", + "name": "Bytedance Seedream v4.5 Edit", + "endpoint": "bytedance-seedream-v4.5-edit", + "family": "seedream-v45", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Replace the glowing amethyst flame at the tower’s peak with a levitating orb of swirling turquoise water, keeping the spiral tower, crystalline desert, floating shards, and aurora-lit sky unchanged; ensure the water orb emits cool reflections and integrates naturally with the existing lighting." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "4:3", + "3:4", + "2:3", + "3:2", + "21:9" + ], + "default": "1:1" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "Quality of the output image.", + "enum": [ + "basic", + "high" + ], + "default": "basic" + } + } + }, + { + "id": "qwen-image-edit-2511", + "name": "Qwen Image Edit 2511", + "endpoint": "qwen-image-edit-2511", + "family": "qwen", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Replace the glass observatory with a floating bronze astrolabe composed of interlocking rings and engraved symbols, keep the glowing desert, dusk sky, dust trails, and lighting unchanged; ensure the bronze surface reflects the warm sunset tones naturally and integrates seamlessly with the scene." + ] + }, + "width": { + "type": "integer", + "title": "Width", + "name": "width", + "description": "Width of the image in pixels", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + }, + "height": { + "type": "integer", + "title": "Height", + "name": "height", + "description": "Height of the image in pixels", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + } + } + }, + { + "id": "wan2.6-image-edit", + "name": "Wan2.6 Image Edit", + "endpoint": "wan2.6-image-edit", + "family": "wan2.6", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Replace the glowing crystal spires with towering living trees made of luminous jade leaves and silver bark, keep the floating citadel structure, ocean reflections, mist, moonlight, and twilight color palette unchanged; ensure the new trees cast soft green highlights that blend naturally with the existing lighting." + ] + } + } + }, + { + "id": "qwen-text-to-image-2512", + "name": "Qwen Text To Image 2512", + "endpoint": "qwen-text-to-image-2512", + "family": "qwen", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "A colossal biomechanical whale swimming slowly through a vast sky made of soft clouds and fractured light. Its translucent body reveals glowing internal organs shaped like rotating gears and flowing energy veins. Below it, a sprawling patchwork of farmland and rivers curves with the planet’s surface, catching reflections from the whale’s luminous glow. Long fabric banners trail from the whale’s fins, fluttering gently in the wind like ceremonial streamers. The camera angle is wide and aerial, emphasizing scale and serenity. Soft sunrise colors, cinematic depth, ultra-detailed surreal sci-fi atmosphere." + ] + }, + "width": { + "type": "integer", + "title": "Width", + "name": "width", + "description": "Width of the image in pixels", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + }, + "height": { + "type": "integer", + "title": "Height", + "name": "height", + "description": "Height of the image in pixels", + "default": 1024, + "minValue": 256, + "maxValue": 1536, + "step": 1 + } + } + }, + { + "id": "gpt-image-1.5-edit", + "name": "Gpt Image 1.5 Edit", + "endpoint": "gpt-image-1.5-edit", + "family": "gpt-1.5", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt for edit image.", + "examples": [ + "Replace the abandoned car with a sleek autonomous electric vehicle made of brushed metal and soft glowing panels, keep the desert highway, sunset lighting, heat distortion, power lines, and approaching storm unchanged; ensure reflections and shadows match the original environment naturally." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "2:3", + "3:2" + ], + "default": "1:1" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The quality of the generated image.", + "enum": [ + "low", + "medium", + "high" + ], + "default": "medium" + } + } + }, + { + "id": "grok-imagine-image-to-image", + "name": "Grok Imagine Image To Image", + "endpoint": "grok-imagine-image-to-image", + "family": "grok", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image.", + "examples": [ + "Replace the arriving train with a silent magnetic levitation transit pod made of matte white composite and glass, keep the platform, people, lighting, reflections, and urban environment unchanged; ensure the new vehicle fits naturally into the scene with correct scale, shadows, and motion blur." + ] + } + } + }, + { + "id": "Api Node", + "name": "Api Node", + "endpoint": "Api Node", + "family": "wavespeed", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "model_url": { + "type": "string", + "title": "Model URL", + "name": "model_url", + "description": "Url of the wavespeed model", + "examples": [ + "" + ] + }, + "api_key": { + "type": "string", + "title": "API Key", + "name": "api_key", + "description": "API key for authentication", + "examples": [ + "" + ] + } + } + }, + { + "id": "flux-2-klein-4b-edit", + "name": "Flux 2 Klein 4b Edit", + "endpoint": "flux-2-klein-4b-edit", + "family": "flux-2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Add a tiny blue knitted scarf around the kitten’s neck, keep the kitten’s pose, table, lighting, and cozy indoor environment unchanged; make the scarf soft and cute, fitting naturally without covering the kitten’s face." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "The aspect ratio of the generated image", + "enum": [ + "16:9", + "9:16", + "1:1", + "3:4", + "4:3", + "21:9", + "9:21" + ], + "default": "1:1" + } + } + }, + { + "id": "flux-2-klein-9b-edit", + "name": "Flux 2 Klein 9b Edit", + "endpoint": "flux-2-klein-9b-edit", + "family": "flux-2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the image, what you want the final edited image to look like.", + "examples": [ + "Add a small red bow tie around the puppy’s neck, slightly fluffy fabric texture, keep the puppy’s pose, facial expression, sofa, lighting, and living room environment unchanged; ensure the bow tie matches the warm lighting and looks naturally placed." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "The aspect ratio of the generated image", + "enum": [ + "16:9", + "9:16", + "1:1", + "3:4", + "4:3", + "21:9", + "9:21" + ], + "default": "1:1" + } + } + }, + { + "id": "add-image-watermark", + "name": "Add Image Watermark", + "endpoint": "add-image-watermark", + "family": "watermark", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "position": { + "type": "string", + "title": "Position", + "name": "position", + "description": "Position of the watermark on the image", + "enum": [ + "top-left", + "top-right", + "bottom-left", + "bottom-right", + "center" + ], + "default": "bottom-right" + }, + "opacity": { + "type": "number", + "title": "Opacity", + "name": "opacity", + "description": "Watermark transparency (0 = invisible, 1 = fully opaque)", + "default": 0.7 + }, + "scale": { + "type": "number", + "title": "Scale", + "name": "scale", + "description": "Watermark size relative to image (0.1 = 10%, 1.0 = 100%)", + "default": 0.2 + } + } + } +]; + +// Auto-generated from schema_data.json — Image to Video models +export const i2vModels = [ + { + "id": "ai-video-effects", + "name": "AI Video Effects", + "endpoint": "generate_wan_ai_effects", + "family": "effects", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to insert into the predefined prompt template for the selected effect.", + "examples": [ + "a cute kitten" + ] + }, + "name": { + "type": "string", + "title": "Effect Type", + "name": "name", + "description": "The type of effect to apply to the video.", + "enum": [ + "360 Rotation", + "Abandoned Places", + "Angry", + "Animal Documentary", + "Assassin It", + "Baby It", + "Boxing", + "Bride It", + "Cakeify", + "Cartoon Jaw Drop", + "Cats", + "Crush It", + "Crying", + "Cyberpunk 2077", + "Deflate It", + "Disney Princess It", + "Dogs", + "Eye Close-Up", + "Fantasy Landscapes", + "Film Noir", + "Fire", + "Glamor", + "Goblin", + "Gun Reveal", + "Hug Jesus", + "Hulk Transformation", + "Inflate It", + "Jungle It", + "Jumpscare", + "Kamehameha", + "Kiss Cam", + "Kissing", + "Lego", + "Laughing", + "Little Planet", + "Live Wallpaper", + "Looping Pixel Art", + "Melt It", + "Mona Lisa It", + "Museum It", + "Muscle Show Off", + "Orc", + "Pixar", + "Pirate Captain", + "POV Driving", + "Princess It", + "Puppy it", + "Robotic Face Reveal", + "Samurai It", + "Sharingan Eyes", + "Skyrim Fus-Ro-Dah", + "Snow White It", + "Squish It", + "Steamboat Willie", + "Super Saiyan Transformation", + "Tsunami", + "Ultra Wide", + "VHS Footage", + "VIP It", + "Warrior It", + "Wind Blast", + "Younger Self Selfie", + "Zen It", + "Zoom Call" + ], + "default": "Cakeify" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The quality of the generated video.", + "enum": [ + "medium", + "high" + ], + "default": "medium" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10 + ], + "default": 5 + } + } + }, + { + "id": "motion-controls", + "name": "Motion Controls", + "endpoint": "generate_wan_ai_effects", + "family": "effects", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to insert into the predefined prompt template for the selected effect.", + "examples": [ + "a blueberry person" + ] + }, + "name": { + "type": "string", + "title": "Effect Type", + "name": "name", + "description": "The type of effect to apply to the video.", + "enum": [ + "360 Orbit", + "Arc Shot", + "Car Chase", + "Car Mount Cam", + "Crash Zoom In", + "Crash Zoom Out", + "Crane Down", + "Crane Overhead", + "Crane Punch-In", + "Crane Up", + "Dirty Lens", + "Dolly In", + "Dolly Left", + "Dolly Out", + "Dolly Right", + "Dolly Zoom In", + "Dolly Zoom Out", + "Dutch Angle", + "Fast Dolly Zoom In", + "Fast Dolly Zoom Out", + "Fisheye Lens", + "Focus Shift", + "FPV Drone Cam", + "Handheld Cam", + "Head Tracking", + "Hero Run", + "Human Timelapse", + "Landscape Timelapse", + "Lazy Susan", + "Lens Crac", + "Lens Flare", + "Matrix Shot", + "Motion Blur", + "Object POV", + "Overhead", + "Rap Video Cam", + "Robotic Cam", + "Snorricam", + "Tilt Down", + "Tilt Up", + "Whip Pan", + "Wiggle", + "Zoom In", + "Zoom In Through Object", + "Zoom Into Mouth", + "Zoom Out", + "Zoom Out Through Object" + ], + "default": "360 Orbit" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The quality of the generated video.", + "enum": [ + "medium", + "high" + ], + "default": "medium" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10 + ], + "default": 5 + } + } + }, + { + "id": "vfx", + "name": "VFX", + "endpoint": "generate_wan_ai_effects", + "family": "effects", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to insert into the predefined prompt template for the selected effect.", + "examples": [ + "a Mercedes bench car" + ] + }, + "name": { + "type": "string", + "title": "Effect Type", + "name": "name", + "description": "The type of effect to apply to the video.", + "enum": [ + "Building Explosion", + "Car Explosion", + "Decay Time-Lapse", + "Disintegration", + "Electricity", + "Flying", + "Huge Explosion", + "Levitate", + "Tornado" + ], + "default": "Car Explosion" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The quality of the generated video.", + "enum": [ + "medium", + "high" + ], + "default": "medium" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10 + ], + "default": 5 + } + } + }, + { + "id": "veo3-image-to-video", + "name": "Veo3 Image To Video", + "endpoint": "veo3-image-to-video", + "family": "veo", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the desired video content.", + "examples": [ + "On a neon-lit street corner, a hyped street performer with a mic shouts: 'Yo! Big drop today! VEO3 just launched on muapi!' A crowd cheers as holograms of videos burst into the air and the muapi logo spins above." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + } + } + }, + { + "id": "veo3-fast-image-to-video", + "name": "Veo3 Fast Image To Video", + "endpoint": "veo3-fast-image-to-video", + "family": "veo", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the desired video content.", + "examples": [ + "A spaceship hovers over Earth. A digital billboard beams out: 'MuAPI is broadcasting creativity across the galaxy.' A robot host floats in zero gravity holding a prompt card: 'Let’s turn this into a story.' Suddenly, video panels fly around the ship with generated content." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + } + } + }, + { + "id": "runway-image-to-video", + "name": "Runway Image To Video", + "endpoint": "runway-image-to-video", + "family": "runway", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to be used to generate a video", + "examples": [ + "The camera smoothly zooms in on the sleek, futuristic race car as it speeds through a neon-lit urban tunnel at twilight, its glossy white surface reflecting the vibrant pink and blue lights streaking past. The precise detailing of the car’s aerodynamic curves and glowing accents is highlighted as droplets of water spray from the spinning tires, adding a palpable sense of motion and intensity. The driver’s black helmet, contrasted against the car’s gleaming body, remains sharply in focus, emphasizing the thrilling high-speed chase through the city. The blurred cityscape and illuminated digital billboards in the background create a high-tech, cyberpunk atmosphere, intensifying the scene’s adrenaline and futuristic vibe." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video. If 1080p is selected, 8-second video cannot be generated.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration in seconds. If 8-second video is selected, 1080p resolution cannot be used.", + "enum": [ + 5, + 8 + ], + "default": 5 + } + } + }, + { + "id": "wan2.1-image-to-video", + "name": "Wan2.1 Image To Video", + "endpoint": "wan2.1-image-to-video", + "family": "wan2.1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Animate the girl in the painting to blink and look around while her hair moves gently in the wind." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The quality of the generated video.", + "enum": [ + "medium", + "high" + ], + "default": "medium" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "midjourney-v7-image-to-video", + "name": "Midjourney v7 Image To Video", + "endpoint": "midjourney-v7-image-to-video", + "family": "midjourney", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Add slow drifting fog, glowing mushrooms pulsating softly, and subtle camera zoom" + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output image.", + "enum": [ + "1:1", + "16:9", + "9:16", + "3:4", + "4:3", + "1:2", + "2:1", + "2:3", + "3:2", + "5:6", + "6:5" + ], + "default": "1:1" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "1080p" + ], + "default": "480p" + }, + "num_videos": { + "type": "int", + "title": "Number of videos", + "name": "num_videos", + "description": "Number of videos generated in single request. Each number will charge separately", + "enum": [ + 1, + 2, + 4 + ], + "default": 1 + }, + "variety": { + "type": "int", + "title": "Variety", + "name": "variety", + "description": "Controls the diversity of generated images. Increment by 5 each time. Higher values create more diverse results. Lower values create more consistent results.", + "default": 5, + "minValue": 0, + "maxValue": 100, + "step": 5 + }, + "stylization": { + "type": "int", + "title": "Stylization", + "name": "stylization", + "description": "Controls the artistic style intensity. Higher values create more stylized results. Lower values create more realistic results.", + "default": 1, + "minValue": 0, + "maxValue": 1000, + "step": 1 + }, + "weirdness": { + "type": "int", + "title": "Weirdness", + "name": "weirdness", + "description": "Controls the creativity and uniqueness. Higher values create more unusual results. Lower values create more conventional results.", + "default": 1, + "minValue": 0, + "maxValue": 3000, + "step": 1 + } + } + }, + { + "id": "hunyuan-image-to-video", + "name": "Hunyuan Image To Video", + "endpoint": "hunyuan-image-to-video", + "family": "hunyuan", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "The camera begins with a slow, deliberate zoom out from the figure standing on the rain-soaked rooftop, revealing the sleek, armored silhouette clutching a glowing katana that pulses with ominous red light. The deep blues and purples of the wet cityscape set a moody, cyberpunk atmosphere, with neon signs in vibrant pinks, blues, and oranges casting reflections on the glistening surfaces below. The mist and rain softly blur the distant buildings and streetlights, emphasizing the isolation of the lone warrior framed against the sprawling urban expanse. As the camera pulls back, the subtle hum of the futuristic city grows louder, immersing the viewer in a world of tension and anticipation, where danger lurks in the glowing depths of the rain-drenched streets." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + } + } + }, + { + "id": "kling-v2.1-master-i2v", + "name": "Kling v2.1 Master I2V", + "endpoint": "kling-v2.1-master-i2v", + "family": "kling-v2.1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Animates wind effects, camera panning, and subtle movements like blinking or background motion, transforming the image into a compelling cinematic shot." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "kling-v2.1-standard-i2v", + "name": "Kling v2.1 Standard I2V", + "endpoint": "kling-v2.1-standard-i2v", + "family": "kling-v2.1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "A female explorer stands at the edge of a cliff overlooking a dense jungle, her hair and cape rustling gently in the wind as the dramatic sunset casts warm, golden hues across the sky and landscape, capturing a moment of awe and adventure." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "kling-v2.1-pro-i2v", + "name": "Kling v2.1 Pro I2V", + "endpoint": "kling-v2.1-pro-i2v", + "family": "kling-v2.1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "A cyberpunk woman with neon tattoos stands in a rainy alley as glowing signs reflect vividly in puddles around her. Her coat flutters slightly in the breeze, and she makes subtle head movements, capturing the moody, futuristic atmosphere without any scene changes." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "wan2.2-image-to-video", + "name": "Wan2.2 Image To Video", + "endpoint": "wan2.2-image-to-video", + "family": "wan2.2", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "A close-up video of a young woman smiling gently in the rain, with raindrops glistening on her face and eyelashes. The camera focuses on the delicate details of her expression and the shimmering water droplets, while soft light softly reflects off her skin, emphasizing the rainy atmosphere." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "quality": { + "type": "string", + "title": "Quality", + "name": "quality", + "description": "The quality of the generated video.", + "enum": [ + "medium", + "high" + ], + "default": "medium" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds.", + "default": 5, + "minValue": 5, + "maxValue": 8, + "step": 3 + } + } + }, + { + "id": "runway-act-two-i2v", + "name": "Runway Act Two I2V", + "endpoint": "runway-act-two-i2v", + "family": "runway", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4", + "21:9" + ], + "default": "16:9" + } + } + }, + { + "id": "pixverse-v4.5-i2v", + "name": "Pixverse v4.5 I2V", + "endpoint": "pixverse-v4.5-i2v", + "family": "pixverse-v4.5", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "A cat dressed in a sharp business suit stands confidently on a TED Talk stage, delivering an engaging lecture on quantum physics. The audience is filled with attentive dogs wearing glasses, reacting thoughtfully to the presentation. The video features dramatic camera zooms that highlight the cat speaker’s expressions and the intrigued faces of the canine audience, maintaining the setting and characters without altering the scene." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "360p", + "540p", + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds. 8s not supported for 1080p resolution.", + "default": 5, + "minValue": 5, + "maxValue": 8, + "step": 3 + } + } + }, + { + "id": "vidu-v2.0-i2v", + "name": "Vidu v2.0 I2V", + "endpoint": "vidu-v2.0-i2v", + "family": "vidu-v2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "A baby dragon wearing a tiny cape attempts to fly, wobbling uncertainly in the air with playful flaps of its wings, set against a bright and cheerful background. Light, upbeat music plays throughout, capturing the dragon's joyful effort. The video ends with the baby dragon gently crashing in a cute and harmless tumble, smiling and unfazed." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video. 16:9 for 360p/720p, 1:1 for 1080p are supported.", + "enum": [ + "16:9", + "1:1" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "360p", + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds.", + "enum": [ + 4 + ], + "default": 4 + } + } + }, + { + "id": "vidu-q1-reference", + "name": "Vidu Q1 Reference", + "endpoint": "vidu-q1-reference", + "family": "vidu-q1", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the desired video content.", + "examples": [ + "Animate the character walking through the foggy forest at dawn, swinging the sword gracefully. Add cinematic camera pan and soft ambient lighting." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "1:1" + } + } + }, + { + "id": "minimax-hailuo-02-standard-i2v", + "name": "Minimax Hailuo 02 Standard I2V", + "endpoint": "minimax-hailuo-02-standard-i2v", + "family": "minimax-2", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Animate her looking out at the horizon as gentle waves crash, with her hair moving in the wind. Light, smooth motion, perfect for social clips." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 6, + 10 + ], + "default": 6 + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "512P", + "768P" + ], + "default": "512P" + } + } + }, + { + "id": "minimax-hailuo-02-pro-i2v", + "name": "Minimax Hailuo 02 Pro I2V", + "endpoint": "minimax-hailuo-02-pro-i2v", + "family": "minimax-2", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Transform this still image into a dramatic cinematic sequence: the scholar walks slowly through an ancient library where shelves tower endlessly into the shadows. The lantern’s flame flickers, casting moving patterns across scrolls and statues. Dust motes dance in golden light as the camera glides smoothly behind him, then pans upward to reveal an infinite expanse of glowing constellations painted across the ceiling that begin to shimmer and move as if alive." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 6 + ], + "default": 6 + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "1080p" + ], + "default": "1080p" + } + } + }, + { + "id": "video-effects", + "name": "Video Effects", + "endpoint": "video-effects", + "family": "effects", + "imageField": "image_url", + "hasPrompt": false, + "inputs": { + "name": { + "type": "string", + "title": "Effect Name", + "name": "name", + "description": "The type of effect to apply to the video.", + "enum": [ + "Balloon Flyaway", + "Blow Kiss", + "Body Shake", + "Break Glass", + "Carry Me", + "Cartoon Doll", + "Cheek Kiss", + "Child Memory", + "Couple Arrival", + "Fairy Me", + "Fashion Stride", + "Fisherman", + "Flower Receive", + "Flying", + "French Kiss", + "Gender Swap", + "Golden Epoch", + "Hair Swap", + "Hugging", + "Jiggle Up", + "Kissing Pro", + "Live Memory", + "Love Drop", + "Melt", + "Minecraft", + "Muscling", + "Nap Me 360p", + "Paperman", + "Pilot", + "Pinch", + "Pixel Me", + "Romantic Lift", + "Sexy Me", + "Slice Therapy", + "Soul Depart", + "Split Stance Human", + "Squid Game", + "Toy Me", + "Walk Forward", + "Zoom In Fast", + "Zoom Out" + ], + "default": "Balloon Flyaway" + } + } + }, + { + "id": "seedance-lite-i2v", + "name": "Seedance Lite I2V", + "endpoint": "seedance-lite-i2v", + "family": "bytedance", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "A lively dog is running swiftly across a sunlit park, with green trees softly blurred in the background to emphasize quick motion, capturing the energetic and joyful movement during the day." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p", + "1080p" + ], + "default": "480p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 3, + "maxValue": 12, + "step": 1 + }, + "camera_fixed": { + "type": "boolean", + "title": "Camera Fixed", + "name": "camera_fixed", + "description": "Whether to fix the camera position", + "default": false + } + } + }, + { + "id": "seedance-pro-i2v", + "name": "Seedance Pro I2V", + "endpoint": "seedance-pro-i2v", + "family": "bytedance", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "A slow cinematic pan following a knight riding through a dense, foggy forest at dawn, with dramatic lighting casting long shadows and soft rays filtering through the misty trees, emphasizing the mysterious and atmospheric mood." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p", + "1080p" + ], + "default": "480p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 3, + "maxValue": 12, + "step": 1 + }, + "camera_fixed": { + "type": "boolean", + "title": "Camera Fixed", + "name": "camera_fixed", + "description": "Whether to fix the camera position", + "default": false + } + } + }, + { + "id": "pixverse-v5-i2v", + "name": "Pixverse v5 I2V", + "endpoint": "pixverse-v5-i2v", + "family": "pixverse-v5", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Animate the glowing stag slowly walking forward, fireflies drifting in the air, soft mist rolling across the clearing, camera gently circling around for a magical cinematic motion." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "360p", + "540p", + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 8, + "step": 3 + } + } + }, + { + "id": "seedance-lite-reference-video", + "name": "Seedance Lite Reference Video", + "endpoint": "seedance-lite-reference-to-video", + "family": "bytedance", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "The businessman walks towards the sports car on the rooftop, places his hand on the hood, and gazes at the glowing skyline as the camera circles around dramatically, capturing the neon-lit atmosphere in ultra-realism." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 3, + "maxValue": 12, + "step": 1 + } + } + }, + { + "id": "wan2.1-reference-video", + "name": "Wan2.1 Reference Video", + "endpoint": "wan2.1-reference-video", + "family": "wan2.1", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "The motorcycle driving through the neon tunnel, reflections glowing on its body, dynamic tracking shot, cinematic product ad style." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "kling-v2.5-turbo-pro-i2v", + "name": "Kling v2.5 Turbo Pro I2V", + "endpoint": "kling-v2.5-turbo-pro-i2v", + "family": "kling-v2.5", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Animate subtle cloak movement, glowing energy pulsing from the staff, storm clouds rolling above, camera orbiting slightly to add depth and atmosphere." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "wan2.5-image-to-video", + "name": "Wan2.5 Image To Video", + "endpoint": "wan2.5-image-to-video", + "family": "wan2.5", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Animate the scene: camera slowly dollies forward toward the robot, neon city lights begin to flicker, soft reflections shift across the dome glass, twilight deepens into night with subtle ambient glow. The robot raises its head and speaks in a clear futuristic voice: ‘WAN 2.5 is now available on the MuAPI app.’" + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p", + "1080p" + ], + "default": "480p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "wan2.5-image-to-video-fast", + "name": "Wan2.5 Image To Video Fast", + "endpoint": "wan2.5-image-to-video-fast", + "family": "wan2.5", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "The camera slowly pulls back from the portrait, revealing the rooftop garden swaying in the breeze, clouds drifting across the orange-pink sky. The city lights begin to flicker on in the distance as the sun sets. She gazes at the horizon and softly says: “Every ending feels like the start of something new.” Natural ambient sounds of wind and faint city life in the background." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "openai-sora-2-image-to-video", + "name": "Openai Sora 2 Image To Video", + "endpoint": "openai-sora-2-image-to-video", + "family": "sora", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Camera pans along the platform as the bullet train doors open, passengers step forward with rolling suitcases. Footsteps and soft chatter fill the air. A female announcer says: ‘Train number 2245 to Tokyo is now departing from platform 3.’ Wheels screech lightly as the train starts moving." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 10, + 15 + ], + "default": 10 + }, + "remove_watermark": { + "type": "boolean", + "title": "Remove Watermark", + "name": "remove_watermark", + "description": "When enabled, removes watermarks from the generated video.", + "default": true + } + } + }, + { + "id": "ovi-image-to-video", + "name": "Ovi Image To Video", + "endpoint": "ovi-image-to-video", + "family": "ovi", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Camera: static medium shot. The scientist speaks: We have discovered life beyond Earth. Soft electronic hum, distant Beep of instruments" + ] + } + } + }, + { + "id": "openai-sora-2-pro-image-to-video", + "name": "Openai Sora 2 Pro Image To Video", + "endpoint": "openai-sora-2-pro-image-to-video", + "family": "sora", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Scene: Submerged coral clearing, soft light filtering from above.\nCharacters: Tiny jellyfish with monocle and top hat, hosting tea for small seahorses.\nAction: Jellyfish floats and pours tea → bubbles rise slowly; seahorses sip → tiny octopus clumsily serves cake.\nCamera: Wide underwater → tracking floating jellyfish → macro on bubbles.\nLook & Lighting: Aqua-blue palette; subtle caustics on sand; shimmering reflections on water surfaces.\nMotion/Physics: Water currents gently sway characters; bubbles rise naturally; floating cakes wobble lightly.\nAudio: Bubbling water + faint harp melody; line: “Tea, my dear friends, before it drifts away.”" + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds. Currently 25 seconds supports 720p only.", + "enum": [ + 10, + 15, + 25 + ], + "default": 10 + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "remove_watermark": { + "type": "boolean", + "title": "Remove Watermark", + "name": "remove_watermark", + "description": "When enabled, removes watermarks from the generated video.", + "default": true + } + } + }, + { + "id": "leonardoai-motion-2.0", + "name": "Leonardoai Motion 2.0", + "endpoint": "leonardoai-motion-2.0", + "family": "leonardoai", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "A diver swimming through a coral reef, colorful fish darting around, sunlight filtering through the water, slow-motion effect." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + } + } + }, + { + "id": "higgsfield-dop-image-to-video", + "name": "Higgsfield Dop Image To Video", + "endpoint": "higgsfield-dop-image-to-video", + "family": "higgsfield", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Rotate the camera around the scene." + ] + }, + "motion": { + "type": "string", + "title": "Motion", + "name": "motion", + "description": "Terminoogies to use for transform.", + "enum": [ + "360 Orbit", + "3D Rotation", + "Abstract", + "Action Run", + "Agent Reveal", + "Angel Wings", + "Arc Left", + "Arc Right", + "Baseball Kick", + "Basketball Dunks", + "Black Tears", + "Bloom Mouth", + "Boxing", + "Buckle Up", + "Building Explosion", + "Bullet Time", + "Car Chasing", + "Car Explosion", + "Car Grip", + "Catwalk", + "Clone Explosion", + "Crane Down", + "Crane Over The Head", + "Crane Up", + "Crash Zoom In", + "Crash Zoom Out", + "Datamosh", + "Diamond", + "Dirty Lens", + "Disintegration", + "Dolly In", + "Dolly Left", + "Dolly Out", + "Dolly Right", + "Dolly Zoom In", + "Dolly Zoom Out", + "Double Dolly", + "Downhill POV", + "Duplicate", + "Dutch Angle", + "Earth Zoom Out", + "Eyes In", + "Face Punch", + "Fire Breathe", + "Fisheye", + "Floating Fish", + "Flood", + "Floral Eyes", + "Flying", + "Focus Change", + "FPV Drone", + "Freezing", + "Garden Bloom", + "General", + "Glam", + "Glowing Fish", + "Glowshift", + "Handheld", + "Head Explosion", + "Head Off", + "Head Tracking", + "Hyperlapse", + "Incline", + "Innerlight", + "Invisible", + "Jelly Drift", + "Jib Down", + "Jib Up", + "Kiss", + "Lazy Susan", + "Lens Crack", + "Lens Flare", + "Levitation", + "Low Shutter", + "Medusa Gorgona", + "Melting", + "Moonwalk Left", + "Moonwalk Right", + "Morphskin", + "Mouth In", + "Object POV", + "Overhead", + "Paint Splash", + "Paparazzi", + "Powder Explosion", + "Push To Glass", + "Rap Flex", + "Robo Arm", + "Roll Transition", + "Sand Storm", + "Set on Fire", + "Skateboard Glide", + "Skateboard Ollie", + "Skate Cruise", + "Ski Carving", + "Skin Surge", + "Ski Powder", + "Snorricam", + "Snowboard Carving", + "Snowboard Powder", + "Soul Jump", + "Static", + "Super 8MM", + "Super Dolly In", + "Super Dolly Out", + "Tentacles", + "Through Object In", + "Through Object Out", + "Thunder God", + "Tilt Down", + "Tilt up", + "Timelapse Human", + "Timelapse Landscape", + "Turning Metal", + "VHS", + "Whip Pan", + "Wiggle", + "Wind to Face", + "YoYo Zoom", + "Zoom In", + "Zoom Out" + ], + "default": "Bullet Time" + }, + "strength": { + "type": "int", + "title": "Strength", + "name": "strength", + "description": "The strength to use for the motion.", + "default": 1, + "minValue": 0, + "maxValue": 1, + "step": 0.01 + }, + "options": { + "type": "string", + "title": "Options", + "name": "options", + "description": "Model versions.", + "enum": [ + "dop-lite", + "dop-turbo", + "dop-preview" + ], + "default": "dop-lite" + } + } + }, + { + "id": "veo3.1-image-to-video", + "name": "Veo3.1 Image To Video", + "endpoint": "veo3.1-image-to-video", + "family": "veo3.1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Scene: Giant floating library orbiting in zero-gravity space.\nCharacters: Astronaut-librarian flipping glowing pages suspended midair.\nAction: Camera rotates 360° around drifting books → zooms through a floating page into a nebula outside window.\nCamera: Orbit + push-through transition.\nLighting: Cool cosmic ambient with warm page glows; rim lighting on suit.\nMotion: Slow rotational drift; pages react with fluid inertia.\nAudio: Ethereal synth pads + book rustle in vacuum hush.\nMood: Awe, wonder, intellectual calm.\nLine: “Wow veo3.1 launched in Muapiapp. Let's go!”" + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 8 + ], + "default": 8 + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "1080p" + ], + "default": "1080p" + } + } + }, + { + "id": "veo3.1-fast-image-to-video", + "name": "Veo3.1 Fast Image To Video", + "endpoint": "veo3.1-fast-image-to-video", + "family": "veo3.1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Scene: Lantern festival by the river at night.\nCharacters: Young boy with his grandmother.\nAction: Camera starts behind them → tracks one lantern downstream → lift to sky full of lights.\nLighting: Warm candlelight vs cool night reflections.\nAudio: Gentle music, water flow.\nDialogue:\nGrandmother: “Every lantern carries a wish.”\nBoy: “Then mine’s for you to stay forever.”\nGrandmother (smiling): “I’ll be right there, glowing among them.”" + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 8 + ], + "default": 8 + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "1080p" + ], + "default": "1080p" + } + } + }, + { + "id": "veo3.1-reference-to-video", + "name": "Veo3.1 Reference To Video", + "endpoint": "veo3.1-reference-to-video", + "family": "veo3.1", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "A small robotic fox exploring a sun-drenched enchanted forest. The fox hops across a sparkling stream, pauses on mossy rocks, and looks curiously at glowing fireflies. Cinematic camera pans follow the fox from behind, then orbit slightly to reveal sunbeams filtering through the canopy. Warm dappled lighting with volumetric light rays and soft particle effects. Gentle ambient forest sounds and faint magical chimes. Dialogue: ‘Everything shines differently under the forest light…’" + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 8 + ], + "default": 8 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio.", + "default": true + } + } + }, + { + "id": "seedance-pro-i2v-fast", + "name": "Seedance Pro I2V Fast", + "endpoint": "seedance-pro-i2v-fast", + "family": "bytedance", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "The cyberpunk samurai turns slowly toward the camera, raindrops gliding off his glowing armor, neon lights reflecting on wet metal, camera pans around him in a slow 360°, subtle lightning flashes illuminate the skyline." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p", + "1080p" + ], + "default": "480p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 2, + "maxValue": 12, + "step": 1 + }, + "camera_fixed": { + "type": "boolean", + "title": "Camera Fixed", + "name": "camera_fixed", + "description": "Whether to fix the camera position", + "default": false + } + } + }, + { + "id": "ltx-2-pro-image-to-video", + "name": "Ltx 2 Pro Image To Video", + "endpoint": "ltx-2-pro-image-to-video", + "family": "ltx", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "An ancient stone portal deep in an enchanted forest, glowing runes, beams of sunlight breaking through the canopy, cinematic tracking shot, warm colour grading." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 6, + 8, + 10 + ], + "default": 6 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio.", + "default": true + } + } + }, + { + "id": "ltx-2-fast-image-to-video", + "name": "Ltx 2 Fast Image To Video", + "endpoint": "ltx-2-fast-image-to-video", + "family": "ltx", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Image of two explorers standing atop a dune. Now the viewpoint shifts: camera slowly dollies backward while sun rises behind them, sand drifts around feet, warm golden light, soft wind in audio." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 6, + 8, + 10, + 12, + 14, + 16, + 18, + 20 + ], + "default": 6 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio.", + "default": true + } + } + }, + { + "id": "vidu-q2-reference", + "name": "Vidu Q2 Reference", + "endpoint": "vidu-q2-reference", + "family": "vidu-q2", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "The female explorer walks slowly across the alien terrain, crystals glimmering around her. The camera glides beside her as light from twin suns scatters across her reflective suit. Wind stirs the mist as she looks up toward the horizon, where a colossal planet looms above — evoking awe and wonder." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "360p", + "540p", + "720p", + "1080p" + ], + "default": "720p" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "4:3", + "3:4", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 2, + "maxValue": 8, + "step": 1 + }, + "movement_amplitude": { + "type": "string", + "title": "Movement Amplitude", + "name": "movement_amplitude", + "description": "The movement amplitude of objects in the frame.", + "enum": [ + "auto", + "small", + "medium", + "large" + ], + "default": "auto" + } + } + }, + { + "id": "vidu-q2-turbo-start-end-video", + "name": "Vidu Q2 Turbo Start End Video", + "endpoint": "vidu-q2-turbo-start-end-video", + "family": "vidu-q2", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "The camera begins behind the traveler standing amid the misty ancient ruins. Leaves swirl in the air as golden light flickers. A surge of energy surrounds the traveler — ruins start to dissolve into bright particles. The environment morphs into a neon-lit futuristic city as the traveler continues walking forward, entering the new world." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 2, + "maxValue": 8, + "step": 1 + }, + "bgm": { + "type": "boolean", + "title": "Bgm", + "name": "bgm", + "description": "The background music for generating the output.", + "default": true + }, + "movement_amplitude": { + "type": "string", + "title": "Movement Amplitude", + "name": "movement_amplitude", + "description": "The movement amplitude of objects in the frame.", + "enum": [ + "auto", + "small", + "medium", + "large" + ], + "default": "auto" + } + } + }, + { + "id": "vidu-q2-pro-start-end-video", + "name": "Vidu Q2 Pro Start End Video", + "endpoint": "vidu-q2-pro-start-end-video", + "family": "vidu-q2", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Camera begins behind the cabin as snowflakes drift through pale dawn light. Warm sunlight pierces the mist — the snow slowly melts, trees turn green, and the ground blossoms with flowers. The air brightens into a spring sunrise as birds take flight over the cabin, symbolizing rebirth and renewal." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 2, + "maxValue": 8, + "step": 1 + }, + "bgm": { + "type": "boolean", + "title": "Bgm", + "name": "bgm", + "description": "The background music for generating the output.", + "default": true + }, + "movement_amplitude": { + "type": "string", + "title": "Movement Amplitude", + "name": "movement_amplitude", + "description": "The movement amplitude of objects in the frame.", + "enum": [ + "auto", + "small", + "medium", + "large" + ], + "default": "auto" + } + } + }, + { + "id": "minimax-hailuo-2.3-pro-i2v", + "name": "Minimax Hailuo 2.3 Pro I2V", + "endpoint": "minimax-hailuo-2.3-pro-i2v", + "family": "minimax-2.3", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "The camera slowly moves around the woman as the wind gently sways the tall grass. Her hair flows with the breeze, sunlight flickering through passing clouds. The atmosphere feels calm, nostalgic, and cinematic." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "1080p" + ], + "default": "1080p" + } + } + }, + { + "id": "minimax-hailuo-2.3-standard-i2v", + "name": "Minimax Hailuo 2.3 Standard I2V", + "endpoint": "minimax-hailuo-2.3-standard-i2v", + "family": "minimax-2.3", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Camera slowly moves forward over the lake surface as light wind ripples the water. The clouds drift across the mountains, and sunlight flickers on the waves, creating a peaceful cinematic mood." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 6, + 10 + ], + "default": 6 + } + } + }, + { + "id": "minimax-hailuo-2.3-fast", + "name": "Minimax Hailuo 2.3 Fast", + "endpoint": "minimax-hailuo-2.3-fast", + "family": "minimax-2.3", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "The camera gently moves around the woman as snowflakes drift through the air. Her expression shifts slightly as the wind brushes her hair. The background lights shimmer softly, creating a calm cinematic mood." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 6, + 10 + ], + "default": 6 + }, + "go_fast": { + "type": "boolean", + "title": "Go Fast", + "name": "go_fast", + "description": "Prioritize faster video generation speed with a moderate trade-off in visual quality.", + "default": true + } + } + }, + { + "id": "kling-v2.5-turbo-std-i2v", + "name": "Kling v2.5 Turbo Std I2V", + "endpoint": "kling-v2.5-turbo-std-i2v", + "family": "kling-v2.5", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Animate subtle cloak movement, glowing energy pulsing from the staff, storm clouds rolling above, camera orbiting slightly to add depth and atmosphere." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 10, + "step": 5 + } + } + }, + { + "id": "grok-imagine-image-to-video", + "name": "Grok Imagine Image To Video", + "endpoint": "grok-imagine-image-to-video", + "family": "grok", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Camera glides through vines toward temple entrance, mist disperses as sunlight pierces canopy, birds fly off, subtle dust motes in the air, adventure-style cinematic score." + ] + }, + "mode": { + "type": "string", + "title": "Mode", + "name": "mode", + "description": "Note: When generating videos using external image inputs, Spicy mode is not supported and will automatically switch to Normal.", + "enum": [ + "fun", + "normal", + "spicy" + ], + "default": "normal" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds.", + "enum": [ + 6, + 10 + ], + "default": 6 + } + } + }, + { + "id": "kling-o1-image-to-video", + "name": "Kling O1 Image To Video", + "endpoint": "kling-o1-image-to-video", + "family": "kling-o1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "A gentle dolly forward toward the cabin as morning light intensifies, mist lifts in streaks, subtle water ripples, birds take flight, warm golden hour soundscape." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10 + ], + "default": 5 + } + } + }, + { + "id": "kling-o1-reference-to-video", + "name": "Kling O1 Reference To Video", + "endpoint": "kling-o1-reference-to-video", + "family": "kling-o1", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Cinematic orbit camera move around the pilot in a futuristic hangar, holographic lights flickering, armor reflections shifting, soft mechanical ambience." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 3, + "maxValue": 10, + "step": 1 + }, + "keep_original_sound": { + "type": "boolean", + "title": "Keep Original Sound", + "name": "keep_original_sound", + "description": "Select whether to keep the video original sound through the parameter.", + "default": true + } + } + }, + { + "id": "kling-v2.6-pro-i2v", + "name": "Kling v2.6 Pro I2V", + "endpoint": "kling-v2.6-pro-i2v", + "family": "kling-v2.6", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Slow cinematic orbit around the floating obsidian throne, holographic runes pulsing gently, drifting quartz shards rotating with soft parallax, molten crystal canyon glowing brighter with movement, and subtle particle storms rising toward the cosmic vortex; maintain original lighting, style, and atmosphere." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds.", + "enum": [ + 5, + 10 + ], + "default": 5 + }, + "sound": { + "type": "boolean", + "title": "Sound", + "name": "sound", + "description": "Whether sound is generated simultaneously when generating a video.", + "default": true + } + } + }, + { + "id": "pixverse-v5.5-i2v", + "name": "Pixverse v5.5 I2V", + "endpoint": "pixverse-v5.5-i2v", + "family": "pixverse-v5.5", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Slow upward camera glide along the staircase, lanterns gently swaying, stardust drifting in soft spirals, nebula clouds subtly shifting, and the cosmic gateway pulsing with rhythmic light; maintain original colors, composition, and celestial atmosphere with smooth cinematic motion." + ] + }, + "style": { + "type": "string", + "title": "Style", + "name": "style", + "description": "The style of the generated video.", + "enum": [ + "none", + "anime", + "3d_animation", + "clay", + "comic", + "cyberpunk" + ], + "default": "none" + }, + "thinking": { + "type": "string", + "title": "Thinking", + "name": "thinking", + "description": "Prompt optimization mode for model decision.", + "enum": [ + "auto", + "enabled", + "disabled" + ], + "default": "auto" + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "4:3", + "3:4" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "360p", + "540p", + "720p", + "1080p" + ], + "default": "360p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds.", + "enum": [ + 5, + 8, + 10 + ], + "default": 5 + }, + "audio": { + "type": "boolean", + "title": "Audio", + "name": "audio", + "description": "Enable audio generation (BGM, SFX, dialogue).", + "default": false + }, + "multi_clip": { + "type": "boolean", + "title": "Multi Clip", + "name": "multi_clip", + "description": "Enable multi-clip generation with dynamic camera changes.", + "default": false + } + } + }, + { + "id": "wan2.2-spicy-image-to-video", + "name": "Wan2.2 Spicy Image To Video", + "endpoint": "wan2.2-spicy-image-to-video", + "family": "wan2.2", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Animate the scene with intense fiery motion—lava cracking and flowing down the phoenix wings, embers drifting upward, volcanic smoke swirling dramatically, floating stones shifting with parallax depth; camera performs a slow power-shot push-in toward the phoenix statue while preserving the glowing, high-contrast cinematic atmosphere." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p" + ], + "default": "480p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 8 + ], + "default": 5 + } + } + }, + { + "id": "wan2.6-image-to-video", + "name": "Wan2.6 Image To Video", + "endpoint": "wan2.6-image-to-video", + "family": "wan2.6", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Add slow cinematic camera movement circling the floating lighthouse, orbiting symbol rings rotating gently with parallax depth, ocean waves shimmering and moving naturally, clouds drifting and lightning flashing subtly in the distance, and the lighthouse beam pulsing softly while preserving the original lighting and dramatic mood." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10, + 15 + ], + "default": 5 + }, + "shot_type": { + "type": "string", + "title": "Shot Type", + "name": "shot_type", + "description": "The type of shot to generate.", + "enum": [ + "single", + "multi" + ], + "default": "single" + } + } + }, + { + "id": "kling-o1-standard-image-to-video", + "name": "Kling O1 Standard Image To Video", + "endpoint": "kling-o1-standard-image-to-video", + "family": "kling-o1", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Add gentle camera drift forward with slight parallax depth, waterfalls flowing softly, clouds slowly moving beneath the island, birds gliding naturally through the scene, and sunlight shifting subtly while maintaining the calm cinematic mood and original lighting." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10 + ], + "default": 5 + } + } + }, + { + "id": "kling-o1-standard-reference-to-video", + "name": "Kling O1 Standard Reference To Video", + "endpoint": "kling-o1-standard-reference-to-video", + "family": "kling-o1", + "imageField": "images_list", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "The prompt to generate the video", + "examples": [ + "Blend the reference scenes into a single cinematic shot with gentle forward camera movement, soft parallax depth between the bridge and forest valley, fog drifting slowly above the river, leaves swaying lightly in the breeze, and sunlight shifting subtly while maintaining a calm, realistic atmosphere." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1" + ], + "default": "16:9" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "enum": [ + 5, + 10 + ], + "default": 5 + } + } + }, + { + "id": "seedance-v1.5-pro-i2v", + "name": "Seedance v1.5 Pro I2V", + "endpoint": "seedance-v1.5-pro-i2v", + "family": "seedance-v1.5-pro", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Add a slow cinematic orbit around the floating archive, gentle parallax between cloud layers and spires, flowing data streams pulsing softly, fog drifting naturally, and sky colors deepening slightly while preserving the original lighting, scale, and cinematic mood." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "3:4", + "4:3", + "21:9" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 4, + "maxValue": 12, + "step": 1 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio", + "default": true + }, + "camera_fixed": { + "type": "boolean", + "title": "Camera Fixed", + "name": "camera_fixed", + "description": "Whether to fix the camera position", + "default": false + } + } + }, + { + "id": "seedance-v1.5-pro-i2v-fast", + "name": "Seedance v1.5 Pro I2V Fast", + "endpoint": "seedance-v1.5-pro-i2v-fast", + "family": "seedance-v1.5-pro", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Add gentle forward camera movement toward the floating observatory, subtle parallax between clouds and structure, soft cloud drift below, interior window lights glowing steadily, and sunlight rays shifting slightly while keeping motion smooth, minimal, and fast." + ] + }, + "aspect_ratio": { + "type": "string", + "title": "Aspect Ratio", + "name": "aspect_ratio", + "description": "Aspect ratio of the output video.", + "enum": [ + "16:9", + "9:16", + "1:1", + "3:4", + "4:3", + "21:9" + ], + "default": "16:9" + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 4, + "maxValue": 12, + "step": 1 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio", + "default": true + }, + "camera_fixed": { + "type": "boolean", + "title": "Camera Fixed", + "name": "camera_fixed", + "description": "Whether to fix the camera position", + "default": false + } + } + }, + { + "id": "ltx-2-19b-image-to-video", + "name": "Ltx 2 19b Image To Video", + "endpoint": "ltx-2-19b-image-to-video", + "family": "ltx", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "Animate the scene so the camera slowly pushes toward the billboard, the text characters on the woman’s face subtly scrolling and re-forming, rain falling continuously, reflections on the wet road shifting as car headlights flicker, pedestrians making small natural movements while the city lights pulse softly; maintain realistic motion, urban mood, and cinematic pacing." + ] + }, + "resolution": { + "type": "string", + "title": "Resolution", + "name": "resolution", + "description": "The resolution of the generated video.", + "enum": [ + "480p", + "720p", + "1080p" + ], + "default": "720p" + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 5, + "maxValue": 20, + "step": 1 + } + } + }, + { + "id": "kling-v3.0-pro-image-to-video", + "name": "Kling v3.0 Pro Image To Video", + "endpoint": "kling-v3.0-pro-image-to-video", + "family": "kling-v3.0", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "The camera begins on the railway station platform beside a stationary train as morning sunlight filters through the roof. Passengers make small natural movements while the train doors are open. The camera moves forward and enters the train, transitioning smoothly into a window-seat point of view. As the doors close, the train starts moving. The view shifts fully to the window, showing the city passing by outside with gentle motion blur, buildings and trees sliding past. Sunlight reflects on the glass, faint interior reflections appear, and the ride feels calm and realistic with smooth, cinematic motion." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 3, + "maxValue": 15, + "step": 1 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio for the video", + "default": true + } + } + }, + { + "id": "kling-v3.0-standard-image-to-video", + "name": "Kling v3.0 Standard Image To Video", + "endpoint": "kling-v3.0-standard-image-to-video", + "family": "kling-v3.0", + "imageField": "image_url", + "hasPrompt": true, + "inputs": { + "prompt": { + "type": "string", + "title": "Prompt", + "name": "prompt", + "description": "Text prompt describing the video.", + "examples": [ + "The hamster begins on the left side of the tabletop and quickly runs across the surface toward the right. Its tiny legs move rapidly, body bouncing slightly with natural motion. As it runs, the sunflower seeds blur slightly beneath it. The hamster slows near the bowl, stops, and stands upright to grab a seed. The camera remains fixed, depth of field stays shallow, and lighting remains soft and consistent for a realistic, cute result." + ] + }, + "duration": { + "type": "int", + "title": "Duration", + "name": "duration", + "description": "The duration of the generated video in seconds", + "default": 5, + "minValue": 3, + "maxValue": 15, + "step": 1 + }, + "generate_audio": { + "type": "boolean", + "title": "Generate Audio", + "name": "generate_audio", + "description": "Whether to generate audio for the video", + "default": true + } + } + } +]; + +export const getI2IModelById = (id) => i2iModels.find(m => m.id === id); +export const getI2VModelById = (id) => i2vModels.find(m => m.id === id); + +export const getAspectRatiosForI2IModel = (modelId) => { + const model = getI2IModelById(modelId); + if (!model) return ['1:1']; + if (model.inputs && model.inputs.aspect_ratio && model.inputs.aspect_ratio.enum) return model.inputs.aspect_ratio.enum; + return ['1:1', '16:9', '9:16']; +}; + +export const getAspectRatiosForI2VModel = (modelId) => { + const model = getI2VModelById(modelId); + if (!model) return ['16:9']; + if (model.inputs && model.inputs.aspect_ratio && model.inputs.aspect_ratio.enum) return model.inputs.aspect_ratio.enum; + return ['16:9', '9:16', '1:1']; +}; + +export const getDurationsForI2VModel = (modelId) => { + const model = getI2VModelById(modelId); + if (!model) return []; + const dur = model.inputs && model.inputs.duration; + if (!dur) return []; + if (dur.enum) return dur.enum; + if (dur.minValue !== undefined && dur.maxValue !== undefined && dur.step) { + const vals = []; + for (let v = dur.minValue; v <= dur.maxValue; v += dur.step) vals.push(v); + return vals; + } + if (dur.default) return [dur.default]; + return []; +}; + +export const getResolutionsForI2VModel = (modelId) => { + const model = getI2VModelById(modelId); + if (!model) return []; + const res = model.inputs && model.inputs.resolution; + if (res && res.enum) return res.enum; + return []; +}; + +export const getResolutionsForI2IModel = (modelId) => { + const model = getI2IModelById(modelId); + if (!model) return []; + const res = model.inputs && model.inputs.resolution; + if (res && res.enum) return res.enum; + return []; +}; diff --git a/src/lib/muapi.js b/src/lib/muapi.js index f709557..39d78c3 100644 --- a/src/lib/muapi.js +++ b/src/lib/muapi.js @@ -1,4 +1,4 @@ -import { getModelById, getVideoModelById } from './models.js'; +import { getModelById, getVideoModelById, getI2IModelById, getI2VModelById } from './models.js'; export class MuapiClient { constructor() { @@ -173,6 +173,7 @@ export class MuapiClient { if (params.duration) finalPayload.duration = params.duration; if (params.resolution) finalPayload.resolution = params.resolution; if (params.quality) finalPayload.quality = params.quality; + if (params.image_url) finalPayload.image_url = params.image_url; console.log('[Muapi] Video Request:', url); console.log('[Muapi] Video Payload:', finalPayload); @@ -212,6 +213,171 @@ export class MuapiClient { } } + /** + * Generates an image using an Image-to-Image model. + * The model's imageField determines which payload key receives the uploaded image URL. + * @param {Object} params + * @param {string} params.model - i2iModel id + * @param {string} params.image_url - The uploaded reference image URL + * @param {string} [params.prompt] - Optional text prompt + * @param {string} [params.aspect_ratio] + * @param {string} [params.resolution] + */ + async generateI2I(params) { + const key = this.getKey(); + const modelInfo = getI2IModelById(params.model); + const endpoint = modelInfo?.endpoint || params.model; + const url = `${this.baseUrl}/api/v1/${endpoint}`; + + const finalPayload = {}; + + // Only include prompt if the model supports it and one was provided + if (params.prompt) finalPayload.prompt = params.prompt; + + // Place the uploaded image in the correct field for this model + const imageField = modelInfo?.imageField || 'image_url'; + if (params.image_url) { + if (imageField === 'images_list') { + finalPayload.images_list = [params.image_url]; + } else { + finalPayload[imageField] = params.image_url; + } + } + + if (params.aspect_ratio) finalPayload.aspect_ratio = params.aspect_ratio; + if (params.resolution) finalPayload.resolution = params.resolution; + + console.log('[Muapi] I2I Request:', url); + console.log('[Muapi] I2I Payload:', finalPayload); + + try { + const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'x-api-key': key }, + body: JSON.stringify(finalPayload) + }); + + if (!response.ok) { + const errText = await response.text(); + throw new Error(`API Request Failed: ${response.status} ${response.statusText} - ${errText.slice(0, 100)}`); + } + + const submitData = await response.json(); + console.log('[Muapi] I2I Submit Response:', submitData); + + const requestId = submitData.request_id || submitData.id; + if (!requestId) return submitData; + + const result = await this.pollForResult(requestId, key); + const imageUrl = result.outputs?.[0] || result.url || result.output?.url; + console.log('[Muapi] I2I Result URL:', imageUrl); + return { ...result, url: imageUrl }; + } catch (error) { + console.error('Muapi I2I Error:', error); + throw error; + } + } + + /** + * Generates a video using an Image-to-Video model. + * @param {Object} params + * @param {string} params.model - i2vModel id + * @param {string} params.image_url - The uploaded start frame image URL + * @param {string} [params.prompt] + * @param {string} [params.aspect_ratio] + * @param {string} [params.resolution] + * @param {number} [params.duration] + * @param {string} [params.quality] + */ + async generateI2V(params) { + const key = this.getKey(); + const modelInfo = getI2VModelById(params.model); + const endpoint = modelInfo?.endpoint || params.model; + const url = `${this.baseUrl}/api/v1/${endpoint}`; + + const finalPayload = {}; + + if (params.prompt) finalPayload.prompt = params.prompt; + + // Place image in the correct field for this model + const imageField = modelInfo?.imageField || 'image_url'; + if (params.image_url) { + if (imageField === 'images_list') { + finalPayload.images_list = [params.image_url]; + } else { + finalPayload[imageField] = params.image_url; + } + } + + if (params.aspect_ratio) finalPayload.aspect_ratio = params.aspect_ratio; + if (params.duration) finalPayload.duration = params.duration; + if (params.resolution) finalPayload.resolution = params.resolution; + if (params.quality) finalPayload.quality = params.quality; + + console.log('[Muapi] I2V Request:', url); + console.log('[Muapi] I2V Payload:', finalPayload); + + try { + const response = await fetch(url, { + method: 'POST', + headers: { 'Content-Type': 'application/json', 'x-api-key': key }, + body: JSON.stringify(finalPayload) + }); + + if (!response.ok) { + const errText = await response.text(); + throw new Error(`API Request Failed: ${response.status} ${response.statusText} - ${errText.slice(0, 100)}`); + } + + const submitData = await response.json(); + console.log('[Muapi] I2V Submit Response:', submitData); + + const requestId = submitData.request_id || submitData.id; + if (!requestId) return submitData; + + const result = await this.pollForResult(requestId, key, 120, 2000); + const videoUrl = result.outputs?.[0] || result.url || result.output?.url; + console.log('[Muapi] I2V Result URL:', videoUrl); + return { ...result, url: videoUrl }; + } catch (error) { + console.error('Muapi I2V Error:', error); + throw error; + } + } + + /** + * Uploads a file to muapi and returns the hosted URL. + * @param {File} file - The image file to upload + * @returns {Promise} The hosted URL of the uploaded file + */ + async uploadFile(file) { + const key = this.getKey(); + const url = `${this.baseUrl}/api/v1/upload_file`; + + const formData = new FormData(); + formData.append('file', file); + + console.log('[Muapi] Uploading file:', file.name); + + const response = await fetch(url, { + method: 'POST', + headers: { 'x-api-key': key }, + body: formData + }); + + if (!response.ok) { + const errText = await response.text(); + throw new Error(`File upload failed: ${response.status} - ${errText.slice(0, 100)}`); + } + + const data = await response.json(); + console.log('[Muapi] Upload response:', data); + + const fileUrl = data.url || data.file_url || data.data?.url; + if (!fileUrl) throw new Error('No URL returned from file upload'); + return fileUrl; + } + getDimensionsFromAR(ar) { // Base unit 1024 (Flux standard) switch (ar) { diff --git a/src/lib/uploadHistory.js b/src/lib/uploadHistory.js new file mode 100644 index 0000000..960a33a --- /dev/null +++ b/src/lib/uploadHistory.js @@ -0,0 +1,52 @@ +const STORAGE_KEY = 'muapi_uploads'; +const MAX_UPLOADS = 20; + +export function getUploadHistory() { + try { + return JSON.parse(localStorage.getItem(STORAGE_KEY) || '[]'); + } catch { + return []; + } +} + +export function saveUpload({ id, name, uploadedUrl, thumbnail, timestamp }) { + const history = getUploadHistory(); + history.unshift({ id, name, uploadedUrl, thumbnail, timestamp }); + localStorage.setItem(STORAGE_KEY, JSON.stringify(history.slice(0, MAX_UPLOADS))); +} + +export function removeUpload(id) { + const history = getUploadHistory().filter(e => e.id !== id); + localStorage.setItem(STORAGE_KEY, JSON.stringify(history)); +} + +/** + * Generates a square 80×80 base64 JPEG thumbnail from a File. + * @param {File} file + * @returns {Promise} + */ +export async function generateThumbnail(file) { + return new Promise((resolve) => { + const objectUrl = URL.createObjectURL(file); + const img = new Image(); + img.onload = () => { + const SIZE = 80; + const canvas = document.createElement('canvas'); + canvas.width = SIZE; + canvas.height = SIZE; + const ctx = canvas.getContext('2d'); + // Center-crop to square + const size = Math.min(img.width, img.height); + const sx = (img.width - size) / 2; + const sy = (img.height - size) / 2; + ctx.drawImage(img, sx, sy, size, size, 0, 0, SIZE, SIZE); + URL.revokeObjectURL(objectUrl); + resolve(canvas.toDataURL('image/jpeg', 0.6)); + }; + img.onerror = () => { + URL.revokeObjectURL(objectUrl); + resolve(null); + }; + img.src = objectUrl; + }); +}