From 4120f37c94e26d9b2a2347ee84df368fba958a64 Mon Sep 17 00:00:00 2001 From: "949036910@qq.com" <> Date: Sun, 31 May 2026 22:19:51 +0800 Subject: [PATCH] 11 --- .../workflow/MixCutSettingPanel.vue | 23 ++++ src/components/workflow/Step03VideoEdit.vue | 15 +-- .../workflow/Step05SubtitleMusic.vue | 5 +- src/services/mixCutSettings.js | 109 +++++++++++++++++- src/services/subtitleBgmGenerate.js | 4 +- src/services/talkingVideoGenerate.js | 21 +++- src/services/videoEditProcess.js | 5 +- src/stores/workflow.js | 2 +- 8 files changed, 167 insertions(+), 17 deletions(-) diff --git a/src/components/workflow/MixCutSettingPanel.vue b/src/components/workflow/MixCutSettingPanel.vue index d3e3767..af4f125 100644 --- a/src/components/workflow/MixCutSettingPanel.vue +++ b/src/components/workflow/MixCutSettingPanel.vue @@ -8,11 +8,13 @@ import { findMappingForLine, loadMixCutSubtitleRecords, openSubtitleFileAndParse, + persistSubtitleRecordsToMixCut, pickLocalMixCutMaterial, pickMaterialFolder, prepareMixCutSettingsForSave, removeMaterialFromSubtitleLine, } from "../../services/mixCutSettings.js"; +import { revealLocalFileInFolder } from "../../services/fileExport.js"; import { createDefaultGlobalDisplay, createDefaultMixCutSettings, @@ -120,6 +122,10 @@ async function loadExistingSubtitleLines() { if (result.srtPath) subtitleFilePath.value = result.srtPath; settings.value.records = result.records; if (result.srtPath) settings.value.subtitleFilePath = result.srtPath; + await persistSubtitleRecordsToMixCut(props.store, { + records: result.records, + srtPath: result.srtPath, + }); const msg = result.message || `字幕加载成功,共 ${result.records.length} 条`; @@ -131,6 +137,19 @@ async function loadExistingSubtitleLines() { } async function onOpenSubtitleFile() { + const currentPath = subtitleFilePath.value || props.store.subtitleSrtPath; + if (currentPath) { + try { + await revealLocalFileInFolder(currentPath); + } catch (err) { + showFeedback( + "error", + err instanceof Error ? err.message : "打开文件夹失败", + ); + } + return; + } + const result = await openSubtitleFileAndParse(); if (!result.message && !result.ok) return; if (!result.ok) { @@ -141,6 +160,10 @@ async function onOpenSubtitleFile() { subtitleFilePath.value = result.srtPath || ""; settings.value.records = result.records; settings.value.subtitleFilePath = result.srtPath || ""; + await persistSubtitleRecordsToMixCut(props.store, { + records: result.records, + srtPath: result.srtPath, + }); showFeedback("success", `已加载 ${result.records.length} 行字幕`); } diff --git a/src/components/workflow/Step03VideoEdit.vue b/src/components/workflow/Step03VideoEdit.vue index fa77d34..d90e18b 100644 --- a/src/components/workflow/Step03VideoEdit.vue +++ b/src/components/workflow/Step03VideoEdit.vue @@ -12,8 +12,9 @@ const { greenScreen, videoProcessing, greenScreenBackgroundPath, - generatedVideoSrc, generatedVideoPath, + processedVideoSrc, + processedVideoPath, } = storeToRefs(workflow); const feedback = ref({ severity: "", message: "" }); @@ -56,12 +57,12 @@ async function onPickPipMaterial() { } async function onOpenVideoInExplorer() { - if (!generatedVideoPath.value) { - feedback.value = { severity: "error", message: "暂无视频文件" }; + if (!processedVideoPath.value) { + feedback.value = { severity: "error", message: "暂无编辑后的视频文件" }; return; } try { - await revealLocalFileInFolder(generatedVideoPath.value); + await revealLocalFileInFolder(processedVideoPath.value); } catch (err) { feedback.value = { severity: "error", @@ -146,15 +147,15 @@ async function onOpenVideoInExplorer() { size="small" severity="secondary" text - :disabled="!generatedVideoPath" + :disabled="!processedVideoPath" aria-label="在资源管理器中打开" @click="onOpenVideoInExplorer" />