dsh-vidi 0.5.0 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +64 -15
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -33525,11 +33525,31 @@ const Player = (0, react.forwardRef)(function Player(props, ref) {
|
|
|
33525
33525
|
const idleTimer = (0, react.useRef)();
|
|
33526
33526
|
/** Where playback was, so a new source (quality switch) continues from there. */
|
|
33527
33527
|
const lastTime = (0, react.useRef)(0);
|
|
33528
|
+
const [held, setHeld] = (0, react.useState)(null);
|
|
33529
|
+
const heldRef = (0, react.useRef)(false);
|
|
33528
33530
|
(0, react.useImperativeHandle)(ref, () => ({
|
|
33529
33531
|
seek: (time) => {
|
|
33530
33532
|
if (video.current) video.current.currentTime = Math.max(0, time);
|
|
33531
33533
|
},
|
|
33532
|
-
closeMenu: () => setMenu(null)
|
|
33534
|
+
closeMenu: () => setMenu(null),
|
|
33535
|
+
hold: (text, onSkip) => {
|
|
33536
|
+
const el = video.current;
|
|
33537
|
+
if (!el) return;
|
|
33538
|
+
if (text) {
|
|
33539
|
+
if (!heldRef.current) {
|
|
33540
|
+
heldRef.current = true;
|
|
33541
|
+
el.pause();
|
|
33542
|
+
}
|
|
33543
|
+
setHeld((h) => h?.text === text ? h : {
|
|
33544
|
+
text,
|
|
33545
|
+
skip: onSkip
|
|
33546
|
+
});
|
|
33547
|
+
} else if (heldRef.current) {
|
|
33548
|
+
heldRef.current = false;
|
|
33549
|
+
setHeld(null);
|
|
33550
|
+
el.play().catch(() => {});
|
|
33551
|
+
}
|
|
33552
|
+
}
|
|
33533
33553
|
}), []);
|
|
33534
33554
|
(0, react.useEffect)(() => {
|
|
33535
33555
|
const el = video.current;
|
|
@@ -33895,6 +33915,18 @@ const Player = (0, react.forwardRef)(function Player(props, ref) {
|
|
|
33895
33915
|
className: "dshl-overlay",
|
|
33896
33916
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", { className: "dshl-spinner" }), waitingText]
|
|
33897
33917
|
}),
|
|
33918
|
+
ready && held && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
33919
|
+
className: "dshl-holdnote",
|
|
33920
|
+
children: [
|
|
33921
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("i", { className: "dshl-spinner sm" }),
|
|
33922
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: held.text }),
|
|
33923
|
+
held.skip && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
33924
|
+
className: "dshl-link",
|
|
33925
|
+
onClick: () => held.skip?.(),
|
|
33926
|
+
children: t("hold.skip")
|
|
33927
|
+
})
|
|
33928
|
+
]
|
|
33929
|
+
}),
|
|
33898
33930
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SubtitleOverlay, {
|
|
33899
33931
|
texts,
|
|
33900
33932
|
style,
|
|
@@ -35055,6 +35087,27 @@ function LiveView(props) {
|
|
|
35055
35087
|
state: "off",
|
|
35056
35088
|
at: 0
|
|
35057
35089
|
};
|
|
35090
|
+
const [noWait, setNoWait] = (0, react.useState)(false);
|
|
35091
|
+
(0, react.useEffect)(() => {
|
|
35092
|
+
setNoWait(false);
|
|
35093
|
+
}, [mode, job?.id]);
|
|
35094
|
+
const lastPolished = (0, react.useMemo)(() => cues.reduce((m, c) => c.polished && c.end > m ? c.end : m, 0), [cues]);
|
|
35095
|
+
(0, react.useEffect)(() => {
|
|
35096
|
+
const p = player.current;
|
|
35097
|
+
if (!p) return;
|
|
35098
|
+
const waiting = !!job && job.status === "running" && !job.vod && mode !== "site" && subs.state === "running" && !noWait;
|
|
35099
|
+
const ready = mode === "polished" ? Math.max(lastPolished, subs.at - 150) : subs.at;
|
|
35100
|
+
if (waiting && now > ready + .5) p.hold(t(mode === "polished" ? "hold.polished" : "hold.realtime"), () => setNoWait(true));
|
|
35101
|
+
else if (!waiting || ready > now + (mode === "polished" ? 20 : 4)) p.hold(null);
|
|
35102
|
+
}, [
|
|
35103
|
+
now,
|
|
35104
|
+
subs.at,
|
|
35105
|
+
subs.state,
|
|
35106
|
+
lastPolished,
|
|
35107
|
+
mode,
|
|
35108
|
+
noWait,
|
|
35109
|
+
job?.status
|
|
35110
|
+
]);
|
|
35058
35111
|
(0, react.useEffect)(() => {
|
|
35059
35112
|
if (!job?.title || !props.onTitle) return;
|
|
35060
35113
|
const key = `dsh-live.named.${sessionId}`;
|
|
@@ -35548,9 +35601,7 @@ function LiveView(props) {
|
|
|
35548
35601
|
onTerms: setTerms
|
|
35549
35602
|
})
|
|
35550
35603
|
] });
|
|
35551
|
-
const
|
|
35552
|
-
const slow = live && mode !== "site" && rate !== null && rate < .95;
|
|
35553
|
-
const behindBy = live && mode !== "site" && subs.state === "running" && cues.length > 0 ? now - subs.at : 0;
|
|
35604
|
+
const slow = !!job && job.status === "running" && !job.vod && mode !== "site" && rate !== null && rate < .95;
|
|
35554
35605
|
const engineNow = providers.find((x) => x.id === usableEngine());
|
|
35555
35606
|
const liveNote = siteOnly && job && job.status !== "resolving" && !job.site?.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
35556
35607
|
className: "dshl-lag",
|
|
@@ -35566,13 +35617,6 @@ function LiveView(props) {
|
|
|
35566
35617
|
onClick: () => setSettingsOpen(true),
|
|
35567
35618
|
children: t("lag.settings")
|
|
35568
35619
|
})]
|
|
35569
|
-
}) : behindBy > 6 ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
35570
|
-
className: "dshl-lag",
|
|
35571
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t("lag.behind").replace("{t}", CLOCK(behindBy)) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
35572
|
-
className: "dshl-link",
|
|
35573
|
-
onClick: () => player.current?.seek(Math.max(0, subs.at - 2)),
|
|
35574
|
-
children: t("lag.wait")
|
|
35575
|
-
})]
|
|
35576
35620
|
}) : null;
|
|
35577
35621
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
35578
35622
|
className: `dshl ${theater && !activeBench ? "theater" : ""} ${pageMode ? "page" : ""} ${activeBench ? "bench" : ""}`,
|
|
@@ -36512,8 +36556,9 @@ const en = {
|
|
|
36512
36556
|
"mode.polished.tip": "1–2 minutes behind: misheard words fixed with context and the picture — the most accurate (default)",
|
|
36513
36557
|
"site.none": "This video has no subtitles of its own.",
|
|
36514
36558
|
"site.switch": "Switch to Polished",
|
|
36515
|
-
"
|
|
36516
|
-
"
|
|
36559
|
+
"hold.realtime": "Waiting for subtitles…",
|
|
36560
|
+
"hold.polished": "Waiting for polished subtitles…",
|
|
36561
|
+
"hold.skip": "Don’t wait",
|
|
36517
36562
|
"lag.slow": "Transcription runs slower than the stream ({x}×), so subtitles fall further behind.",
|
|
36518
36563
|
"lag.slowLocal": "This computer transcribes slower than the stream ({x}×), so subtitles fall further behind. An online service keeps up.",
|
|
36519
36564
|
"lag.settings": "Choose one",
|
|
@@ -36847,8 +36892,9 @@ const zh = {
|
|
|
36847
36892
|
"mode.polished.tip": "晚 1–2 分钟:结合上下文和画面改正听错的词,字幕最准(默认)",
|
|
36848
36893
|
"site.none": "这个视频没有网站自带的字幕。",
|
|
36849
36894
|
"site.switch": "换成精修",
|
|
36850
|
-
"
|
|
36851
|
-
"
|
|
36895
|
+
"hold.realtime": "等字幕…",
|
|
36896
|
+
"hold.polished": "等精修字幕…",
|
|
36897
|
+
"hold.skip": "不等了",
|
|
36852
36898
|
"lag.slow": "转写比直播慢({x} 倍速),字幕会越落越远。",
|
|
36853
36899
|
"lag.slowLocal": "本机转写比直播慢({x} 倍速),字幕会越落越远。换成在线转写就能跟上。",
|
|
36854
36900
|
"lag.settings": "去选一个",
|
|
@@ -37326,6 +37372,9 @@ html[data-platform='darwin'] .dshl.page .dshl-top :is(button, input, label, a, .
|
|
|
37326
37372
|
.dshl-stage.pagefull { position: fixed; inset: 0; z-index: 2147483000; width: 100vw; height: 100vh; aspect-ratio: auto; border-radius: 0; }
|
|
37327
37373
|
.dshl-stage video { display: block; width: 100%; height: 100%; object-fit: contain; background: #000; }
|
|
37328
37374
|
.dshl-stage.idle { cursor: none; }
|
|
37375
|
+
.dshl-holdnote { position: absolute; top: 14px; left: 50%; z-index: 4; display: flex; align-items: center; gap: 8px; padding: 6px 12px; border-radius: 999px; transform: translateX(-50%);
|
|
37376
|
+
background: rgba(20,20,22,.78); color: #f2f2f3; font-size: 12.5px; white-space: nowrap; backdrop-filter: blur(8px); }
|
|
37377
|
+
.dshl-holdnote .dshl-link { color: #9ec0ff; }
|
|
37329
37378
|
.dshl-overlay { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 14px; color: #cfcfcf; font-size: 14px; }
|
|
37330
37379
|
.dshl-spinner { width: 28px; height: 28px; border: 2.5px solid rgba(255,255,255,.18); border-top-color: #fff; border-radius: 50%; animation: dshl-spin .9s linear infinite; }
|
|
37331
37380
|
.dshl-spinner.sm { width: 14px; height: 14px; border-width: 2px; flex: none; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vidi",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "A video tool for DeepSeek Harness: watch live streams, videos and podcasts with real-time subtitles in any language, then clip and download",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "PolyForm-Noncommercial-1.0.0",
|