Files
capcut-mate/desktop-client/nodeapi/draftPathDetect.js
T
Hommy 716831b93d 新增加剪映小助手客户端自动选择目录的能力,需求如下:
帮我重构客户端desktop-client的配置逻辑,当首次运行时,没有配置剪映草稿地址时,自动选择草稿地址规则如下:
windows:
C:\Users\1\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft
说明:路径中1是用户名,需要遍历用户名,如果能找到路径:
C:\Users\1\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft\root_meta_info.json
或者
C:\Users\1\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft\.recycle_bin
就能确认草稿目录为C:\Users\1\AppData\Local\JianyingPro\User Data\Projects\com.lveditor.draft

macos:
路径:~/Movies/CapCut/User Data/Projects/com.lveditor.draft/
或者
~/Movies/JianyingPro/User Data/Projects/com.lveditor.draft/
同理,如果目录下面有目录.recycle_bin或文件root_meta_info.json就能确认对应的目录为剪映草稿目录;

如果上述规则都无法找到剪映草稿目录,就弹窗口让用户自己去选。
2026-04-09 11:36:52 +08:00

107 lines
2.5 KiB
JavaScript

const path = require("path");
const fs = require("fs").promises;
const os = require("os");
const logger = require("./logger");
/** Windows 下相对用户主目录的剪映草稿根路径后缀 */
const DRAFT_REL_WIN = path.join(
"AppData",
"Local",
"JianyingPro",
"User Data",
"Projects",
"com.lveditor.draft"
);
/**
* 目录下存在 root_meta_info.json 或 .recycle_bin 子目录时,认为是剪映草稿根目录。
*/
async function isConfirmedJianyingDraftDir(dir) {
try {
await fs.access(dir, fs.constants.R_OK | fs.constants.W_OK);
} catch {
return false;
}
const metaPath = path.join(dir, "root_meta_info.json");
try {
const st = await fs.stat(metaPath);
if (st.isFile()) return true;
} catch {
// ignore
}
try {
const st = await fs.stat(path.join(dir, ".recycle_bin"));
if (st.isDirectory()) return true;
} catch {
// ignore
}
return false;
}
async function detectWindowsDraftPath() {
const usersDir = path.join(process.env.SystemDrive || "C:", "Users");
const ordered = [];
const seen = new Set();
const push = (p) => {
const norm = path.normalize(p);
if (seen.has(norm)) return;
seen.add(norm);
ordered.push(norm);
};
push(path.join(os.homedir(), DRAFT_REL_WIN));
try {
const names = await fs.readdir(usersDir);
for (const name of names) {
const userRoot = path.join(usersDir, name);
try {
const st = await fs.stat(userRoot);
if (!st.isDirectory()) continue;
} catch {
continue;
}
push(path.join(userRoot, DRAFT_REL_WIN));
}
} catch (e) {
logger.warn("[draft-detect] Windows Users 目录扫描失败:", e.message);
}
for (const dir of ordered) {
if (await isConfirmedJianyingDraftDir(dir)) {
return dir;
}
}
return null;
}
async function detectMacDraftPath() {
const home = os.homedir();
const candidates = [
path.join(home, "Movies", "CapCut", "User Data", "Projects", "com.lveditor.draft"),
path.join(home, "Movies", "JianyingPro", "User Data", "Projects", "com.lveditor.draft"),
];
for (const dir of candidates) {
if (await isConfirmedJianyingDraftDir(dir)) return dir;
}
return null;
}
/**
* 按平台自动探测剪映草稿根目录(com.lveditor.draft)。
* @returns {Promise<string|null>}
*/
async function detectJianyingDraftRoot() {
if (process.platform === "win32") {
return detectWindowsDraftPath();
}
if (process.platform === "darwin") {
return detectMacDraftPath();
}
return null;
}
module.exports = {
detectJianyingDraftRoot,
};