diff --git a/web/i18n/locales/en_US.json b/web/i18n/locales/en_US.json index 3873eba..9c0d736 100644 --- a/web/i18n/locales/en_US.json +++ b/web/i18n/locales/en_US.json @@ -430,7 +430,10 @@ "digital_human.section.character_assets": "😊 Character Image Upload", "digital_human.assets.character_what": "Upload an image for the digital human character", "digital_human.assets.character_warning": "Please upload a character image", - "digital_human.assets.select_mode": "Please select a mode and fill in the corresponding information", + "digital_human.assets.goods_warning": "Please upload product images", + "digital_human.assets.digital_mode": "Please enter a custom in-video script or an AI-generated theme", + "digital_human.assets.digital_mode_warning": "⚠️ Only one in-video script or AI-generated theme needs to be entered. If an in-video script has already been entered, the content of the AI-generated theme will not be considered", + "digital_human.assets.customize_mode": "Please enter a custom voiceover message", "digital_human.assets.how": "Supported formats: JPG/PNG/WebP; clear and relevant images are recommended", "digital_human.assets.upload": "Upload Asset", "digital_human.assets.upload_help": "Only single image upload is supported", @@ -469,7 +472,7 @@ "i2v.input_text": "Video prompt text", "i2v.assets.image_warning": "Upload the first frame image of the video", "i2v.assets.prompt_warning": "Please enter the video prompt text", - "iv2.workflow_select": "Selection of image-to-video workflow (including local and runninghub)", + "i2v.workflow_select": "Selection of image-to-video workflow (including local and runninghub)", "action_transfer.video_upload": "🎞️Video footage", "action_transfer.assets.video_what": "Upload the reference video used for the migration action", "action_transfer.assets.video_how": "Supports MP4/MKV/MOV image formats. The reference video only supports single-person action migration. It is recommended that the video action be clearly displayed", diff --git a/web/i18n/locales/zh_CN.json b/web/i18n/locales/zh_CN.json index 30aef76..0626c6e 100644 --- a/web/i18n/locales/zh_CN.json +++ b/web/i18n/locales/zh_CN.json @@ -430,7 +430,10 @@ "digital_human.section.character_assets": "😊 人物形象上传", "digital_human.assets.character_what": "上传数字人形象的图片", "digital_human.assets.character_warning": "请上传人物形象图片", - "digital_human.assets.select_mode": "请选择模式并填入对应信息", + "digital_human.assets.goods_warning": "请上传商品图片", + "digital_human.assets.digital_mode": "请输入自定义口播文案或AI创作主题", + "digital_human.assets.digital_mode_warning": "⚠️ 口播文案与AI创作主题填入一个即可,若已填入口播文案则不再参考AI创作主题的内容", + "digital_human.assets.customize_mode": "请输入自定义口播文案", "digital_human.assets.how": "支持 JPG/PNG/WebP 等格式图片,建议素材清晰且内容相关", "digital_human.assets.upload": "上传素材", "digital_human.assets.upload_help": "仅支持单张图片上传", @@ -469,7 +472,7 @@ "i2v.input_text": "视频提示词", "i2v.assets.image_warning": "上传视频首帧图片", "i2v.assets.prompt_warning": "请输入视频提示词", - "iv2.workflow_select": "图生视频工作流选择(包含本地和runninghub)", + "i2v.workflow_select": "图生视频工作流选择(包含本地和runninghub)", "action_transfer.video_upload": "🎞️视频素材", "action_transfer.assets.video_what": "上传迁移动作使用的参考视频", "action_transfer.assets.video_how": "支持 MP4/MKV/MOV 等格式图片,参考视频仅支持单人动作迁移,建议视频动作表现明显", diff --git a/web/pipelines/action_transfer.py b/web/pipelines/action_transfer.py index 2004292..ac89b61 100644 --- a/web/pipelines/action_transfer.py +++ b/web/pipelines/action_transfer.py @@ -192,9 +192,9 @@ class ActionTransferPipelineUI(PipelineUI): key="prompt_box" ) - iv2_workflows = list_action_transfer_workflows() - workflow_options = [wf["display_name"] for wf in iv2_workflows] - workflow_keys = [wf["key"] for wf in iv2_workflows] + transfer_workflows = list_action_transfer_workflows() + workflow_options = [wf["display_name"] for wf in transfer_workflows] + workflow_keys = [wf["key"] for wf in transfer_workflows] default_workflow_index = 0 workflow_display = st.selectbox( @@ -271,7 +271,7 @@ class ActionTransferPipelineUI(PipelineUI): return # Generate button - if st.button(tr("btn.generate"), type="primary", use_container_width=True, key="iv2_generate"): + if st.button(tr("btn.generate"), type="primary", use_container_width=True, key="transfer_generate"): if not config_manager.validate(): st.error(tr("settings.not_configured")) st.stop() diff --git a/web/pipelines/digital_human.py b/web/pipelines/digital_human.py index 2f61216..9d45763 100644 --- a/web/pipelines/digital_human.py +++ b/web/pipelines/digital_human.py @@ -159,24 +159,21 @@ class DigitalHumanPipelineUI(PipelineUI): "second_workflow_path": "workflows/runninghub/digital_combination.json", "third_workflow_path": "workflows/runninghub/digital_customize.json" } + if not has_runninghub: + st.warning(tr("asset_based.source.runninghub_not_configured")) + else: + st.info(tr("asset_based.source.runninghub_hint")) else: workflow_config = { "first_workflow_path": "workflows/selfhost/digital_image.json", "second_workflow_path": "workflows/selfhost/digital_combination.json", "third_workflow_path": "workflows/selfhost/digital_customize.json" } - - # Show hint based on selection - if source == "runninghub": - if not has_runninghub: - st.warning(tr("asset_based.source.runninghub_not_configured")) - else: - st.info(tr("asset_based.source.runninghub_hint")) - else: if not has_selfhost: st.warning(tr("asset_based.source.selfhost_not_configured")) else: st.info(tr("asset_based.source.selfhost_hint")) + # Check and warn for selfhost workflows (auto popup if not confirmed) # Warn for the first workflow as representative # TODO: need to check if the workflow is valid @@ -319,17 +316,42 @@ class DigitalHumanPipelineUI(PipelineUI): key="digital_human_generate_disabled" ) return - - if not goods_text and not goods_title: - st.info(tr("digital_human.assets.select_mode")) + + if mode == "digital" and not goods_assets: + st.info(tr("digital_human.assets.goods_warning")) st.button( tr("btn.generate"), type="primary", use_container_width=True, disabled=True, - key="digital_human_generate" + key="digital_human_goods_vaiidation" ) - return + return + + if mode == "digital" and not (goods_text or goods_title): + st.info(tr("digital_human.assets.digital_mode")) + st.button( + tr("btn.generate"), + type="primary", + use_container_width=True, + disabled=True, + key="digital_human_digital_disable" + ) + return + + if mode == "digital" and (goods_text or goods_title): + st.warning(tr("digital_human.assets.digital_mode_warning")) + + if mode == "customize" and not goods_text: + st.info(tr("digital_human.assets.customize_mode")) + st.button( + tr("btn.generate"), + type="primary", + use_container_width=True, + disabled=True, + key="digital_human_customize_disable" + ) + return # Generate button if st.button(tr("btn.generate"), type="primary", use_container_width=True, key="digital_human_generate"): diff --git a/web/pipelines/i2v.py b/web/pipelines/i2v.py index 600f2e8..3c4a9ed 100644 --- a/web/pipelines/i2v.py +++ b/web/pipelines/i2v.py @@ -31,16 +31,19 @@ class ImageToVideoPipelineUI(PipelineUI): return tr("pipeline.i2v.description") def render(self, pixelle_video: Any): - # Three-column layout + # Two-column layout left_col,right_col = st.columns([1, 1]) # ==================================================================== - # Middle Column: Asset Upload + # Left Column: Asset Upload # ==================================================================== with left_col: asset_params = self.render_audio_visual_input(pixelle_video) render_version_info() + # ==================================================================== + # Right Column: Output Preview + # ==================================================================== with right_col: video_params = { **asset_params @@ -58,14 +61,14 @@ class ImageToVideoPipelineUI(PipelineUI): st.markdown(f"**{tr('help.how')}**") st.markdown(tr("i2v.assets.how")) - def list_iv2_workflows(): + def list_i2v_workflows(): result = [] for source in ("runninghub", "selfhost"): dir_path = os.path.join("workflows", source) if not os.path.isdir(dir_path): continue for fname in os.listdir(dir_path): - if fname.startswith("iv2_") and fname.endswith(".json"): + if fname.startswith("i2v_") and fname.endswith(".json"): display = f"{fname} - {'Runninghub' if source == 'runninghub' else 'Selfhost'}" result.append({ "key": f"{source}/{fname}", @@ -119,17 +122,17 @@ class ImageToVideoPipelineUI(PipelineUI): key="audio_box" ) - iv2_workflows = list_iv2_workflows() - workflow_options = [wf["display_name"] for wf in iv2_workflows] - workflow_keys = [wf["key"] for wf in iv2_workflows] + i2v_workflows = list_i2v_workflows() + workflow_options = [wf["display_name"] for wf in i2v_workflows] + workflow_keys = [wf["key"] for wf in i2v_workflows] default_workflow_index = 0 workflow_display = st.selectbox( - tr("iv2.workflow_select"), + tr("i2v.workflow_select"), workflow_options if workflow_options else ["No workflow found"], index=default_workflow_index, label_visibility="collapsed", - key="iv2_workflow_select" + key="i2v_workflow_select" ) if workflow_options: @@ -185,7 +188,7 @@ class ImageToVideoPipelineUI(PipelineUI): return # Generate button - if st.button(tr("btn.generate"), type="primary", use_container_width=True, key="iv2_generate"): + if st.button(tr("btn.generate"), type="primary", use_container_width=True, key="i2v_generate"): if not config_manager.validate(): st.error(tr("settings.not_configured")) st.stop() diff --git a/workflows/runninghub/iv2_LTX2.json b/workflows/runninghub/i2v_LTX2.json similarity index 100% rename from workflows/runninghub/iv2_LTX2.json rename to workflows/runninghub/i2v_LTX2.json