Skip to content

Commit 005764e

Browse files
committed
Merge branch 'dev'
2 parents 0b7e9c3 + 37af243 commit 005764e

File tree

6 files changed

+97
-32
lines changed

6 files changed

+97
-32
lines changed

.env.example

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
TTS_DEFAULT_SPEAKER=默认音色名称,比如:东北老铁(可选)
1+
# 基础配置
2+
# SECRET_PATH=你的接口访问秘密路径,比如:are-you-ok(可选)
3+
# TTS_DEFAULT_SPEAKER=默认音色名称,比如:东北老铁(可选)
24

35
# 火山引擎,官方文档:https://www.volcengine.com/docs/6561/79817
46
VOLCANO_TTS_APP_ID=火山引擎语音合成 APP ID

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ async function main() {
5858
main();
5959
```
6060

61+
## 🔊 音色列表
62+
63+
当前支持的完整音色列表和音色名称,可在以下列表中查询:
64+
65+
- [火山引擎](https://github.com/idootop/mi-gpt-tts/blob/main/src/tts/volcano.ts)
66+
- [微软必应](https://github.com/idootop/mi-gpt-tts/blob/main/src/tts/edge.ts)
67+
- [OpenAI](https://github.com/idootop/mi-gpt-tts/blob/main/src/tts/openai.ts)
68+
69+
> 注意:列表中不存在的音色,无法直接使用。请提 PR 或自行修改代码添加额外的音色。
70+
6171
## 📖 使用文档
6272

6373
以下为更详细的使用教程,大多数问题都可在 [💬 常见问题](https://github.com/idootop/mi-gpt-tts/blob/main/docs/faq.md) 中找到答案。

docs/changelog.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
# v3.0.0
2+
3+
## 🚨 风险预警
4+
5+
根据用户反馈,有人正在根据 `MiGPT-TTS` 默认 `4321` 端口 + API 路径特征,搜集公网上的相关服务资产。
6+
7+
出于安全考虑,`MiGPT-TTS` 从 v3.0.0 版本开始,访问语音合成接口需要带上 `SECRET_PATH` 防止他人盗刷接口。
8+
9+
如果你正在公网使用旧版 `MiGPT-TTS`,建议立即更新到 v3.0.0 版本,防止接口被盗刷。
10+
11+
## ✨ 更新内容
12+
13+
- ✅ 新增 `SECRET_PATH` 接口访问凭证,防止接口被盗刷
14+
- ✅ 优化接口访问提示文案
15+
116
# v2.0.0
217

318
新增对 [edge-tts](https://github.com/rany2/edge-tts)[OpenAI TTS](https://platform.openai.com/docs/guides/text-to-speech) 的支持,相关配置参数请[在此查看](https://github.com/idootop/mi-gpt-tts/blob/main/docs/settings.md)

docs/mi-gpt.md

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,25 +25,39 @@
2525

2626
然后,将里面的环境变量修改成你自己的,参数含义如下:
2727

28-
| 环境变量名称 | 描述 | 示例 |
29-
| -------------------------- | --------------------------------------------------------------------------------------------------- | ----------------- |
30-
| `VOLCANO_TTS_APP_ID` | 火山引擎语音合成 APP ID | `123456` |
31-
| `VOLCANO_TTS_ACCESS_TOKEN` | 火山引擎语音合成 Access Token | `xxxxxx` |
32-
| `TTS_DEFAULT_SPEAKER` | 默认音色名称或 ID(可选,查看完整[音色列表](https://www.volcengine.com/docs/6561/97465)和费用详情) | `BV700_streaming` |
28+
| 环境变量名称 | 描述 | 示例 |
29+
| -------------------------- | --------------------------------------------------------------------------------------------------- | ------------------------------- |
30+
| `VOLCANO_TTS_APP_ID` | 火山引擎语音合成 APP ID | `123456` |
31+
| `VOLCANO_TTS_ACCESS_TOKEN` | 火山引擎语音合成 Access Token | `xxxxxx` |
32+
| `SECRET_PATH` | 访问秘密路径,相当于访问密码。推荐长度大于 6,由字母、数字、- 和 \_ 组成,为空时每次启动随机生成 | `Are-You-OK` (不要直接用这个!) |
33+
| `TTS_DEFAULT_SPEAKER` | 默认音色名称或 ID(可选,查看完整[音色列表](https://www.volcengine.com/docs/6561/97465)和费用详情) | `BV700_streaming` |
3334

34-
### 3. 部署 MiGPT-TTS 服务
35+
> 注意:出于安全考虑,从 v3.0.0 版本开始,访问语音合成接口需要带上 `SECRET_PATH` 防止他人盗刷接口。
36+
> 如果 `SECRET_PATH` 环境变量为空,每次启动服务则会生成随机访问密码。
3537
36-
考虑到国内网络访问 [Vercel](https://vercel.com) 并不友好,此处仅提供 Docker 部署方式。
38+
### 3. 部署 MiGPT-TTS 服务
3739

3840
[![Docker Image Version](https://img.shields.io/docker/v/idootop/mi-gpt-tts?color=%23086DCD&label=docker%20image)](https://hub.docker.com/r/idootop/mi-gpt-tts)
3941

42+
环境变量配置完成后,请在对应目录运行以下命令,启动服务:
43+
4044
```shell
4145
docker run -d --env-file $(pwd)/.env -p 4321:3000 idootop/mi-gpt-tts:latest
4246
```
4347

44-
启动成功后,访问 `http://[你的公网/局域网地址]:4321/api/tts.mp3` 即可查看语音合成效果。
48+
启动成功后,可在控制台的日志输出中查看接口地址,比如:
49+
50+
```shell
51+
MiGPT-TTS: v3.0.0 by: del.wang
52+
53+
接口地址:http://localhost:3000/7a0e9f21/api
54+
55+
✅ 服务已启动...
56+
```
57+
58+
访问 `http://[IP]:[PORT]/[SECRET_PATH]/api/tts.mp3` 即可查看语音合成效果。
4559

46-
> 注意:如果你是通过 Node.js 本地启动本项目,则默认服务端口为 `3000`
60+
> 注意:这里的端口(PORT)是你为 Docker 分配的实际端口,不推荐使用默认的 4321 端口。如果你是通过 Node.js 本地启动本项目,则默认端口为 `3000`
4761
4862
### 4. 修改 MiGPT 默认 TTS 引擎
4963

@@ -54,7 +68,7 @@ docker run -d --env-file $(pwd)/.env -p 4321:3000 idootop/mi-gpt-tts:latest
5468

5569
```js
5670
// mi-gpt/.env
57-
TTS_BASE_URL=http://[你的公网/局域网地址]:[端口号]/api
71+
TTS_BASE_URL=http://[IP]:[PORT]/[SECRET_PATH]/api
5872

5973
// mi-gpt/.migpt.js
6074
export default {
@@ -76,8 +90,8 @@ export default {
7690

7791
```shell
7892
# mi-gpt/.env
79-
AUDIO_SILENT=http://[你的公网/局域网地址]:[端口号]/slient.wav
80-
AUDIO_BEEP=http://[你的公网/局域网地址]:[端口号]/beep.wav
81-
AUDIO_ACTIVE=http://[你的公网/局域网地址]:[端口号]/active.wav
82-
AUDIO_ERROR=http://[你的公网/局域网地址]:[端口号]/error.wav
93+
AUDIO_SILENT=http://[IP]:[PORT]/[SECRET_PATH]/slient.wav
94+
AUDIO_BEEP=http://[IP]:[PORT]/[SECRET_PATH]/beep.wav
95+
AUDIO_ACTIVE=http://[IP]:[PORT]/[SECRET_PATH]/active.wav
96+
AUDIO_ERROR=http://[IP]:[PORT]/[SECRET_PATH]/error.wav
8397
```

server.js

Lines changed: 40 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,32 @@
11
import http from "http";
22
import apiSpeakers from "./api/speakers.js";
33
import apiTTS from "./api/tts.mp3.js";
4-
import { createReadStream, statSync } from "fs";
4+
import { createReadStream, readFileSync, statSync } from "fs";
5+
import { randomUUID } from "crypto";
56

6-
const exists = (path) => {
7-
try {
8-
return statSync(path).isFile();
9-
} catch (e) {
10-
return false;
11-
}
12-
};
7+
const kPort = process.env.PORT || 3000;
8+
const kVersion = JSON.parse(readFileSync("package.json")).version;
9+
const kSecretPath = process.env.SECRET_PATH || randomUUID().substring(0, 8);
1310

1411
const server = http.createServer((req, res) => {
15-
req.url = req.url.replace("+text=", "&text="); // 修正请求 URL
12+
// 返回提示字符串
13+
const response = (msg) => {
14+
res.writeHead(404, { "Content-Type": "text/plain; charset=utf-8" });
15+
res.end(Buffer.from(msg, "utf8"));
16+
};
17+
18+
// 修正请求 URL 中的转义字符
19+
req.url = req.url.replace("+text=", "&text=");
20+
21+
// 校验 secret path
22+
const secretPath = req.url.split("/")[1];
23+
if (secretPath !== kSecretPath) {
24+
console.log("❌ 非法请求" + decodeURI(req.url));
25+
return response("❌ 非法请求");
26+
}
27+
28+
// 解析原始请求 URL
29+
req.url = req.url.split(kSecretPath)[1];
1630
const { pathname } = new URL("http://127.0.0.1" + req.url);
1731
const filePath = `public${pathname}`;
1832

@@ -30,14 +44,24 @@ const server = http.createServer((req, res) => {
3044
const readStream = createReadStream(filePath);
3145
readStream.pipe(res);
3246
} else {
33-
res.writeHead(404, { "Content-Type": "text/plain" });
34-
res.end("404");
47+
response("✅ 服务已启动");
3548
}
3649
});
3750

38-
const PORT = process.env.PORT || 3000;
39-
server.listen(PORT, () => {
40-
console.log(`MiGPT-TTS is running on port ${PORT}\n`);
41-
console.log("version: v2.0.0 by: del.wang\n");
42-
console.log("✅ 服务已启动...\n");
51+
server.listen(kPort, () => {
52+
console.log(
53+
[
54+
`MiGPT-TTS: v${kVersion} by: del.wang`,
55+
`接口地址: http://localhost:${kPort}/${kSecretPath}/api`,
56+
"✅ 服务已启动...\n",
57+
].join("\n\n")
58+
);
4359
});
60+
61+
function exists(path) {
62+
try {
63+
return statSync(path).isFile();
64+
} catch (e) {
65+
return false;
66+
}
67+
}

src/common/stream.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ export const createStreamHandler = (responseStream: Readable) => {
2727

2828
const error = (err: any, msg = "Something went wrong") => {
2929
console.log(requestId, "❌ " + msg, err);
30-
responseStream.push("404");
30+
responseStream.push("error");
3131
responseStream.push(null);
3232
reject();
3333
};

0 commit comments

Comments
 (0)