Your Name 1912bcd25b
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
chore: sync all remaining local workspace changes
2026-05-08 11:26:57 +08:00

2126 lines
78 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Extracted from browser-delivered Turbopack chunk: fd0220e4d10052af.701bdafa2d.js
* Module id: 649517
* For reading/searching only; this factory depends on the original Turbopack runtime.
*/
const moduleFactory = (e) => {
"use strict";
var t = e.i(462214),
n = e.i(358379),
i = e.i(403094),
r = e.i(292002),
a = e.i(768924),
o = e.i(575091),
s = e.i(41671),
c = e.i(777784),
l = e.i(45523),
u = e.i(722573),
h = e.i(395132),
f = e.i(184656);
e.i(204347);
var d = e.i(317286),
p = e.i(703962),
g = e.i(713118),
b = e.i(182004),
m = e.i(500724),
w = e.i(677588),
v = e.i(606095),
x = e.i(299750),
y = e.i(733077),
_ = e.i(562530),
S = e.i(216257),
E = e.i(929286),
M = e.i(791997),
T = e.i(72789),
k = e.i(664115),
C = e.i(295085),
A = e.i(10036),
N = e.i(42939),
I = e.i(111581),
P = e.i(44980),
R = e.i(275704),
L = e.i(306677),
D = e.i(717139),
j = e.i(36108),
O = e.i(464025),
F = e.i(329931),
U = e.i(457044),
B = e.i(500536),
H = e.i(715636),
z = e.i(316925),
G = e.i(959248),
$ = e.i(380332),
V = e.i(251292),
W = e.i(589001),
K = e.i(710871),
q = e.i(260561),
X = e.i(124821),
Y = e.i(799093),
J = e.i(439552),
Z = e.i(983802);
let Q = 0,
ee = [];
function et() {
for (; ee.length > 0 && Q < 3; ) {
let e = ee.shift();
if (!e) break;
Q++, e.resolve(en());
}
}
function en() {
let e = !1,
t = setTimeout(() => {
e ||
(console.warn(
"[VideoLoadLimiter] slot 超时自动释放(可能存在泄漏)",
),
(e = !0),
Q--,
et());
}, 15e3);
return () => {
e || ((e = !0), clearTimeout(t), Q--, et());
};
}
function ei(e) {
let t = ee.findIndex((t) => t.id === e);
-1 !== t && ee.splice(t, 1);
}
var er = e.i(174008),
ea = e.i(419065);
let eo = new Map();
function es(e) {
let t = eo.get(e);
return t
? Promise.resolve(t)
: new Promise((t) => {
let n = new Image();
(n.onload = () => {
let i = (0, g.computeNodeDimensionsFromNatural)(
n.naturalWidth,
n.naturalHeight,
);
eo.set(e, i), t(i);
}),
(n.onerror = () =>
t({ width: g.NODE_WIDTH, height: g.NODE_WIDTH })),
(n.src = e);
});
}
function ec(e, t) {
let n = S.stores.canvas;
if (!n) return;
let i = n.getNode(e);
if (!i) return;
let r = t.duration && isFinite(t.duration) ? t.duration : void 0,
a = t.videoWidth > 0 ? t.videoWidth : void 0,
o = t.videoHeight > 0 ? t.videoHeight : void 0;
if (!r && !a && !o) return;
let s = i.resourceMeta;
if (!s?.items.length)
return void n.updateNodeData(e, {
resourceMeta: {
items: [{ kind: "video", durationSec: r, width: a, height: o }],
},
});
let c = s.items[0];
if ("video" !== c.kind) return;
let l = !1,
u = { ...c };
null == r || u.durationSec || ((u.durationSec = r), (l = !0)),
null == a || u.width || ((u.width = a), (l = !0)),
null == o || u.height || ((u.height = o), (l = !0)),
l &&
n.updateNodeData(e, {
resourceMeta: { items: [u, ...s.items.slice(1)] },
});
}
let el = [0, 2, 4, 6],
eu = (0, n.memo)(function ({ id: et, selected: eo }) {
let eu = (0, S.useCanvasStore)((e) => e.getNode(et)?.data),
eh = (0, S.useCanvasStore)((0, E.selectHasIncomingEdge)(et)),
ef = (0, S.useCanvasStore)((0, E.selectNodeResourceMeta)(et)),
{
updateNodeData: ed,
markDownstreamStale: ep,
addNode: eg,
addNodes: eb,
addEdge: em,
applyNodeChanges: ew,
} = (0, S.useCanvasStore)((e) => ({
updateNodeData: e.updateNodeData,
markDownstreamStale: e.markDownstreamStale,
addNode: e.addNode,
addNodes: e.addNodes,
addEdge: e.addEdge,
applyNodeChanges: e.applyNodeChanges,
})),
ev = (0, S.useCanvasStore)((e) => e.isReadonly),
ex = (0, S.useCanvasStore)((e) => e.projectId),
ey = (0, S.useCanvasStore)(
(e) => e.isMarkMode && e.markSourceNodeId === et,
),
e_ = (0, S.useGlobalStore)((e) => e.getModel),
eS = (0, M.useCanvasThemeStore)((e) => e.theme),
eE = (0, D.useNodeDimensionSync)(et),
[eM, eT] = (0, n.useState)(!1),
[ek, eC] = (0, n.useState)(!1),
eA = (0, n.useCallback)(() => eC(!0), []),
eN = (0, n.useCallback)(() => eC(!1), []),
eI = (0, O.useShouldShowGenerator)(eo, et) || ey,
eP = !!eu?.assetVideoAssetId,
eR = eI && !eM && (!(0, b.isResourceAction)(eu?.action) || eP),
eL = (0, f.useIncomingNodeData)(et),
{ getNode: eD, getNodes: ej } = (0, a.useReactFlow)(),
eO = (0, B.useVideoTargetWidth)(g.NODE_WIDTH),
eF = (0, S.useRootStore)(),
eU = (0, n.useCallback)(
(e) => {
let t = ej().map((t) => ({
type: "select",
id: t.id,
selected: t.id === e,
}));
t.push({ type: "select", id: e, selected: !0 }), ew(t);
},
[ej, ew],
),
eB = (0, $.useNodeInteraction)(et, eo),
{
isDraggingConnection: eH,
pipelineNodeStatus: ez,
pipelineBorderColor: eG,
} = eB,
e$ = (0, G.isTaskGenerating)(eu?.taskInfo),
eV = (0, G.isTaskFailed)(eu?.taskInfo),
eW = (0, n.useCallback)(() => {
let e = eu?.taskInfo?.taskId;
e &&
(0, x.stopTaskBatch)([e]).then(() => {
let t = S.stores.canvas?.getNode(et),
n = t?.data;
n?.taskInfo?.taskId !== e ||
ed(et, {
taskInfo: n?.prevTaskInfo ?? void 0,
prevTaskInfo: void 0,
});
});
}, [eu?.taskInfo?.taskId, et, ed]),
eK = eu?.url ?? [],
eq = eK[0],
eX = !!eq,
eY = !!eq && (eq.startsWith("blob:") || eq.startsWith("data:")),
{
retryKey: eJ,
showRetryButton: eZ,
handleLoadError: eQ,
handleLoadSuccess: e1,
triggerManualRetry: e0,
} = (0, v.useResourceRetry)(eY ? void 0 : eq),
[e2, e3] = (0, n.useState)(!1),
[e4, e5] = (0, n.useState)(!1),
e6 = (0, n.useRef)(eq);
(0, n.useEffect)(() => {
let e = e6.current;
e6.current = eq;
let t = !!e && (e.startsWith("blob:") || e.startsWith("data:")),
n = !!eq && (eq.startsWith("blob:") || eq.startsWith("data:"));
t && eq && !n ? e3(!0) : e3(!1), e5(!1);
}, [eq]),
(0, n.useEffect)(() => {
if (!e4 || !e2) return;
let e = setTimeout(() => e3(!1), 350);
return () => clearTimeout(e);
}, [e4, e2]);
let e8 = eK.length > 1,
e9 = eu?.poster,
e7 = !eY && eq ? (0, C.getVideoSnapshotForWidth)(eq, eO) : null,
te = (0, U.useTierCommit)(e7, eq),
tt = (0, n.useRef)(null);
(0, n.useEffect)(() => {
if (eq && !eY) {
if (tt.current === eq)
return void (0, T.preDecodeAdjacentVideoTiers)(eq, eO);
(tt.current = eq),
(0, T.prefetchAllVideoTiers)(eq, eO, et),
(0, T.preDecodeAdjacentVideoTiers)(eq, eO);
}
}, [eq, eY, eO, et]);
let tn = (0, n.useMemo)(() => {
let e = eu?.name || eu?.label || "视频";
if (
eu?.generatorType !== b.GeneratorType.ENHANCE ||
(eu?.name && "高清" !== eu.name)
)
return e;
let t = eu?.params,
n = t?.resolution,
i = {
"1080p": "1080P",
"2K": "2K",
"4K": "4K",
"2k": "2K",
"4k": "4K",
};
if ("string" == typeof n && i[n]) return `高清(${i[n]})`;
let r = t?.scale,
a =
"number" == typeof r
? r
: "string" == typeof r
? parseInt(String(r), 10)
: NaN;
return Number.isInteger(a) && a > 0
? `高清(${a} 倍)`
: e || "高清";
}, [
eu?.generatorType,
eu?.params?.scale,
eu?.params?.resolution,
eu?.name,
eu?.label,
]),
ti = eu?._pendingThirdAssetUuid,
tr = eu?._starVideoCheckStatus,
{ isReviewing: ta } = (0, F.useThirdAssetNodeSync)({
id: et,
nodeType: b.NodeType.VIDEO,
pendingUuid: ti,
updateNodeData: ed,
}),
to = ta || "checking" === tr,
ts = "failed" === tr,
tc = (0, n.useMemo)(
() =>
to
? (0, t.jsxs)("span", {
className:
"flex items-center gap-0.5 text-[12px] text-[#09CAF5]/80",
children: [
(0, t.jsx)("span", {
className:
"mr-0.5 inline-block h-1.5 w-1.5 animate-pulse rounded-full bg-[#09CAF5]",
}),
"校验中",
],
})
: ts
? (0, t.jsx)("span", {
className:
"flex items-center text-[12px] text-[#F5514F]/80",
children: "审核失败",
})
: eP
? (0, t.jsx)(u.Tooltip, {
label: "素材内容已合规,可用于Seedance2.0视频生成",
position: "top",
withArrow: !0,
zIndex: 720,
children: (0, t.jsx)("span", {
className: "flex shrink-0 items-center",
children: (0, t.jsx)(s.Icons.ShieldCheck, {
width: 14,
height: 14,
className: "text-[#09CAF5]",
}),
}),
})
: void 0,
[to, ts, eP],
),
tl = (0, n.useMemo)(
() => (0, R.getNodeTitleDimensionHint)(ef ?? void 0),
[ef],
),
tu = (0, n.useCallback)((e) => ed(et, { name: e }), [et, ed]),
th = (0, n.useCallback)(() => ed(et, { isStale: !1 }), [et, ed]),
tf = (0, n.useCallback)(async () => {
let e = S.stores.canvas?.getNode(et),
t = e?.data,
n = t?.params;
if (!n) return;
let i =
t?.generatorType === b.GeneratorType.ENHANCE
? "enhanceVideo"
: "video",
r = {
...n,
textList: eL.textList,
imageList: eL.imageList,
videoList: eL.videoList,
audioList: eL.audioList,
};
ed(et, {
isStale: !1,
params: r,
taskInfo: {
taskId: "",
loading: !0,
status: 0,
failedReason: void 0,
},
});
try {
let e = (0, A.buildRequestData)(r, i, et, ex, e_, "video"),
t = await (0, _.submitGenerationTask)(e);
if (t.success) {
if (!t.taskId) {
c.Notify.error("任务创建成功但缺少 taskId,请重试"),
ed(et, {
taskInfo: {
taskId: "",
loading: !1,
status: 3,
failedReason: "任务创建成功但缺少 taskId",
},
});
return;
}
ed(et, {
taskInfo: {
taskId: t.taskId,
loading: !0,
status: 0,
failedReason: void 0,
},
});
return;
}
t.handledByCommercial || c.Notify.error(t.errorMsg ?? "生成失败"),
ed(et, {
taskInfo: {
taskId: "",
loading: !1,
status: 3,
failedReason: t.errorMsg ?? "生成失败",
},
});
} catch {
c.Notify.error("网络异常,请重试"),
ed(et, {
taskInfo: {
taskId: "",
loading: !1,
status: 3,
failedReason: "网络异常,请重试",
},
});
}
}, [et, eL, ex, e_, ed]),
td = (0, n.useCallback)(() => {
tf();
}, [tf]),
tp = e$ && (eX || !!e9),
tg = e9 || e7 || void 0,
tb = e$
? tp
? "generating_with_content"
: "generating"
: eV
? "failed"
: eX
? "resource"
: eh
? "pending"
: "empty_generate",
{
loaded: tm,
nodeWidth: tw,
nodeHeight: tv,
} = (0, V.useImageNodeHeight)(
tg,
eu?.contentWidth,
eu?.contentHeight,
),
[tx, ty] = (0, n.useState)(null),
t_ = tx?.width ?? eu?.contentWidth ?? tw,
tS = tx?.height ?? eu?.contentHeight ?? tv,
tE =
tm ||
null !== tx ||
(eu?.contentWidth != null && eu?.contentHeight != null),
tM = (0, g.extractRatioFromNodeParams)(eu?.params ?? void 0),
tT = (0, n.useMemo)(
() => (0, g.computeNodeDimensionsFromRatio)(tM),
[tM],
),
tk = eu?.contentWidth != null && eu?.contentHeight != null,
tC = (eX && !e$ && !eV) || tp || ((e$ || eV) && tk) ? t_ : tT.width;
(0, j.useFrozenEffect)(() => {
if (!tx) return;
let e = S.stores.canvas?.getNode(et)?.data,
t = "number" == typeof e?.contentWidth ? e.contentWidth : void 0,
n = "number" == typeof e?.contentHeight ? e.contentHeight : void 0;
(t !== t_ || n !== tS) &&
ed(et, { contentWidth: t_, contentHeight: tS });
}, [tx, t_, tS, et, ed]);
let [tA, tN] = (0, n.useState)(!1),
[tI, tP] = (0, n.useState)(null),
[tR, tL] = (0, n.useState)(null),
[tD, tj] = (0, n.useState)(!1),
tO = (0, n.useRef)(null),
tF = (0, n.useCallback)(() => {
tj(!0),
tO.current && clearTimeout(tO.current),
(tO.current = setTimeout(() => tj(!1), 350));
}, []);
(0, n.useEffect)(
() => () => {
tO.current && clearTimeout(tO.current);
},
[],
);
let [tU, tB] = (0, n.useState)(!1),
tH = tU && !eH,
tz = (0, n.useRef)(eH);
tz.current = eH;
let tG = (0, n.useRef)(null),
t$ = (0, n.useCallback)(() => {
tz.current || (tG.current = setTimeout(() => tB(!0), 300));
}, []),
tV = (0, n.useCallback)(() => {
tG.current && (clearTimeout(tG.current), (tG.current = null)),
tB(!1);
}, []),
tW = eI && !ev,
tK = eI || tH,
tq = !(!eY && e7) || eI || tH,
[tX, tY] = (0, n.useState)(!1),
tJ = (0, n.useRef)(),
tZ = !ev || eo || tH || e2;
(0, j.useFrozenEffect)(() => {
let e = eF.canvasStore;
function t() {
!e.getState().isInteracting && tZ
? (clearTimeout(tJ.current), tY(!0))
: (clearTimeout(tJ.current),
(tJ.current = setTimeout(() => tY(!1), 1500)));
}
t();
let n = e.subscribe((e, n) => {
e.isInteracting !== n.isInteracting && t();
});
return () => {
n(), clearTimeout(tJ.current), tY(!1);
};
}, [eF, tZ]);
let {
isFullScreen: tQ,
openFullScreen: t1,
closeFullScreen: t0,
} = (0, W.useNodeFullScreen)(),
t2 = (0, n.useRef)(0),
t3 = (0, n.useRef)(null),
t4 = (0, J.useUploadOverlay)(et),
t5 = (eI || tH) && !tQ && !t4,
t6 = (0, n.useRef)(t5);
t6.current = t5;
let t8 = (0, n.useCallback)(() => {
t3.current?.pause(), t1();
}, [t1]),
t9 = (0, n.useCallback)(() => {
let e = t3.current;
e && t2.current > 0 && (e.currentTime = t2.current), t0();
}, [t0]),
[t7, ne] = (0, n.useState)(void 0),
nt = (0, n.useRef)(null);
(0, n.useEffect)(() => {
if (!tX || !tq || !eq) {
ne(void 0),
ei(et),
nt.current && (nt.current(), (nt.current = null));
return;
}
let e = !1;
return (
new Promise((e) => {
Q < 3 ? (Q++, e(en())) : ee.push({ resolve: e, id: et });
}).then((t) => {
e ? t() : ((nt.current = t), ne(eq));
}),
() => {
(e = !0),
ei(et),
nt.current && (nt.current(), (nt.current = null));
}
);
}, [tX, tq, eq, et, eJ]);
let nn = (0, n.useRef)(null),
[ni, nr] = (0, n.useState)(!1),
[na, no] = (0, n.useState)(1),
[ns, nc] = (0, n.useState)(!1),
[nl, nu] = (0, n.useState)(0),
[nh, nf] = (0, n.useState)(0),
nd = ef?.items?.[0],
np = nd?.kind === "video" ? (nd.durationSec ?? 0) : 0,
ng = nh > 0 ? nh : np,
[nb, nm] = (0, n.useState)(null),
[nw, nv] = (0, n.useState)(!1),
[nx, ny] = (0, n.useState)(void 0),
[n_, nS] = (0, n.useState)(!1),
[nE, nM] = (0, n.useState)(0),
nT = (0, n.useRef)(null),
nk = (0, n.useRef)(na);
nk.current = na;
let nC = (0, n.useRef)(ns);
nC.current = ns;
let nA =
!!eq && nh > 0 && nh <= 600 && !!nb && 1080 >= Math.min(nb.w, nb.h),
nN = (0, n.useCallback)(() => {
eT(!0),
eq &&
!(nh <= 0) &&
(async () => {
let t,
{ AVEditor: n, createAVWorker: i } = await e.A(490917);
try {
t = i();
} catch (e) {
console.warn("[VideoNode] Failed to create AV worker", e);
}
let r = new n({
url: eq,
duration: nh,
frameHeight: 64,
frameCount: 12,
worker: t,
});
r.onEncodeProgress((e) => nM(e)),
nT.current && nT.current.dispose(),
(nT.current = r);
})();
}, [eq, nh]);
(0, n.useEffect)(
() => () => {
nT.current && (nT.current.dispose(), (nT.current = null));
},
[],
);
let nI = (0, n.useCallback)(
(t) => {
let n = nT.current;
if (!n?.supportsEncode) {
eT(!1), ed(et, { clipRange: t });
return;
}
nS(!0),
nM(0),
(async () => {
try {
let i,
a = await n.encode(t.start, t.end),
o = new File([a], `clip-${Date.now()}.mp4`, {
type: "video/mp4",
}),
{ validateVideoFile: s } = await e.A(645867),
l = await s(o);
if (l) {
c.Notify.error(l), nS(!1);
return;
}
let { getCookie: u } = await e.A(710867),
{ uploadViaPreSign: h, resolveUploadUrl: f } =
await e.A(33412),
{ USER_TOKEN_COOKIE_KEY: d, USER_UUID_COOKIE_KEY: p } =
await e.A(525723),
m = u(d),
w = u(p);
if (
!m ||
"string" != typeof m ||
!w ||
"string" != typeof w
) {
c.Notify.error("请先登录"), nS(!1);
return;
}
let v = await h(o, {
token: m,
uuid: w,
onCalcHashEnd: (e) => {
i = e;
},
verify: !1,
}),
x = f(v);
if (x) {
let e = eD(et);
if (e) {
let t = crypto.randomUUID();
eg({
id: t,
type: b.NodeType.VIDEO,
data: {
type: b.NodeType.VIDEO,
name: "剪辑",
url: [],
poster: "",
action: b.NodeAction.VIDEO_RESOURCE,
},
position: {
x: e.position.x + tC + g.NODE_GAP,
y: e.position.y,
},
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
}),
em({ source: et, target: t }),
eU(t),
S.stores.canvas?.updateNodeData(t, {
url: [x],
resourceMeta: (0, L.buildUploadedResourceMeta)(
o,
b.NodeType.VIDEO,
{ hashSha1: i },
),
});
}
}
eT(!1), nS(!1), n.dispose(), (nT.current = null);
} catch (e) {
console.error("视频剪辑失败:", e),
c.Notify.error("视频合成失败"),
nS(!1);
}
})();
},
[et, ed, eD, eg, em, eU, tC],
),
nP = (0, n.useCallback)(() => {
eT(!1),
nS(!1),
nT.current && (nT.current.dispose(), (nT.current = null));
}, []),
[nR, nL] = (0, n.useState)(!0);
(0, n.useEffect)(() => {
nL(!0);
}, [eq, eJ]),
(0, n.useEffect)(() => {
let e = t3.current;
e && ((e.crossOrigin = nR ? "anonymous" : ""), nR || e.load());
}, [nR]);
let nD = (0, n.useRef)(nR);
nD.current = nR;
let nj = (0, n.useRef)(e2);
nj.current = e2;
let nO = (0, n.useRef)(eQ);
nO.current = eQ;
let nF = (0, n.useRef)(e1);
(nF.current = e1),
(0, n.useEffect)(() => {
if (!tX || !tq) return;
let e = nn.current;
if (!e) return;
let t = (0, Z.acquireVideoElement)(et);
(t.className = "h-full w-full object-cover"),
(t.crossOrigin = nD.current ? "anonymous" : ""),
(t.volume = nk.current),
(t.muted = nC.current),
(t.playsInline = !0),
(t.preload = ev ? "none" : "metadata"),
(t3.current = t);
let n = () => {
nD.current &&
(console.warn(
`[VideoNode ${et}] 视频 CORS 加载失败,降级为非跨域模式`,
),
nL(!1));
},
i = () => {
nj.current && (e5(!0), t.play().catch(() => void 0));
};
return (
t.addEventListener("error", n),
t.addEventListener("canplay", i),
e.contains(t) || e.appendChild(t),
t.offsetWidth,
(t.currentTime = 0),
() => {
t.removeEventListener("error", n),
t.removeEventListener("canplay", i),
(t3.current = null),
e.contains(t) && e.removeChild(t),
(0, Z.releaseVideoElement)(et);
}
);
}, [et, tX, tq, eq]),
(0, n.useEffect)(() => {
let e = t3.current;
e &&
t7 &&
(e.src !== t7 ? (e.src = t7) : e.readyState < 2 && e.load());
}, [t7, eJ]),
(0, n.useEffect)(() => {
let e = t3.current;
e && (te ? (e.poster = te) : e.removeAttribute("poster"));
}, [te]),
(0, n.useEffect)(() => {
let e = t3.current;
if (!e) return;
nr(!1), nu(0), nf(0), ty(null), nm(null), nv(!1), ny(void 0);
let t = !1,
n = () => {
if (t) return;
let n = (0, N.detectVideoHasAudio)(e, {
minCurrentTimeSec: 0.5,
});
null !== n && ((t = !0), ny(n));
},
i = () => {
e.videoWidth > 0 &&
e.videoHeight > 0 &&
(ty(
(0, g.computeNodeDimensionsFromNatural)(
e.videoWidth,
e.videoHeight,
),
),
nm({ w: e.videoWidth, h: e.videoHeight }));
},
r = () => {
nu(e.currentTime), t || n();
},
a = () => {
e.duration && isFinite(e.duration) && nf(e.duration),
i(),
ec(et, e),
nt.current && (nt.current(), (nt.current = null)),
t6.current && e.play().catch(() => void 0),
nF.current();
},
o = () => {
e.duration && isFinite(e.duration) && nf(e.duration), i();
},
s = () => nr(!0),
c = () => nr(!1),
l = () => {
nr(!1), e.loop || ((e.currentTime = 0), nu(0));
},
u = () => {
nv(!0), n();
},
h = () => {
nt.current && (nt.current(), (nt.current = null));
},
f = () => {
console.warn(`[VideoNode ${et}] 视频加载失败,释放并发 slot`),
h(),
nD.current || nO.current();
};
return (
e.addEventListener("timeupdate", r),
e.addEventListener("loadedmetadata", a),
e.addEventListener("durationchange", o),
e.addEventListener("play", s),
e.addEventListener("pause", c),
e.addEventListener("ended", l),
e.addEventListener("loadeddata", u),
e.addEventListener("error", f),
e.readyState >= 1
? (e.duration && isFinite(e.duration) && nf(e.duration),
i(),
ec(et, e),
h(),
t6.current && e.play().catch(() => void 0))
: t6.current && e.src && e.play().catch(() => void 0),
e.readyState >= 2 && u(),
e.paused || (nr(!0), nu(e.currentTime)),
() => {
e.removeEventListener("timeupdate", r),
e.removeEventListener("loadedmetadata", a),
e.removeEventListener("durationchange", o),
e.removeEventListener("play", s),
e.removeEventListener("pause", c),
e.removeEventListener("ended", l),
e.removeEventListener("loadeddata", u),
e.removeEventListener("error", f);
}
);
}, [t7, tX, eJ]);
let nU = (0, n.useRef)(!1);
(0, j.useFrozenEffect)(() => {
let e = t3.current;
if (e && eq) {
if (eY) {
e.pause(), (nU.current = !1);
return;
}
return (
t5 && !nU.current
? e.play().catch(() => void 0)
: !t5 && nU.current && e.pause(),
(nU.current = t5),
() => {
e.pause(), (nU.current = !1);
}
);
}
}, [t5, eq, eY]);
let nB = (0, n.useCallback)(
({ cdnUrl: e, resourceMeta: t }) => {
let n = eD(et);
ed(et, {
url: [e],
poster: "",
resourceMeta: (0, L.mergeResourceMetaBundle)(
n?.resourceMeta,
t,
),
}),
ep(et);
},
[et, eD, ed, ep],
),
{ requestFileUpload: nH } = (0, I.useCanvasCallbacks)(),
nz = (0, n.useCallback)(
(t) => {
if (!t.type.startsWith("video/"))
return void (0, J.setUploadOverlay)(et, {
type: "error",
message: "请选择视频文件",
});
(0, J.setUploadOverlay)(et, { type: "uploading" });
let n = URL.createObjectURL(t),
i = eD(et)?.resourceMeta;
ed(et, {
url: [n],
poster: "",
action: b.NodeAction.VIDEO_RESOURCE,
resourceMeta: (0, L.buildUploadedResourceMeta)(
t,
b.NodeType.VIDEO,
{ previous: i },
),
}),
(async () => {
let { validateVideoFile: r } = await e.A(645867),
{ getCookie: a } = await e.A(710867),
{
uploadViaPreSign: o,
resolveUploadUrl: s,
pollMediaAudit: l,
AuditContentType: u,
MediaAuditError: h,
FileReviewError: f,
} = await e.A(33412),
{ USER_TOKEN_COOKIE_KEY: d, USER_UUID_COOKIE_KEY: p } =
await e.A(525723),
g = () => {
URL.revokeObjectURL(n),
ed(et, {
url: [],
poster: "",
action: void 0,
resourceMeta: i,
});
};
try {
let e,
c = await r(t);
if (c) {
g(),
(0, J.setUploadOverlay)(et, {
type: "error",
message: c,
});
return;
}
let h = a(d),
f = a(p);
if (
!h ||
"string" != typeof h ||
!f ||
"string" != typeof f
) {
g(),
(0, J.setUploadOverlay)(et, {
type: "error",
message: "请先登录",
});
return;
}
let m = await o(t, {
token: h,
uuid: f,
verify: !1,
onCalcHashEnd: (t) => {
e = t;
},
onProgress: (e) =>
(0, J.setUploadOverlay)(et, {
type: "uploading",
progress: e,
}),
}),
w = s(m);
if (!w) {
g(),
(0, J.setUploadOverlay)(et, {
type: "error",
message: "上传失败",
});
return;
}
await l(w, u.VIDEO),
URL.revokeObjectURL(n),
ed(et, {
url: [w],
poster: "",
resourceMeta: (0, L.buildUploadedResourceMeta)(
t,
b.NodeType.VIDEO,
{ hashSha1: e, previous: i },
),
}),
ep(et),
(0, J.setUploadOverlay)(et, { type: "success" });
} catch (e) {
console.error("视频上传失败:", e),
g(),
e instanceof h || e instanceof f
? (0, J.setUploadOverlay)(et, {
type: "error",
message: e.message,
})
: (c.Notify.error("视频上传失败,请重试"),
(0, J.setUploadOverlay)(et, {
type: "error",
message: "上传失败",
}));
}
})();
},
[et, eD, ed, ep],
),
nG = (0, n.useCallback)(() => {
nH({ accept: "video/*", onFile: nz });
}, [nH, nz]),
n$ = (0, n.useCallback)(async () => {
if (eh) return;
let e = eD(et);
if (!e) return;
let t = m.VIDEO_PRESETS.firstFrame.imageUrl,
n = await es(t),
i = crypto.randomUUID(),
a = {
id: i,
type: b.NodeType.IMAGE,
data: {
type: b.NodeType.IMAGE,
name: "首帧",
url: [t],
alt: "首帧图片",
action: b.NodeAction.IMAGE_RESOURCE,
contentWidth: n.width,
contentHeight: n.height,
},
position: {
x: e.position.x - n.width - g.NODE_GAP,
y: e.position.y,
},
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
};
ed(et, { params: { prompt: m.VIDEO_PRESETS.firstFrame.prompt } }),
eg(a),
em({
id: `e-${i.slice(0, 8)}-${et.slice(0, 8)}`,
source: i,
sourceHandle: "source",
target: et,
targetHandle: "target",
}),
eU(et);
}, [et, eh, eD, eg, em, eU]),
nV = (0, n.useCallback)(() => {
n$();
}, [n$]),
nW = (0, n.useCallback)(async () => {
if (eh) return;
let e = eD(et);
if (!e) return;
let t = m.VIDEO_PRESETS.firstLastFrame.firstImageUrl,
n = m.VIDEO_PRESETS.firstLastFrame.lastImageUrl,
[i, a] = await Promise.all([es(t), es(n)]),
o = Math.max(i.width, a.width),
s = e.position.x - o - g.NODE_GAP,
c = e.position.y + tT.height / 2,
l = c - 20 - i.height,
u = crypto.randomUUID(),
h = {
id: u,
type: b.NodeType.IMAGE,
data: {
type: b.NodeType.IMAGE,
name: "首帧",
url: [t],
alt: "首帧图片",
action: b.NodeAction.IMAGE_RESOURCE,
contentWidth: i.width,
contentHeight: i.height,
},
position: { x: s, y: l },
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
},
f = crypto.randomUUID();
eb([
h,
{
id: f,
type: b.NodeType.IMAGE,
data: {
type: b.NodeType.IMAGE,
name: "尾帧",
url: [n],
alt: "尾帧图片",
action: b.NodeAction.IMAGE_RESOURCE,
contentWidth: a.width,
contentHeight: a.height,
},
position: { x: s, y: c + 20 },
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
},
]),
ed(et, {
params: { prompt: m.VIDEO_PRESETS.firstLastFrame.prompt },
});
let d = {
id: `e-${u.slice(0, 8)}-${et.slice(0, 8)}`,
source: u,
sourceHandle: "source",
target: et,
targetHandle: "target",
},
p = {
id: `e-${f.slice(0, 8)}-${et.slice(0, 8)}`,
source: f,
sourceHandle: "source",
target: et,
targetHandle: "target",
};
em(d), em(p), eU(et);
}, [et, eh, eD, eb, em, eU]),
nK = (0, n.useCallback)(() => {
nW();
}, [nW]),
nq = (0, n.useCallback)(
(e) => {
e.stopPropagation();
let t = t3.current;
t && (ni ? t.pause() : t.play().catch(() => void 0));
},
[ni],
),
nX = (0, n.useCallback)((e) => {
let t = t3.current;
t && ((t.volume = e), (t.muted = 0 === e), no(e), nc(0 === e));
}, []),
nY = (0, n.useCallback)(() => {
let e = t3.current;
if (!e) return;
let t = !ns;
(e.muted = t), nc(t), t || 0 !== na || ((e.volume = 0.5), no(0.5));
}, [ns, na]),
nJ = (0, n.useCallback)((e) => {
let t = t3.current;
t && ((t.currentTime = e), nu(e));
}, []),
nZ = (0, n.useCallback)(
(e, t) =>
Number.isFinite(t)
? 0.05 > Math.abs(e.currentTime - t)
? Promise.resolve(!0)
: new Promise((n) => {
let i = !1,
r = null,
a = null,
o = (t) => {
i ||
((i = !0),
a && e.removeEventListener("seeked", a),
r && clearTimeout(r),
n(t));
};
(a = () => o(!0)),
(r = setTimeout(() => o(!1), 1500)),
e.addEventListener("seeked", a);
try {
e.currentTime = t;
} catch {
o(!1);
}
})
: Promise.resolve(!1),
[],
),
nQ = (0, n.useCallback)(
async (e, t) => {
if (!nR)
return (
c.Notify.error("截图不可用:视频服务未启用跨域访问(CORS)"),
null
);
if (
t?.targetTimeSec != null &&
(e.pause(), !(await nZ(e, t.targetTimeSec)))
)
return c.Notify.error("定位视频帧失败,请重试"), null;
let n = document.createElement("canvas");
(n.width = e.videoWidth || e.clientWidth),
(n.height = e.videoHeight || e.clientHeight);
let i = n.getContext("2d");
if (!i) return null;
try {
i.drawImage(e, 0, 0, n.width, n.height);
} catch {
return c.Notify.error("截图失败(可能是跨域限制)"), null;
}
return t?.restoreTimeSec != null && nZ(e, t.restoreTimeSec), n;
},
[nR, nZ],
),
n1 = (0, n.useCallback)(
(t, n) => {
let i;
try {
i = t.toDataURL("image/png");
} catch {
c.Notify.error("截图失败(canvas 跨域限制)");
return;
}
let a = eD(et);
if (!a) return;
let o = n?.name ?? "截图",
s = n?.alt ?? "视频截图",
l = crypto.randomUUID(),
u = t.width,
h = t.height,
f =
u > 0 && h > 0
? { items: [{ kind: "image", width: u, height: h }] }
: void 0;
eg({
id: l,
type: b.NodeType.IMAGE,
data: {
type: b.NodeType.IMAGE,
name: o,
url: [i],
alt: s,
action: b.NodeAction.IMAGE_RESOURCE,
...(f ? { resourceMeta: f } : {}),
},
position: {
x: a.position.x + tC + g.NODE_GAP,
y: a.position.y,
},
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
}),
(async () => {
try {
let n,
i = await new Promise((e) => t.toBlob(e, "image/png"));
if (!i) return;
let r = new File([i], `screenshot-${Date.now()}.png`, {
type: "image/png",
}),
{ getCookie: a } = await e.A(710867),
{ uploadViaPreSign: o, resolveUploadUrl: s } =
await e.A(33412),
{ USER_TOKEN_COOKIE_KEY: u, USER_UUID_COOKIE_KEY: h } =
await e.A(525723),
d = a(u),
p = a(h);
if (
!d ||
"string" != typeof d ||
!p ||
"string" != typeof p
)
return void c.Notify.error("请先登录");
let g = await o(r, {
token: d,
uuid: p,
onCalcHashEnd: (e) => {
n = e;
},
}),
m = s(g);
if (m)
if (eD(l)) {
let e = (0, L.buildUploadedResourceMeta)(
r,
b.NodeType.IMAGE,
{ hashSha1: n, previous: f },
);
ed(l, { url: [m], resourceMeta: e });
} else
console.warn("截图上传完成但节点已被删除,跳过更新");
} catch (e) {
console.error("截图上传失败:", e),
c.Notify.error("截图上传失败");
}
})();
},
[et, eD, eg, ed, tC],
),
n0 = (0, n.useCallback)(
(e) => {
e.stopPropagation();
let t = t3.current;
t &&
(async () => {
let e = await nQ(t);
e && n1(e, { name: "截图", alt: "视频截图" });
})();
},
[nQ, n1],
),
n2 = (0, n.useCallback)(
async (e) => {
if (!eq) return null;
if (!nR)
return (
c.Notify.error("截图不可用:视频服务未启用跨域访问(CORS)"),
null
);
let t = document.createElement("video");
(t.muted = !0),
(t.playsInline = !0),
(t.crossOrigin = "anonymous"),
(t.preload = "auto");
try {
await new Promise((e, n) => {
let i = setTimeout(() => {
t.removeAttribute("src"), t.load(), n(Error("timeout"));
}, 8e3);
t.addEventListener(
"loadeddata",
() => {
clearTimeout(i), e();
},
{ once: !0 },
),
t.addEventListener(
"error",
() => {
clearTimeout(i), n(Error("load error"));
},
{ once: !0 },
),
(t.src = eq);
}),
await new Promise((n, i) => {
let r = setTimeout(() => i(Error("seek timeout")), 3e3);
t.addEventListener(
"seeked",
() => {
clearTimeout(r), n();
},
{ once: !0 },
),
(t.currentTime = e);
});
let n = document.createElement("canvas");
(n.width = t.videoWidth || t.clientWidth),
(n.height = t.videoHeight || t.clientHeight);
let i = n.getContext("2d");
if (!i) return null;
return i.drawImage(t, 0, 0, n.width, n.height), n;
} catch (e) {
return (
console.error("离屏截帧失败:", e),
c.Notify.error("截帧失败,请重试"),
null
);
} finally {
t.removeAttribute("src"), t.load();
}
},
[eq, nR],
),
n3 = (0, n.useCallback)(
(e) => {
e.stopPropagation(),
(async () => {
let e = await n2(0);
e && n1(e, { name: "首帧", alt: "视频首帧" });
})();
},
[n2, n1],
),
n4 = (0, n.useCallback)(
(e) => {
e.stopPropagation();
let t = t3.current,
n = t && t.duration > 0 ? t.duration : ng;
if (!(n > 0))
return void c.Notify.error(
"视频尚未加载完成,暂时无法截取尾帧",
);
let i = Math.max(n - 0.05, 0);
(async () => {
let e = await n2(i);
e && n1(e, { name: "尾帧", alt: "视频尾帧" });
})();
},
[ng, n2, n1],
);
(0, n.useCallback)(
(t) => {
let n;
if (!nR)
return void c.Notify.error(
"截图不可用:视频服务未启用跨域访问(CORS)",
);
t.pause();
let i = document.createElement("canvas");
(i.width = t.videoWidth || t.clientWidth),
(i.height = t.videoHeight || t.clientHeight);
let a = i.getContext("2d");
if (!a) return;
try {
a.drawImage(t, 0, 0, i.width, i.height);
} catch {
c.Notify.error("截图失败(可能是跨域限制)");
return;
}
try {
n = i.toDataURL("image/png");
} catch {
c.Notify.error("截图失败(canvas 跨域限制)");
return;
}
let o = eD(et);
if (!o) return;
let s = crypto.randomUUID();
eg({
id: s,
type: b.NodeType.IMAGE,
data: {
type: b.NodeType.IMAGE,
name: "截图",
url: [n],
alt: "视频截图",
action: b.NodeAction.IMAGE_RESOURCE,
},
position: { x: o.position.x + tC + g.NODE_GAP, y: o.position.y },
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
}),
(async () => {
try {
let t,
n = await new Promise((e) => i.toBlob(e, "image/png"));
if (!n) return;
let r = new File([n], `screenshot-${Date.now()}.png`, {
type: "image/png",
}),
{ getCookie: a } = await e.A(710867),
{ uploadViaPreSign: o, resolveUploadUrl: l } =
await e.A(33412),
{ USER_TOKEN_COOKIE_KEY: u, USER_UUID_COOKIE_KEY: h } =
await e.A(525723),
f = a(u),
d = a(h);
if (!f || "string" != typeof f || !d || "string" != typeof d)
return void c.Notify.error("请先登录");
let p = await o(r, {
token: f,
uuid: d,
onCalcHashEnd: (e) => {
t = e;
},
}),
g = l(p);
g &&
eD(s) &&
ed(s, {
url: [g],
resourceMeta: (0, L.buildUploadedResourceMeta)(
r,
b.NodeType.IMAGE,
{ hashSha1: t },
),
});
} catch (e) {
console.error("截图上传失败:", e),
c.Notify.error("截图上传失败");
}
})();
},
[et, eD, eg, ed, nR, tC],
);
let [n5, n6] = (0, n.useState)(!1),
n8 = (0, n.useCallback)(() => {
eq &&
!n5 &&
((0, w.reportLog)({
e: "libtv.canvas.video.download",
var: { video_uuid: et },
}),
(async () => {
try {
let e = await (0, d.ensureWatermarkPreference)();
if (null === e) return;
n6(!0);
let t = (0, y.checkIsVip)();
c.Notify.info("正在下载视频…");
let n = eq;
(1 === e && t) ||
(n =
(await (0, y.getVideoWatermarkUrl)({
videoUrl: eq,
watermark: 1 !== e,
communityWatermark: !t,
})) || eq),
(0, k.triggerDownload)(
n,
(0, k.formatDownloadFileName)(tn, "mp4"),
);
} catch (e) {
console.error("下载失败:", e),
c.Notify.error("下载失败,请重试");
} finally {
setTimeout(() => n6(!1), 2e3);
}
})());
}, [eq, tn, n5, et]),
n9 = (0, n.useCallback)(() => {
(0, w.reportLog)({
e: "libtv.canvas.video.edit.click",
var: { function_name: "高清" },
});
let e = eD(et);
if (!e) return;
let t = crypto.randomUUID(),
n = (0, P.findClosestRightFlowPosition)(e, ej(), {
width: g.NODE_WIDTH,
height: g.NODE_HEIGHT_EMPTY,
});
eg(
{
id: t,
type: b.NodeType.VIDEO,
data: {
type: b.NodeType.VIDEO,
name: "高清",
url: [],
poster: "",
action: b.NodeAction.VIDEO_GENERATE,
generatorType: b.GeneratorType.ENHANCE,
},
position: n,
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
},
{ skipOverlapResolution: !0 },
),
em({ source: et, target: t }),
eU(t);
}, [et, eD, ej, eg, em, eU]),
[n7, ie] = (0, n.useState)(!1),
it = (0, n.useCallback)(() => {
n7 ||
((0, w.reportLog)({
e: "libtv.canvas.video.edit.click",
var: { function_name: "解析" },
}),
eD(et) &&
(ie(!0),
c.Notify.info("正在解析视频..."),
(async () => {
try {
let { parseVideoToVideoStory: t } = await e.A(989805),
n = await t({
videoUrl: eq || "",
nodeId: et,
projectId: ex || "",
});
if (0 !== n.code) {
c.Notify.error(n.msg || "解析失败"), ie(!1);
return;
}
let i = n.data?.rows ?? [],
a = n.data?.columns,
o = eD(et);
if (!o) {
console.warn(
"视频解析完成但视频节点已被删除,跳过创建视频故事节点",
),
ie(!1);
return;
}
let s = crypto.randomUUID(),
l = {
id: s,
type: b.NodeType.VIDEO_STORY,
data: {
type: b.NodeType.VIDEO_STORY,
name: "视频故事",
rows: i,
shotColumns: a,
sourceVideoNodeId: et,
action: b.NodeAction.VIDEO_STORY_RESOURCE,
nodeWidth: 800,
nodeHeight: 400,
},
position: {
x: o.position.x + tC + g.NODE_GAP,
y: o.position.y + 60,
},
sourcePosition: r.Position.Right,
targetPosition: r.Position.Left,
};
eg(l),
em({
id: `e-${et.slice(0, 8)}-${s.slice(0, 8)}`,
source: et,
sourceHandle: "source",
target: s,
targetHandle: "target",
}),
eU(s),
c.Notify.success("解析完成,已创建视频故事节点"),
ie(!1);
} catch (e) {
console.error("视频解析失败:", e), ie(!1);
}
})()));
}, [n7, et, eq, e9, ex, eD, eg, em, eU]),
ii = Math.ceil(eK.length / 2),
ir =
2 * g.GRID_PADDING +
ii * g.GRID_ITEM_H +
(ii - 1) * g.GRID_GAP +
g.CONFIRM_AREA_H,
ia = e8 ? (eK.length - 1) * 0 : 0,
io = tA ? ir : tS + ia,
is = (0, n.useMemo)(
() =>
eK.map((e, t) => {
if (!tA) {
let e = t;
return (
null !== tR && (t === tR ? (e = 0) : t < tR && (e = t + 1)),
{
left: 0 * e,
top: 0 * e,
width: t_,
height: tS,
zIndex: eK.length - e,
rotate: el[e] ?? 0,
}
);
}
let n = Math.floor(t / 2);
return {
left: g.GRID_PADDING + (t % 2) * (g.GRID_ITEM_W + g.GRID_GAP),
top: g.GRID_PADDING + n * (g.GRID_ITEM_H + g.GRID_GAP),
width: g.GRID_ITEM_W,
height: g.GRID_ITEM_H,
zIndex: 1,
rotate: 0,
};
}),
[eK.length, tA, t_, tS, tR],
),
ic = (0, n.useCallback)(
(e) => {
e.stopPropagation(), t3.current?.pause(), tF(), tN(!0), tP(null);
},
[tF],
),
il = (0, n.useCallback)(
(e) => {
e.stopPropagation(), tF(), tN(!1), tP(null);
},
[tF],
),
iu = (0, n.useCallback)(
(e, t) => {
tA && (t.stopPropagation(), tP(e));
},
[tA],
),
ih = (0, n.useCallback)(
(e) => {
if ((e.stopPropagation(), null === tI || 0 === tI)) {
tF(), tN(!1), tP(null);
return;
}
let t = [...eK];
tF(),
tL(tI),
tN(!1),
tP(null),
setTimeout(() => {
let [e] = t.splice(tI, 1);
t.unshift(e);
let n = { url: t },
i = S.stores.canvas?.getNode(et),
r = i ? i.resourceMeta : void 0;
if (r?.items && r.items.length > 1) {
let e = [...r.items],
[t] = e.splice(tI, 1);
e.unshift(t), (n.resourceMeta = { items: e });
}
ed(et, n), tL(null);
}, 300);
},
[tI, eK, et, ed, ep, tF],
),
id = "generating_with_content" === tb,
ip = "resource" === tb || id;
if ("resource" === tb && !eq) return null;
let ig = (0, q.getPipelineStyles)(
ez,
eG,
eo,
"var(--canvas-node-border-selected)",
),
ib = {
width: `${tT.width}px`,
height: `${tT.height}px`,
background: "var(--Surface-secondary-background, #262626)",
border: "1px solid var(--canvas-node-border)",
backdropFilter: "blur(1.5px)",
...ig,
transition: ["width 300ms ease", "height 300ms ease", ig.transition]
.filter(Boolean)
.join(", "),
},
im = { width: `${t_}px`, height: `${io}px`, position: "relative" },
iw =
(e$ || eV) && tk
? { ...ib, width: `${t_}px`, height: `${tS}px` }
: ib,
iv = ip
? id
? { ...im, height: `${tS}px` }
: im
: "generating" === tb || "failed" === tb
? iw
: ib,
ix = ip
? "group overflow-visible"
: "group overflow-visible rounded-xl",
iy = ("empty_generate" === tb || "pending" === tb) && tW && !eh,
i_ =
ip && !id && !tA && tW
? (0, t.jsx)(p.default, {
children: (0, t.jsx)(er.VideoNodeToolbar, {
onClipClick: nA ? nN : void 0,
onDownloadClick: n8,
onEnhanceClick: n9,
onParseClick: it,
showParse: !0,
showEnhance: ng <= 600,
isParsing: n7,
isDownloading: n5,
onExpandClick: t8,
}),
})
: iy
? (0, t.jsx)(p.default, {
children: (0, t.jsx)("div", {
className: "flex items-center",
style: er.FLOATING_TOOLBAR_STYLE,
children: (0, t.jsxs)("button", {
type: "button",
onClick: nG,
className:
"text-canvas-controls-text hover:bg-canvas-controls-hover flex h-6 items-center gap-1 rounded-md px-2 text-xs transition-colors",
children: [
(0, t.jsx)(s.Icons.Upload, { width: 14, height: 14 }),
(0, t.jsx)("span", { children: "上传" }),
],
}),
}),
})
: void 0;
return (0, t.jsxs)(K.default, {
ref: eE,
id: et,
selected: eo,
label: tn,
titleIcon: (0, t.jsx)(er.PlayIcon, { size: 14 }),
isStale: eu?.isStale,
onDismissStale: th,
onRetry:
eu?.isStale &&
eh &&
(eu?.action === b.NodeAction.VIDEO_GENERATE ||
eu?.action === b.NodeAction.VIDEO_EDIT) &&
eu?.params
? td
: void 0,
isReadonly: ev,
onLabelChange: tu,
maxWidth: tC,
interaction: eB,
contentStyle: iv,
contentClassName: ix,
hideTargetHandle: (0, b.isResourceAction)(eu?.action),
hideSourceHandle: eY,
shouldShowGenerator: eR,
nodeType: b.NodeType.VIDEO,
generatorType: eu?.generatorType,
incomingData: eL,
beforeContent: i_,
titleDimensionHint: tl,
labelSuffix: tc,
afterContent:
eM && ip && eq && nh > 0
? (0, t.jsx)(ea.VideoClipBar, {
videoRef: t3,
videoUrl: eq,
duration: nh,
width: t_,
onConfirm: nI,
onCancel: nP,
avEditor: nT.current ?? void 0,
isEncoding: n_,
encodeProgress: nE,
})
: void 0,
children: [
("generating" === tb || "failed" === tb) &&
(0, t.jsx)(G.default, {
taskInfo: eu?.taskInfo,
nodeId: et,
onCancel: e$ ? eW : void 0,
onViewDetail: eA,
}),
"empty_generate" === tb &&
(0, t.jsx)(z.default, {
icon: (0, t.jsx)(er.PlayIcon, {
size: 64,
className: "text-fg-disabled",
}),
isReadonly: ev,
actions: [
{
icon: (0, t.jsx)(s.Icons.layers, { width: 14, height: 14 }),
label: "首尾帧生成视频",
onClick: nK,
},
{
icon: (0, t.jsx)(s.Icons.sparkles, {
width: 14,
height: 14,
}),
label: "首帧生成视频",
onClick: nV,
},
],
}),
"pending" === tb &&
(eu?.generatorType === b.GeneratorType.ENHANCE
? (0, t.jsx)("div", {
className: "flex h-full items-center justify-center px-6",
children: (0, t.jsx)("span", {
className: "text-fg-muted text-center text-sm",
children: "配置参数生成高清视频",
}),
})
: (0, t.jsx)("div", {
className: "flex h-full items-center justify-center",
children: (0, t.jsx)(er.PlayIcon, {
size: 64,
className: "text-fg-disabled",
}),
})),
ip &&
(0, t.jsxs)("div", {
className: "absolute inset-0 overflow-hidden rounded-xl",
children: [
tA &&
(0, t.jsx)("div", {
className: "absolute inset-0 rounded-xl",
style: {
background: "var(--Surface-Panel-background, #171717)",
border: "1px solid var(--canvas-node-border)",
...(0, q.getPipelineStyles)(
ez,
eG,
eo,
"var(--canvas-node-border-selected)",
),
},
}),
eK.map((e, n) => {
let r = is[n];
if (!r) return null;
let a = 0 === n,
o = tA && tI === n;
return (0, t.jsx)(
"div",
{
className: "absolute overflow-hidden rounded-xl",
style: {
left: `${r.left}px`,
top: `${r.top}px`,
width: `${r.width}px`,
height: `${r.height}px`,
zIndex: r.zIndex,
transform:
id && a
? `${r.rotate ? `rotate(${r.rotate}deg) ` : ""}scale(1.1)`
: r.rotate
? `rotate(${r.rotate}deg)`
: void 0,
transformOrigin: "50% 50%",
pointerEvents: !tA && n > 0 ? "none" : void 0,
border: "1px solid var(--canvas-node-border)",
outline:
!tA && a && eG
? `2px solid ${eG}`
: (!tA && a && eo) || o
? "2px solid var(--canvas-node-border-selected)"
: "none",
outlineOffset: "-1px",
...("running" === ez && !tA && a && eG
? { boxShadow: `0 0 12px ${eG}40, 0 0 4px ${eG}20` }
: {}),
cursor: tA ? "pointer" : "default",
transition: tD
? "left 300ms ease, top 300ms ease, width 300ms ease, height 300ms ease, transform 300ms ease"
: void 0,
background:
"var(--Surface-Panel-background, #171717)",
filter: id && a ? "blur(24px)" : void 0,
},
onClick: (e) => iu(n, e),
onMouseEnter: a && !tA ? t$ : void 0,
onMouseLeave: a && !tA ? tV : void 0,
children:
a && !tA
? (0, t.jsxs)(t.Fragment, {
children: [
te
? (0, t.jsx)(h.default, {
src: te,
alt: "",
className: "h-full w-full object-cover",
style: {
background:
"var(--Surface-Panel-background, #171717)",
},
draggable: !1,
})
: (0, t.jsx)("div", {
className: "h-full w-full",
style: {
background:
"var(--Surface-Panel-background, #171717)",
},
}),
tX &&
tq &&
(0, t.jsx)("div", {
ref: nn,
className: "absolute inset-0",
style: {
opacity: e2 && !e4 ? 0 : +!!nw,
transition: "opacity 300ms ease-out",
},
}),
tX &&
tq &&
(eY || (e2 && !e4)) &&
(0, t.jsx)("div", {
className:
"absolute inset-0 flex items-center justify-center backdrop-blur-xl",
style: {
background: "rgba(0, 0, 0, 0.3)",
},
children: (0, t.jsx)("span", {
className:
"size-5 animate-spin rounded-full border-2 border-white/30 border-t-white",
}),
}),
!te &&
!(tX && tq) &&
!eY &&
(0, t.jsx)("div", {
className:
"absolute inset-0 flex items-center justify-center",
children: (0, t.jsx)(i.Loader, {
color: "white",
className: "mix-blend-difference",
}),
}),
eZ &&
!eY &&
!e2 &&
(0, t.jsx)(l.ResourceRetryOverlay, {
onRetry: e0,
}),
tE &&
!eY &&
!e2 &&
tK &&
(0, t.jsx)(er.VideoPlayerBar, {
isPlaying: ni,
currentTime: nl,
duration: ng,
volume: na,
muted: ns,
hasAudio: !0 === nx,
onPlayPause: nq,
onSeek: nJ,
onVolumeChange: nX,
onToggleMute: nY,
onScreenshot: ev ? void 0 : n0,
onCaptureFirstFrame: ev ? void 0 : n3,
onCaptureLastFrame: ev ? void 0 : n4,
}),
],
})
: te
? (0, t.jsx)(h.default, {
src: te,
alt: "",
className: "h-full w-full object-cover",
draggable: !1,
})
: (0, t.jsx)("video", {
src: e,
className: "h-full w-full object-cover",
preload: "none",
}),
},
`${e}-${r.left}-${r.top}`,
);
}),
!tA &&
!id &&
(0, t.jsx)("div", {
className: "pointer-events-none absolute left-0 top-0",
style: {
width: `${t_}px`,
height: `${tS}px`,
zIndex: eK.length + 1,
},
children: e8
? (0, t.jsxs)("button", {
type: "button",
onClick: ic,
className:
"pointer-events-auto absolute right-2 top-2 flex items-center gap-1 rounded-lg px-3 py-1.5 text-sm text-white/80 transition-opacity hover:text-white",
style: er.FLOATING_TOOLBAR_STYLE,
children: [
(0, t.jsx)(s.Icons.expand, {
width: 14,
height: 14,
}),
(0, t.jsxs)("span", {
children: [eK.length, "个"],
}),
],
})
: eu?.action !== b.NodeAction.VIDEO_RESOURCE ||
eu?.generatorType === b.GeneratorType.ENHANCE ||
eu?.assetVideoAssetId
? null
: (0, t.jsx)("div", {
className: "pointer-events-auto",
children: (0, t.jsx)(X.default, {
accept: "video/*",
onUploaded: nB,
isReadonly: ev,
nodeId: et,
chromeVariant:
"light" === eS ? "canvasLight" : "default",
}),
}),
}),
tA &&
(0, t.jsxs)("div", {
className:
"absolute flex items-center justify-center gap-2",
style: {
left: `${g.GRID_PADDING}px`,
right: `${g.GRID_PADDING}px`,
bottom: `${g.GRID_PADDING}px`,
height: `${g.CONFIRM_AREA_H - g.GRID_PADDING}px`,
zIndex: 10,
},
children: [
(0, t.jsx)("button", {
type: "button",
onClick: il,
className:
"flex h-8 flex-1 items-center justify-center rounded-lg text-sm text-white/60 transition-colors hover:bg-white/5 hover:text-white/80",
children: "取消",
}),
(0, t.jsx)("button", {
type: "button",
onClick: ih,
disabled: null === tI,
className:
"bg-btn-invert-bg text-btn-invert-text hover:bg-btn-invert-bg-hover flex h-8 flex-1 items-center justify-center rounded-lg text-sm transition-colors disabled:cursor-not-allowed disabled:opacity-40",
children: "设为主视频",
}),
],
}),
id &&
(0, t.jsx)("div", {
className: "absolute inset-0",
style: { zIndex: eK.length + 2 },
children: (0, t.jsx)(G.default, {
taskInfo: eu?.taskInfo,
hasContent: !0,
nodeId: et,
onCancel: eW,
onViewDetail: eA,
}),
}),
],
}),
(0, t.jsx)(W.NodeFullScreenOverlay, {
open: tQ,
onClose: t9,
title: tn,
hideIdleCursor: !0,
children: (0, t.jsx)("div", {
className: "relative min-h-0 flex-1",
children: eq
? (0, t.jsx)(o.FullscreenVideoPlayer, {
src: eq,
poster: te || void 0,
autoPlay: !0,
initialTime: nl,
hasAudio: !0 === nx,
chromeVariant: "light" === eS ? "canvasLight" : "default",
onTimeUpdate: (e) => {
t2.current = e;
},
className: "absolute inset-0",
})
: (0, t.jsx)("div", {
className:
"text-fg-muted flex h-full items-center justify-center",
children: "暂无视频",
}),
}),
}),
(0, t.jsx)(Y.default, {
nodeId: et,
hasContent: ip && eK.length > 0,
}),
ek && (0, t.jsx)(H.default, { onClose: eN }),
],
});
});
(eu.displayName = "VideoNode"), e.s(["default", 0, eu], 649517);
};
export default moduleFactory;