2126 lines
78 KiB
JavaScript
2126 lines
78 KiB
JavaScript
/*
|
||
* 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;
|