From 615afbc211b295c82175b308373c1c96b336c63c Mon Sep 17 00:00:00 2001 From: WangLeo <690854599@qq.com> Date: Tue, 9 Jun 2026 11:42:00 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=20Video=20=E5=B9=B3?= =?UTF-8?q?=E5=8F=B0=E5=8C=85=EF=BC=88descriptor=20+=20=E6=8E=A7=E4=BB=B6?= =?UTF-8?q?=E8=BF=81=E7=A7=BB=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/platforms/video/controls/pattern.vue | 96 ++++++ src/platforms/video/controls/proportion.vue | 242 ++++++++++++++ src/platforms/video/controls/time.vue | 84 +++++ src/platforms/video/imageUploader.vue | 330 ++++++++++++++++++++ src/platforms/video/index.js | 166 ++++++++++ src/platforms/video/modelSelector.vue | 149 +++++++++ 6 files changed, 1067 insertions(+) create mode 100644 src/platforms/video/controls/pattern.vue create mode 100644 src/platforms/video/controls/proportion.vue create mode 100644 src/platforms/video/controls/time.vue create mode 100644 src/platforms/video/imageUploader.vue create mode 100644 src/platforms/video/index.js create mode 100644 src/platforms/video/modelSelector.vue diff --git a/src/platforms/video/controls/pattern.vue b/src/platforms/video/controls/pattern.vue new file mode 100644 index 0000000..2ad910d --- /dev/null +++ b/src/platforms/video/controls/pattern.vue @@ -0,0 +1,96 @@ + + + + + + + + + {{ option.labelText }} + + + + + + + + diff --git a/src/platforms/video/controls/proportion.vue b/src/platforms/video/controls/proportion.vue new file mode 100644 index 0000000..0aeafae --- /dev/null +++ b/src/platforms/video/controls/proportion.vue @@ -0,0 +1,242 @@ + + + + + 选择比例 + + + {{ item.label }} + + + + + + 选择分辨率 + + + {{ item.label }} + + + + + + + + {{ proportion }} + + {{ resolution }} + + + + + + + + diff --git a/src/platforms/video/controls/time.vue b/src/platforms/video/controls/time.vue new file mode 100644 index 0000000..7acfe1a --- /dev/null +++ b/src/platforms/video/controls/time.vue @@ -0,0 +1,84 @@ + + + + + + + 选择视频生成时长 + + + + + + + diff --git a/src/platforms/video/imageUploader.vue b/src/platforms/video/imageUploader.vue new file mode 100644 index 0000000..4c7c708 --- /dev/null +++ b/src/platforms/video/imageUploader.vue @@ -0,0 +1,330 @@ + + + + + + {{ getFrameLabel(index) }} + + + + + + + + {{ getUploadText(i) }} + + + + + + + + + + diff --git a/src/platforms/video/index.js b/src/platforms/video/index.js new file mode 100644 index 0000000..b2cf613 --- /dev/null +++ b/src/platforms/video/index.js @@ -0,0 +1,166 @@ +import { ref, markRaw } from 'vue' +import { fetchModelConfig } from '@/utils/modelConfig' +import { fetchPlatformModels, getPlatformCode } from '@/utils/modelApi' +import VideoModelSelector from './modelSelector.vue' +import Pattern from './controls/pattern.vue' +import VideoProportion from './controls/proportion.vue' +import Time from './controls/time.vue' +import VideoImageUploader from './imageUploader.vue' +import { registerPlatform } from '../registry.js' + +export function defineVideoPlatform() { + const model = ref('LTX2.0') + const modelType = ref('text') + const proportion = ref('16:9') + const resolution = ref('1k') + const duration = ref(5) + const videoPattern = ref('文生视频') + + const resolutionOptions = ref([ + { value: '1k', label: '标清 1K' }, + { value: '2k', label: '高清 2K' }, + { value: '4k', label: '超清 4K' }, + ]) + const proportionOptions = ref([ + { value: '智能', label: '智能' }, + { value: '21:9', label: '21:9' }, + { value: '16:9', label: '16:9' }, + { value: '4:3', label: '4:3' }, + { value: '1:1', label: '1:1' }, + { value: '3:4', label: '3:4' }, + { value: '9:16', label: '9:16' }, + ]) + const durationOptions = ref([]) + const modelDisplayConfig = ref(null) + const promptPlaceholder = ref('描述你想生成的画面和动作。') + + const state = { + model, modelType, + proportion, resolution, + duration, videoPattern, + resolutionOptions, proportionOptions, durationOptions, + modelDisplayConfig, + } + + async function loadInternalConfig(modelName, modelTypeVal) { + const config = await fetchModelConfig('Video', modelName, modelTypeVal) + modelDisplayConfig.value = config + if (config?.display) { + const d = config.display + if (d.resolution) { + resolution.value = d.resolution.default || '1k' + resolutionOptions.value = d.resolution.options || [] + } + if (d.proportion) { + proportion.value = d.proportion.default || '16:9' + proportionOptions.value = d.proportion.options || [] + } + if (d.duration) { + duration.value = d.duration.default || 5 + durationOptions.value = d.duration.options || [] + } + if (d.promptPlaceholder) { + promptPlaceholder.value = d.promptPlaceholder.default || '描述你想生成的画面和动作。' + } + } + return config + } + + const controls = [ + { + name: 'pattern', + component: markRaw(Pattern), + show: () => true, + props: () => ({ + modelValue: videoPattern.value, + 'onUpdate:modelValue': (v) => { videoPattern.value = v }, + }), + }, + { + name: 'proportion', + component: markRaw(VideoProportion), + show: () => true, + props: () => ({ + modelValue: proportion.value, + 'onUpdate:modelValue': (v) => { proportion.value = v }, + resolution: resolution.value, + 'onUpdate:resolution': (v) => { resolution.value = v }, + proportionOptions: proportionOptions.value, + resolutionOptions: resolutionOptions.value, + }), + }, + { + name: 'time', + component: markRaw(Time), + show: () => true, + props: () => ({ + modelValue: duration.value, + 'onUpdate:modelValue': (v) => { duration.value = v }, + options: durationOptions.value, + }), + }, + ] + + const platform = { + id: 'video', + label: 'AI视频2026', + ModelSelector: markRaw(VideoModelSelector), + modelSelectorProps: () => ({ videoPattern: videoPattern.value }), + controls, + ImageUploader: markRaw(VideoImageUploader), + state, + model, + modelType, + modelDisplayConfig, + promptPlaceholder, + + async loadModels() { + const code = getPlatformCode('Video') + return fetchPlatformModels(code) + }, + + async loadConfig(modelName, modelTypeVal) { + return loadInternalConfig(modelName, modelTypeVal) + }, + + getDefaultModel() { + return 'LTX2.0' + }, + + showImageUploader() { + return modelType.value !== 'text' + }, + + imageUploadLimit() { + return modelDisplayConfig.value?.display?.images || 1 + }, + + isImageRequired() { + return modelType.value !== 'text' + }, + + buildTaskBody(shared) { + const modelParams = { + prompt: shared.prompt.value, + proportion: proportion.value, + resolution: resolution.value, + duration: duration.value, + videoPattern: videoPattern.value, + } + return modelParams + }, + + fillFromResult(resultData) { + if (resultData.model !== undefined) model.value = resultData.model + if (resultData.modelType !== undefined) modelType.value = resultData.modelType + if (resultData.proportion !== undefined) proportion.value = resultData.proportion + if (resultData.resolution !== undefined) resolution.value = resultData.resolution + if (resultData.duration !== undefined) duration.value = resultData.duration + if (resultData.videoPattern !== undefined) videoPattern.value = resultData.videoPattern + }, + } + + return platform +} + +registerPlatform('Video', defineVideoPlatform) diff --git a/src/platforms/video/modelSelector.vue b/src/platforms/video/modelSelector.vue new file mode 100644 index 0000000..7fa0dee --- /dev/null +++ b/src/platforms/video/modelSelector.vue @@ -0,0 +1,149 @@ + + + + + + + + + + +