dsh-vidi 0.7.7 → 0.7.8
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 +135 -134
- package/package.json +1 -1
package/lib/client.js
CHANGED
|
@@ -35389,10 +35389,9 @@ function LiveView(props) {
|
|
|
35389
35389
|
const linesBox = (0, react.useRef)(null);
|
|
35390
35390
|
const fileInput = (0, react.useRef)(null);
|
|
35391
35391
|
const active = !!job && (job.status === "resolving" || job.status === "running" || job.status === "stopping");
|
|
35392
|
-
const [srcTab, setSrcTabRaw] = (0, react.useState)(
|
|
35392
|
+
const [srcTab, setSrcTabRaw] = (0, react.useState)("link");
|
|
35393
35393
|
const setSrcTab = (v) => {
|
|
35394
35394
|
setSrcTabRaw(v);
|
|
35395
|
-
store.set("source", v);
|
|
35396
35395
|
setError("");
|
|
35397
35396
|
};
|
|
35398
35397
|
const devices = useDevices(srcTab === "camera");
|
|
@@ -35896,20 +35895,15 @@ function LiveView(props) {
|
|
|
35896
35895
|
title
|
|
35897
35896
|
}), "device");
|
|
35898
35897
|
};
|
|
35899
|
-
const emptyBox = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
35898
|
+
const emptyBox = () => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
35900
35899
|
className: "dshl-drop",
|
|
35901
35900
|
children: [
|
|
35902
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t(
|
|
35903
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
35904
|
-
|
|
35905
|
-
|
|
35906
|
-
onClick: () => fileInput.current?.click(),
|
|
35907
|
-
children: [
|
|
35908
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon.folder, {}),
|
|
35909
|
-
" ",
|
|
35910
|
-
t("src.file.pick")
|
|
35911
|
-
]
|
|
35901
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h2", { children: t("empty.title") }),
|
|
35902
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
35903
|
+
className: "dshl-bar center",
|
|
35904
|
+
children: sourceBar
|
|
35912
35905
|
}),
|
|
35906
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", { children: srcTab === "camera" && devices && !mics.length ? t("src.cam.none") : t(srcTab === "file" ? "src.file.body" : srcTab === "camera" ? "src.cam.body" : srcTab === "push" ? "src.push.body" : "empty.body") }),
|
|
35913
35907
|
srcTab === "push" && armed?.rtmp && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
35914
35908
|
className: "dshl-pushinfo",
|
|
35915
35909
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("dl", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(CopyRow, {
|
|
@@ -36127,6 +36121,118 @@ function LiveView(props) {
|
|
|
36127
36121
|
children: t("lag.settings")
|
|
36128
36122
|
})]
|
|
36129
36123
|
}) : null;
|
|
36124
|
+
const sourceBar = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
36125
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pick, {
|
|
36126
|
+
className: "srcpick",
|
|
36127
|
+
value: srcTab,
|
|
36128
|
+
onChange: (v) => setSrcTab(v),
|
|
36129
|
+
title: t("src.tip"),
|
|
36130
|
+
options: [
|
|
36131
|
+
"link",
|
|
36132
|
+
"file",
|
|
36133
|
+
"camera",
|
|
36134
|
+
"push"
|
|
36135
|
+
].map((k) => ({
|
|
36136
|
+
value: k,
|
|
36137
|
+
label: t(`src.${k}`)
|
|
36138
|
+
}))
|
|
36139
|
+
}),
|
|
36140
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36141
|
+
ref: fileInput,
|
|
36142
|
+
type: "file",
|
|
36143
|
+
accept: "video/*,audio/*,.mkv,.ts,.flv",
|
|
36144
|
+
hidden: true,
|
|
36145
|
+
onChange: (e) => {
|
|
36146
|
+
const f = e.target.files?.[0];
|
|
36147
|
+
if (f) onFile(f);
|
|
36148
|
+
e.target.value = "";
|
|
36149
|
+
}
|
|
36150
|
+
}),
|
|
36151
|
+
(srcTab === "link" || srcTab === "file") && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
36152
|
+
className: "dshl-field",
|
|
36153
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36154
|
+
type: "text",
|
|
36155
|
+
value: input,
|
|
36156
|
+
placeholder: t(srcTab === "file" ? "src.file.placeholder" : "in.placeholder"),
|
|
36157
|
+
onChange: (e) => setInput(e.target.value),
|
|
36158
|
+
onKeyDown: (e) => {
|
|
36159
|
+
if (e.key === "Enter") start();
|
|
36160
|
+
}
|
|
36161
|
+
}), srcTab === "file" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36162
|
+
className: "ghost",
|
|
36163
|
+
title: t("in.file.tip"),
|
|
36164
|
+
onClick: () => fileInput.current?.click(),
|
|
36165
|
+
children: uploading !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36166
|
+
className: "pct",
|
|
36167
|
+
children: t("in.uploading").replace("{p}", String(uploading))
|
|
36168
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon.folder, {})
|
|
36169
|
+
})]
|
|
36170
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36171
|
+
className: "dshl-btn primary",
|
|
36172
|
+
onClick: () => start(),
|
|
36173
|
+
disabled: !classify(input),
|
|
36174
|
+
children: t("in.open")
|
|
36175
|
+
})] }),
|
|
36176
|
+
srcTab === "camera" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36177
|
+
className: "dshl-devbar",
|
|
36178
|
+
children: devices === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36179
|
+
className: "dshl-muted",
|
|
36180
|
+
children: t("src.cam.loading")
|
|
36181
|
+
}) : mics.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pick, {
|
|
36182
|
+
value: camV,
|
|
36183
|
+
options: videoOptions,
|
|
36184
|
+
onChange: setCamVideo,
|
|
36185
|
+
title: t("dev.video")
|
|
36186
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pick, {
|
|
36187
|
+
value: camA,
|
|
36188
|
+
options: mics.map((d) => ({
|
|
36189
|
+
value: d.id,
|
|
36190
|
+
label: d.name
|
|
36191
|
+
})),
|
|
36192
|
+
onChange: setCamAudio,
|
|
36193
|
+
title: t("dev.audio")
|
|
36194
|
+
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36195
|
+
className: "dshl-muted",
|
|
36196
|
+
children: t("src.cam.none")
|
|
36197
|
+
})
|
|
36198
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36199
|
+
className: "dshl-btn primary",
|
|
36200
|
+
onClick: () => void startDevice(),
|
|
36201
|
+
disabled: !camA,
|
|
36202
|
+
children: t("dev.start")
|
|
36203
|
+
})] }),
|
|
36204
|
+
srcTab === "push" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36205
|
+
className: "dshl-field static",
|
|
36206
|
+
title: t("src.push.body"),
|
|
36207
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(armed?.rtmp ? "src.push.bar" : active ? "src.push.busy" : "src.push.wait") })
|
|
36208
|
+
}),
|
|
36209
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Settings, {
|
|
36210
|
+
engine: engine || "local",
|
|
36211
|
+
onEngine: setEngine,
|
|
36212
|
+
mode,
|
|
36213
|
+
onMode: changeMode,
|
|
36214
|
+
spoken,
|
|
36215
|
+
onSpoken: setSpoken,
|
|
36216
|
+
langOptions,
|
|
36217
|
+
login,
|
|
36218
|
+
onLogin: chooseLogin,
|
|
36219
|
+
browsers,
|
|
36220
|
+
providers,
|
|
36221
|
+
shared: keysShared,
|
|
36222
|
+
name: engineName,
|
|
36223
|
+
onKey: (id, k) => {
|
|
36224
|
+
setProviders((ps) => ps.map((p) => p.id === id ? {
|
|
36225
|
+
...p,
|
|
36226
|
+
key: k,
|
|
36227
|
+
ready: k.set
|
|
36228
|
+
} : p));
|
|
36229
|
+
if (k.set) setError("");
|
|
36230
|
+
},
|
|
36231
|
+
open: settingsOpen,
|
|
36232
|
+
onOpen: setSettingsOpen,
|
|
36233
|
+
t
|
|
36234
|
+
})
|
|
36235
|
+
] });
|
|
36130
36236
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36131
36237
|
className: `dshl ${theater && !activeBench ? "theater" : ""} ${pageMode ? "page" : ""} ${activeBench ? "bench" : ""} ${pageMode && !sideOpen && !activeBench ? "noside" : ""}`,
|
|
36132
36238
|
style: pageMode ? { ["--side-w"]: `${sideW}px` } : void 0,
|
|
@@ -36154,7 +36260,7 @@ function LiveView(props) {
|
|
|
36154
36260
|
if (f && !active) onFile(f);
|
|
36155
36261
|
},
|
|
36156
36262
|
children: [
|
|
36157
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
|
|
36263
|
+
(hasMain || onClose) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("header", {
|
|
36158
36264
|
className: "dshl-top",
|
|
36159
36265
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
36160
36266
|
className: "dshl-bar",
|
|
@@ -36165,117 +36271,8 @@ function LiveView(props) {
|
|
|
36165
36271
|
title: t("page.back"),
|
|
36166
36272
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon.arrow, {})
|
|
36167
36273
|
}),
|
|
36168
|
-
|
|
36169
|
-
|
|
36170
|
-
value: srcTab,
|
|
36171
|
-
onChange: (v) => setSrcTab(v),
|
|
36172
|
-
title: t("src.tip"),
|
|
36173
|
-
options: [
|
|
36174
|
-
"link",
|
|
36175
|
-
"file",
|
|
36176
|
-
"camera",
|
|
36177
|
-
"push"
|
|
36178
|
-
].map((k) => ({
|
|
36179
|
-
value: k,
|
|
36180
|
-
label: t(`src.${k}`)
|
|
36181
|
-
}))
|
|
36182
|
-
}),
|
|
36183
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36184
|
-
ref: fileInput,
|
|
36185
|
-
type: "file",
|
|
36186
|
-
accept: "video/*,audio/*,.mkv,.ts,.flv",
|
|
36187
|
-
hidden: true,
|
|
36188
|
-
onChange: (e) => {
|
|
36189
|
-
const f = e.target.files?.[0];
|
|
36190
|
-
if (f) onFile(f);
|
|
36191
|
-
e.target.value = "";
|
|
36192
|
-
}
|
|
36193
|
-
}),
|
|
36194
|
-
(srcTab === "link" || srcTab === "file") && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
36195
|
-
className: "dshl-field",
|
|
36196
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
36197
|
-
type: "text",
|
|
36198
|
-
value: input,
|
|
36199
|
-
placeholder: t(srcTab === "file" ? "src.file.placeholder" : "in.placeholder"),
|
|
36200
|
-
onChange: (e) => setInput(e.target.value),
|
|
36201
|
-
onKeyDown: (e) => {
|
|
36202
|
-
if (e.key === "Enter") start();
|
|
36203
|
-
}
|
|
36204
|
-
}), srcTab === "file" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36205
|
-
className: "ghost",
|
|
36206
|
-
title: t("in.file.tip"),
|
|
36207
|
-
onClick: () => fileInput.current?.click(),
|
|
36208
|
-
children: uploading !== null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36209
|
-
className: "pct",
|
|
36210
|
-
children: t("in.uploading").replace("{p}", String(uploading))
|
|
36211
|
-
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon.folder, {})
|
|
36212
|
-
})]
|
|
36213
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36214
|
-
className: "dshl-btn primary",
|
|
36215
|
-
onClick: () => start(),
|
|
36216
|
-
disabled: !classify(input),
|
|
36217
|
-
children: t("in.open")
|
|
36218
|
-
})] }),
|
|
36219
|
-
srcTab === "camera" && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36220
|
-
className: "dshl-devbar",
|
|
36221
|
-
children: devices === null ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36222
|
-
className: "dshl-muted",
|
|
36223
|
-
children: t("src.cam.loading")
|
|
36224
|
-
}) : mics.length ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pick, {
|
|
36225
|
-
value: camV,
|
|
36226
|
-
options: videoOptions,
|
|
36227
|
-
onChange: setCamVideo,
|
|
36228
|
-
title: t("dev.video")
|
|
36229
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Pick, {
|
|
36230
|
-
value: camA,
|
|
36231
|
-
options: mics.map((d) => ({
|
|
36232
|
-
value: d.id,
|
|
36233
|
-
label: d.name
|
|
36234
|
-
})),
|
|
36235
|
-
onChange: setCamAudio,
|
|
36236
|
-
title: t("dev.audio")
|
|
36237
|
-
})] }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
36238
|
-
className: "dshl-muted",
|
|
36239
|
-
children: t("src.cam.none")
|
|
36240
|
-
})
|
|
36241
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36242
|
-
className: "dshl-btn primary",
|
|
36243
|
-
onClick: () => void startDevice(),
|
|
36244
|
-
disabled: !camA,
|
|
36245
|
-
children: t("dev.start")
|
|
36246
|
-
})] }),
|
|
36247
|
-
srcTab === "push" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36248
|
-
className: "dshl-field static",
|
|
36249
|
-
title: t("src.push.body"),
|
|
36250
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: t(armed?.rtmp ? "src.push.bar" : active ? "src.push.busy" : "src.push.wait") })
|
|
36251
|
-
}),
|
|
36252
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Settings, {
|
|
36253
|
-
engine: engine || "local",
|
|
36254
|
-
onEngine: setEngine,
|
|
36255
|
-
mode,
|
|
36256
|
-
onMode: changeMode,
|
|
36257
|
-
spoken,
|
|
36258
|
-
onSpoken: setSpoken,
|
|
36259
|
-
langOptions,
|
|
36260
|
-
login,
|
|
36261
|
-
onLogin: chooseLogin,
|
|
36262
|
-
browsers,
|
|
36263
|
-
providers,
|
|
36264
|
-
shared: keysShared,
|
|
36265
|
-
name: engineName,
|
|
36266
|
-
onKey: (id, k) => {
|
|
36267
|
-
setProviders((ps) => ps.map((p) => p.id === id ? {
|
|
36268
|
-
...p,
|
|
36269
|
-
key: k,
|
|
36270
|
-
ready: k.set
|
|
36271
|
-
} : p));
|
|
36272
|
-
if (k.set) setError("");
|
|
36273
|
-
},
|
|
36274
|
-
open: settingsOpen,
|
|
36275
|
-
onOpen: setSettingsOpen,
|
|
36276
|
-
t
|
|
36277
|
-
}),
|
|
36278
|
-
pageMode && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36274
|
+
hasMain && sourceBar,
|
|
36275
|
+
pageMode && hasMain && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
36279
36276
|
className: `dshl-ctl icon ${sideOpen ? "on" : ""}`,
|
|
36280
36277
|
title: t(sideOpen ? "side.hide" : "side.show"),
|
|
36281
36278
|
"aria-pressed": sideOpen,
|
|
@@ -36305,15 +36302,15 @@ function LiveView(props) {
|
|
|
36305
36302
|
children: t("st.retry")
|
|
36306
36303
|
})]
|
|
36307
36304
|
}),
|
|
36308
|
-
!hasMain
|
|
36305
|
+
!hasMain ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("section", {
|
|
36309
36306
|
className: "dshl-empty",
|
|
36310
|
-
children: emptyBox
|
|
36307
|
+
children: emptyBox()
|
|
36311
36308
|
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
36312
36309
|
className: "dshl-main",
|
|
36313
36310
|
ref: mainRef,
|
|
36314
36311
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
36315
36312
|
className: "dshl-col",
|
|
36316
|
-
children: !hasMain || !job ? emptyBox : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
36313
|
+
children: !hasMain || !job ? emptyBox() : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
36317
36314
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Player, {
|
|
36318
36315
|
ref: player,
|
|
36319
36316
|
src: job.status === "resolving" || job.status === "error" ? null : `/live/media/${encodeURIComponent(job.id)}/${job.hls ?? "hls"}/index.m3u8`,
|
|
@@ -37168,7 +37165,7 @@ const en = {
|
|
|
37168
37165
|
"in.uploading": "Uploading {p}%",
|
|
37169
37166
|
"in.drop": "Drop to start",
|
|
37170
37167
|
"empty.title": "Subtitles for any video",
|
|
37171
|
-
"empty.body": "
|
|
37168
|
+
"empty.body": "YouTube, Bilibili and other sites, videos and live streams.",
|
|
37172
37169
|
"st.resolving": "Opening…",
|
|
37173
37170
|
"st.login": "Using your {b} login… if macOS asks, choose “Always Allow”.",
|
|
37174
37171
|
"st.live": "Live",
|
|
@@ -37188,10 +37185,10 @@ const en = {
|
|
|
37188
37185
|
"src.push": "OBS stream",
|
|
37189
37186
|
"src.file.placeholder": "Path of a video or audio file",
|
|
37190
37187
|
"src.file.title": "Open a video on this computer",
|
|
37191
|
-
"src.file.body": "
|
|
37188
|
+
"src.file.body": "Choose a file with the folder button, or drop it anywhere on this page.",
|
|
37192
37189
|
"src.file.pick": "Choose a file",
|
|
37193
37190
|
"src.cam.title": "Talk to the camera",
|
|
37194
|
-
"src.cam.body": "Pick the picture and the microphone
|
|
37191
|
+
"src.cam.body": "Pick the picture and the microphone, press Start: subtitles appear as you speak.",
|
|
37195
37192
|
"src.cam.none": "No camera or microphone found on this computer.",
|
|
37196
37193
|
"src.cam.loading": "Looking for cameras…",
|
|
37197
37194
|
"src.push.title": "Stream from OBS",
|
|
@@ -37586,7 +37583,7 @@ const zh = {
|
|
|
37586
37583
|
"in.uploading": "上传中 {p}%",
|
|
37587
37584
|
"in.drop": "松手开始",
|
|
37588
37585
|
"empty.title": "给任何视频配字幕",
|
|
37589
|
-
"empty.body": "
|
|
37586
|
+
"empty.body": "支持 YouTube、B 站等网站的视频和直播",
|
|
37590
37587
|
"st.resolving": "正在打开…",
|
|
37591
37588
|
"st.login": "正在用 {b} 的登录状态…如果系统弹窗询问,点「始终允许」",
|
|
37592
37589
|
"st.live": "直播中",
|
|
@@ -37606,10 +37603,10 @@ const zh = {
|
|
|
37606
37603
|
"src.push": "OBS 推流",
|
|
37607
37604
|
"src.file.placeholder": "视频或音频文件的路径",
|
|
37608
37605
|
"src.file.title": "打开这台电脑上的视频",
|
|
37609
|
-
"src.file.body": "
|
|
37606
|
+
"src.file.body": "点文件夹按钮选择,或者直接把文件拖进来。",
|
|
37610
37607
|
"src.file.pick": "选择文件",
|
|
37611
37608
|
"src.cam.title": "对着摄像头说话",
|
|
37612
|
-
"src.cam.body": "
|
|
37609
|
+
"src.cam.body": "选好画面和麦克风,点开始,字幕边说边出。",
|
|
37613
37610
|
"src.cam.none": "这台电脑上没有找到摄像头或麦克风。",
|
|
37614
37611
|
"src.cam.loading": "正在找摄像头…",
|
|
37615
37612
|
"src.push.title": "用 OBS 推流过来",
|
|
@@ -38010,6 +38007,10 @@ const CSS = `
|
|
|
38010
38007
|
|
|
38011
38008
|
/* ── Empty state ── */
|
|
38012
38009
|
.dshl-empty { padding: 28px 20px; }
|
|
38010
|
+
.dshl.page .dshl-empty { flex: 1; display: flex; align-items: center; justify-content: center; min-height: 0; overflow: auto; }
|
|
38011
|
+
.dshl.page .dshl-empty > .dshl-drop { border: 0; padding-top: 0; }
|
|
38012
|
+
.dshl-drop > .dshl-bar.center { display: flex; align-items: center; gap: 8px; width: 100%; max-width: 680px; margin: 22px 0 12px; text-align: left; }
|
|
38013
|
+
.dshl-drop > .dshl-bar.center + p { font-size: 13px; color: var(--faint); }
|
|
38013
38014
|
.dshl-drop { display: flex; flex-direction: column; align-items: center; justify-content: center; width: 100%; max-width: 760px; margin: 0 auto; padding: 56px 24px 48px;
|
|
38014
38015
|
border: 1.5px dashed var(--line); border-radius: 16px; text-align: center; }
|
|
38015
38016
|
.dshl-col > .dshl-drop { max-width: none; min-height: 320px; aspect-ratio: 16 / 9; padding: 32px 24px; border-radius: 12px; }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-vidi",
|
|
3
|
-
"version": "0.7.
|
|
3
|
+
"version": "0.7.8",
|
|
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",
|