Chore update constants (#576)
* support multiple base url * use hf-mirror.com for model download host
This commit is contained in:
@@ -109,7 +109,7 @@ Enjoy 采用 **本地优先** 的设计原则,大部分数据均保存在本
|
||||
Enjoy 软件集成了最小的 whisper 模型 `tiny.en`,如果电脑配置较高,可以选用更大的模型以提高语音转文本的准确度。点击 `模型` 按钮,在弹窗中选择相应的模型即可自动下载并选中。
|
||||
|
||||
::: tip 关于 whisper 模型的选择
|
||||
下载的 whisper 模型会保存在 `/EnjoyLibrary/whisper/models/` 文件夹下。如果自动下载失败,也可以到 [这里](https://huggingface.co/ggerganov/whisper.cpp) 手动下载,放置在该文件夹下,在 Enjoy 中即可以选中。
|
||||
下载的 whisper 模型会保存在 `/EnjoyLibrary/whisper/models/` 文件夹下。如果自动下载失败,也可以到 [这里](https://hf-mirror.com/ggerganov/whisper.cpp) 手动下载,放置在该文件夹下,在 Enjoy 中即可以选中。
|
||||
|
||||
理论上,模型越大,识别的准确度也更高,但是运行得越慢,甚至在一些配置不高的电脑中无法运行。
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ if (proxyUrl) {
|
||||
}
|
||||
|
||||
// const modelUrlPrefix =
|
||||
// "https://huggingface.co/ggerganov/whisper.cpp/resolve/main";
|
||||
// "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main";
|
||||
const modelUrlPrefix = "https://enjoy-storage.baizhiheizi.com";
|
||||
|
||||
function hashFile(path, options) {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
export const DATABASE_NAME = "enjoy_database";
|
||||
export const LIBRARY_PATH_SUFFIX = "EnjoyLibrary";
|
||||
|
||||
export const STORAGE_WORKER_ENDPOINT = "https://enjoy-storage.baizhiheizi.com";
|
||||
export const AI_WORKER_ENDPOINT = "https://enjoy-ai.baizhiheizi.com";
|
||||
export const WEB_API_URL = "https://enjoy-web.fly.dev";
|
||||
export const STORAGE_WORKER_ENDPOINT = "https://storage.enjoy.bot";
|
||||
export const STORAGE_WORKER_ENDPOINTS = [
|
||||
"https://storage.enjoy.bot",
|
||||
"https://enjoy-storage.baizhiheizi.com",
|
||||
];
|
||||
|
||||
export const AI_WORKER_ENDPOINT = "https://ai-worker.enjoy.bot";
|
||||
|
||||
export const WEB_API_URL = "https://enjoy.bot";
|
||||
export const WEB_API_URLS = ["https://enjoy.bot", "https://enjoy-web.fly.dev"];
|
||||
|
||||
export const REPO_URL = "https://github.com/xiaolai/everyone-can-use-english";
|
||||
|
||||
@@ -28,84 +35,84 @@ export const FFMPEG_CONVERT_WAV_OPTIONS = [
|
||||
"pcm_s16le",
|
||||
];
|
||||
|
||||
// https://huggingface.co/ggerganov/whisper.cpp/tree/main
|
||||
// https://hf-mirror.com/ggerganov/whisper.cpp/tree/main
|
||||
export const WHISPER_MODELS_OPTIONS = [
|
||||
{
|
||||
type: "tiny",
|
||||
name: "ggml-tiny.bin",
|
||||
size: "75 MB",
|
||||
sha: "bd577a113a864445d4c299885e0cb97d4ba92b5f",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-tiny.bin",
|
||||
},
|
||||
{
|
||||
type: "tiny.en",
|
||||
name: "ggml-tiny.en.bin",
|
||||
size: "75 MB",
|
||||
sha: "c78c86eb1a8faa21b369bcd33207cc90d64ae9df",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-tiny.en.bin",
|
||||
},
|
||||
{
|
||||
type: "base",
|
||||
name: "ggml-base.bin",
|
||||
size: "142 MB",
|
||||
sha: "465707469ff3a37a2b9b8d8f89f2f99de7299dac",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-base.bin",
|
||||
},
|
||||
{
|
||||
type: "base.en",
|
||||
name: "ggml-base.en.bin",
|
||||
size: "142 MB",
|
||||
sha: "137c40403d78fd54d454da0f9bd998f78703390c",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin",
|
||||
},
|
||||
{
|
||||
type: "small",
|
||||
name: "ggml-small.bin",
|
||||
size: "466 MB",
|
||||
sha: "55356645c2b361a969dfd0ef2c5a50d530afd8d5",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-small.bin",
|
||||
},
|
||||
{
|
||||
type: "small.en",
|
||||
name: "ggml-small.en.bin",
|
||||
size: "466 MB",
|
||||
sha: "db8a495a91d927739e50b3fc1cc4c6b8f6c2d022",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-small.en.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-small.en.bin",
|
||||
},
|
||||
{
|
||||
type: "medium",
|
||||
name: "ggml-medium.bin",
|
||||
size: "1.5 GB",
|
||||
sha: "fd9727b6e1217c2f614f9b698455c4ffd82463b4",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-medium.bin",
|
||||
},
|
||||
{
|
||||
type: "medium.en",
|
||||
name: "ggml-medium.en.bin",
|
||||
size: "1.5 GB",
|
||||
sha: "8c30f0e44ce9560643ebd10bbe50cd20eafd3723",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-medium.en.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-medium.en.bin",
|
||||
},
|
||||
{
|
||||
type: "large-v1",
|
||||
name: "ggml-large-v1.bin",
|
||||
size: "2.9 GB",
|
||||
sha: "b1caaf735c4cc1429223d5a74f0f4d0b9b59a299",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v1.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-large-v1.bin",
|
||||
},
|
||||
{
|
||||
type: "large-v2",
|
||||
name: "ggml-large-v2.bin",
|
||||
size: "2.9 GB",
|
||||
sha: "0f4c8e34f21cf1a914c59d8b3ce882345ad349d6",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v2.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-large-v2.bin",
|
||||
},
|
||||
{
|
||||
type: "large",
|
||||
name: "ggml-large-v3.bin",
|
||||
size: "2.9 GB",
|
||||
sha: "ad82bf6a9043ceed055076d0fd39f5f186ff8062",
|
||||
url: "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-large-v3.bin",
|
||||
url: "https://hf-mirror.com/ggerganov/whisper.cpp/resolve/main/ggml-large-v3.bin",
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import whisper from "@main/whisper";
|
||||
import fs from "fs-extra";
|
||||
import "@main/i18n";
|
||||
import log from "@main/logger";
|
||||
import { WEB_API_URL, REPO_URL } from "@/constants";
|
||||
import { WEB_API_URL, REPO_URL, WEB_API_URLS } from "@/constants";
|
||||
import { AudibleProvider, TedProvider, YoutubeProvider } from "@main/providers";
|
||||
import Ffmpeg from "@main/ffmpeg";
|
||||
import { Waveform } from "./waveform";
|
||||
@@ -140,6 +140,10 @@ main.init = () => {
|
||||
} = bounds;
|
||||
const { navigatable = false } = options || {};
|
||||
|
||||
const OAUTH_URL_REGEX = new RegExp(
|
||||
`^("${WEB_API_URLS.map((url) => `${url}/oauth`).join("|")})`
|
||||
);
|
||||
|
||||
logger.debug("view-load", url);
|
||||
const view = new BrowserView();
|
||||
view.setBackgroundColor("#fff");
|
||||
@@ -193,11 +197,7 @@ main.init = () => {
|
||||
});
|
||||
|
||||
logger.debug("will-redirect", detail.url);
|
||||
if (
|
||||
detail.url.startsWith(
|
||||
`${process.env.WEB_API_URL || WEB_API_URL}/oauth`
|
||||
)
|
||||
) {
|
||||
if (detail.url.match(OAUTH_URL_REGEX)) {
|
||||
logger.debug("prevent redirect", detail.url);
|
||||
detail.preventDefault();
|
||||
}
|
||||
@@ -210,12 +210,7 @@ main.init = () => {
|
||||
});
|
||||
|
||||
logger.debug("will-navigate", detail.url);
|
||||
if (
|
||||
!navigatable ||
|
||||
detail.url.startsWith(
|
||||
`${process.env.WEB_API_URL || WEB_API_URL}/oauth`
|
||||
)
|
||||
) {
|
||||
if (!navigatable || detail.url.match(OAUTH_URL_REGEX)) {
|
||||
logger.debug("prevent navigation", detail.url);
|
||||
detail.preventDefault();
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
DefaultAudioLayout,
|
||||
defaultLayoutIcons,
|
||||
} from "@vidstack/react/player/layouts/default";
|
||||
import { STORAGE_WORKER_ENDPOINT } from "@/constants";
|
||||
import { STORAGE_WORKER_ENDPOINTS } from "@/constants";
|
||||
import { TimelineEntry } from "echogarden/dist/utilities/Timeline.d.js";
|
||||
import { t } from "i18next";
|
||||
import { XCircleIcon } from "lucide-react";
|
||||
@@ -63,7 +63,9 @@ export const PostAudio = (props: {
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
{audio.sourceUrl.startsWith(STORAGE_WORKER_ENDPOINT) ? (
|
||||
{audio.sourceUrl.match(
|
||||
new RegExp("^(" + STORAGE_WORKER_ENDPOINTS.join("|") + ")")
|
||||
) ? (
|
||||
<WavesurferPlayer
|
||||
currentTime={currentTime}
|
||||
setCurrentTime={setCurrentTime}
|
||||
|
||||
@@ -23,6 +23,7 @@ import {
|
||||
import { ChevronLeftIcon } from "lucide-react";
|
||||
import intlTelInput from "intl-tel-input";
|
||||
import "intl-tel-input/build/css/intlTelInput.css";
|
||||
import { WEB_API_URLS } from "@/constants";
|
||||
|
||||
export const LoginForm = () => {
|
||||
const { EnjoyApp, login, webApi, user } = useContext(
|
||||
@@ -51,8 +52,11 @@ export const LoginForm = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
const BASE_URL_REGEX = new RegExp(
|
||||
`^(${[webApi.baseUrl, ...WEB_API_URLS].join("|")})`
|
||||
);
|
||||
if (state === "will-navigate" || state === "will-redirect") {
|
||||
if (!url.startsWith(webApi.baseUrl)) {
|
||||
if (!url.match(BASE_URL_REGEX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -117,7 +121,7 @@ export const LoginForm = () => {
|
||||
<>
|
||||
<Card className="w-full max-w-sm">
|
||||
<CardHeader>
|
||||
<CardTitle>{t('login')}</CardTitle>
|
||||
<CardTitle>{t("login")}</CardTitle>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent>
|
||||
@@ -126,7 +130,7 @@ export const LoginForm = () => {
|
||||
<div className="">
|
||||
<Separator className="my-4" />
|
||||
<div className="flex items-center justify-center text-xs text-muted-foreground mb-4">
|
||||
{t('youCanAlsoLoginWith')}
|
||||
{t("youCanAlsoLoginWith")}
|
||||
</div>
|
||||
<div className="flex items-center space-x-2 justify-center">
|
||||
<Button
|
||||
@@ -189,8 +193,9 @@ export const LoginForm = () => {
|
||||
</Card>
|
||||
|
||||
<div
|
||||
className={`absolute top-0 left-0 w-screen h-screen z-10 flex flex-col overflow-hidden ${webviewUrl ? "" : "hidden"
|
||||
}`}
|
||||
className={`absolute top-0 left-0 w-screen h-screen z-10 flex flex-col overflow-hidden ${
|
||||
webviewUrl ? "" : "hidden"
|
||||
}`}
|
||||
>
|
||||
<div className="flex items-center py-2 px-6">
|
||||
<Button variant="ghost" onClick={() => setWebviewUrl(null)}>
|
||||
@@ -224,14 +229,14 @@ const EmailLoginForm = () => {
|
||||
|
||||
return () => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
}
|
||||
};
|
||||
}, [countdown]);
|
||||
|
||||
return (
|
||||
<div className="w-full">
|
||||
<div className="w-full grid gap-4 mb-6">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="email">{t('email')}</Label>
|
||||
<Label htmlFor="email">{t("email")}</Label>
|
||||
<Input
|
||||
id="email"
|
||||
className="h-10"
|
||||
@@ -245,7 +250,7 @@ const EmailLoginForm = () => {
|
||||
</div>
|
||||
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="code">{t('verificationCode')}</Label>
|
||||
<Label htmlFor="code">{t("verificationCode")}</Label>
|
||||
<Input
|
||||
id="code"
|
||||
className="h-10"
|
||||
@@ -304,7 +309,7 @@ const EmailLoginForm = () => {
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
const PandoLoginForm = () => {
|
||||
const ref = useRef<HTMLInputElement>(null);
|
||||
@@ -356,7 +361,7 @@ const PandoLoginForm = () => {
|
||||
|
||||
return () => {
|
||||
if (timeout) clearTimeout(timeout);
|
||||
}
|
||||
};
|
||||
}, [countdown]);
|
||||
|
||||
return (
|
||||
@@ -368,7 +373,7 @@ const PandoLoginForm = () => {
|
||||
<div className="grid gap-6">
|
||||
<div className="grid gap-4">
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="phone">{t('phoneNumber')}</Label>
|
||||
<Label htmlFor="phone">{t("phoneNumber")}</Label>
|
||||
<input
|
||||
id="phone"
|
||||
value={phoneNumber}
|
||||
@@ -379,7 +384,7 @@ const PandoLoginForm = () => {
|
||||
/>
|
||||
</div>
|
||||
<div className="grid gap-2">
|
||||
<Label htmlFor="verrificationCode">{t('verificationCode')}</Label>
|
||||
<Label htmlFor="verrificationCode">{t("verificationCode")}</Label>
|
||||
<Input
|
||||
id="verrificationCode"
|
||||
className="border py-2 h-10 px-4 rounded"
|
||||
|
||||
Reference in New Issue
Block a user