Skip to content

Commit

Permalink
feat: 添加阅读的tts
Browse files Browse the repository at this point in the history
  • Loading branch information
x-dr committed Nov 27, 2023
1 parent fbd1cd4 commit b52a6d1
Show file tree
Hide file tree
Showing 4 changed files with 174 additions and 49 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,5 +105,6 @@ http://ip:3035/

### Star History

[![Star History Chart](https://api.star-history.com/svg?repos=x-dr/tts&type=Date)](https://star-history.com/#x-dr/tts&Date)
[![Star History Chart](https://api.star-history.com/svg?repos=x-dr/tts&type=Timeline)](https://star-history.com/#x-dr/tts&Timeline)


113 changes: 77 additions & 36 deletions cf_worker.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
addEventListener('fetch', event => {
event.respondWith(handleRequest(event.request))
})
function generateUUID() {
})


function generateUUID() {
let uuid = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'.replace(/[x]/g, function (c) {
let r = Math.random() * 16 | 0,
v = c === 'x' ? r : (r & 0x3 | 0x8);
return v.toString(16);
});
return uuid;
}
const API_URL = "https://southeastasia.api.speech.microsoft.com/accfreetrial/texttospeech/acc/v3.0-beta1/vcg/speak";
const DEFAULT_HEADERS = {
}

const API_URL = "https://southeastasia.api.speech.microsoft.com/accfreetrial/texttospeech/acc/v3.0-beta1/vcg/speak";
const DEFAULT_HEADERS = {
authority: "southeastasia.api.speech.microsoft.com",
accept: "*/*",
"accept-language": "zh-CN,zh;q=0.9",
Expand All @@ -29,9 +29,9 @@ addEventListener('fetch', event => {
"user-agent":
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
"content-type": "application/json",
};
const speechApi = async (ssml) => {
};

const speechApi = async (ssml) => {
const data = JSON.stringify({
ssml,
ttsAudioFormat: "audio-24khz-160kbitrate-mono-mp3",
Expand All @@ -40,36 +40,36 @@ addEventListener('fetch', event => {
SpeakTriggerSource: "AccTuningPagePlayButton",
},
});

try {
const response = await fetch(API_URL, {
method: "POST",
responseType: "arraybuffer",
headers: DEFAULT_HEADERS,
body: data
});

if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}

return response.arrayBuffer();
} catch (error) {
console.error("Error during API request:", error);
throw error;
}
};
const handleRequest = async (request) => {
};

const handleRequest = async (request) => {
// 解析请求 URL
const url = new URL(request.url);

const clientIP = request.headers.get("CF-Connecting-IP")

if (url.pathname == "/") {
const html = await fetch("https://raw.githubusercontent.com/x-dr/cf_pages/main/tts.html")
const page =await html.text()
const html = await fetch("https://raw.githubusercontent.com/x-dr/cf_pages/main/ttstest.html")

const page = await html.text()
return new Response(page, {
headers: {
"content-type": "text/html;charset=UTF-8",
Expand Down Expand Up @@ -102,7 +102,7 @@ addEventListener('fetch', event => {
</mstts:express-as>
</voice>
</speak>`;

const audio = await speechApi(ssml);
const nowtime = new Date().getTime();
return new Response(audio, {
Expand All @@ -111,17 +111,58 @@ addEventListener('fetch', event => {
"Content-Disposition": `attachment; filename=${nowtime}.mp3`,
},
});
}else{
return new Response("page", {
headers: {
"content-type": "text/html;charset=UTF-8",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"ip": `Access cloudflare's ip:${clientIP}`
},
})
} else if (url.pathname == "/legado") {
const origin = url.origin
const params = new URLSearchParams(url.search);
// 获取查询参数中的文本
const text = params.get("text");
// 获取查询参数中的语速
const rate = params.get("rate");
// 获取查询参数中的音高
const pitch = params.get("pitch");
// 获取查询参数中的音色
const voice = params.get("voice");
// 获取查询参数中的音色风格
const voiceStyle = params.get("voiceStyle");

const dataJson = {
"concurrentRate": "",//并发率
"contentType": "audio/mpeg",
"header": "",
"id": Date.now(),
"lastUpdateTime": Date.now(),
"loginCheckJs": "",
"loginUi": "",
"loginUrl": "",
"name": `Azure ${voice} ${voiceStyle} pitch: ${pitch} rate:${rate}`,
"url": `${origin}/audio?text={{speakText}}&rate=${rate}&pitch=${pitch}&voice=${voice}&voiceStyle=${voiceStyle},{"method":"GET"}`,
}

return new Response(JSON.stringify(dataJson), {
headers: {
"content-type": "application/json;charset=UTF-8",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"ip": `Access cloudflare's ip:${clientIP}`
},
})



}
else {
return new Response("page", {
headers: {
"content-type": "text/html;charset=UTF-8",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": "true",
"Access-Control-Allow-Headers": "*",
"Access-Control-Allow-Methods": "*",
"ip": `Access cloudflare's ip:${clientIP}`
},
})
}
}

}
24 changes: 24 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,31 @@ app.get("/audio", async (req, res) => {
}
});

app.get("/legado", async (req, res) => {
try{

const { voice, rate, pitch, voiceStyle } = req.query;

const dataJson = {
"concurrentRate": "",//并发率
"contentType": "audio/mpeg",
"header": "",
"id": Date.now(),
"lastUpdateTime": Date.now(),
"loginCheckJs": "",
"loginUi": "",
"loginUrl": "",
"name": `Azure ${voice} ${voiceStyle} pitch: ${pitch} rate:${rate}`,
"url": `${origin}/audio?text={{speakText}}&rate=${rate}&pitch=${pitch}&voice=${voice}&voiceStyle=${voiceStyle},{"method":"GET"}`,
}

res.send(dataJson);

}catch(error){

}

});

// 启动服务器,监听在指定端口上
const port = process.env.PORT || 3035;
Expand Down
83 changes: 71 additions & 12 deletions public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,18 @@
margin-bottom: 5px;
}

select,

select{
width: 80%;
padding: 5px;
margin-bottom: 10px;
border-radius: 5px;
border: 1px solid #ccc;
font-size: 1rem;
color: #33404d;
transition: border .3s, box-shadow .3s;
}

textarea {
width: 100%;
padding: 5px;
Expand Down Expand Up @@ -111,25 +122,49 @@
a {
text-decoration: none;
}

.button-group {
display: flex;
gap: 10px;
padding: 10px;
/* 调整按钮之间的间隔,根据需要进行调整 */
}

.button-group button {
padding: 10px;
/* 调整按钮的内边距,根据需要进行调整 */
}
</style>
</head>

<body>
<main>
<h1>语音合成</h1>
<div>
<label for="voiceSelect">声音:</label>
<select id="voiceSelect"></select>
<label for="voiceStyleSelect">声音风格:</label>
<select id="voiceStyleSelect"></select>
<label for="rateRange">语速:</label>
<input type="range" id="rateRange" min="0" max="100" value="0">
<label for="pitchRange">音调:</label>
<input type="range" id="pitchRange" min="0" max="100" value="0">
<label for="voiceSelect">声音:
<select id="voiceSelect"></select>
</label>
<label for="voiceStyleSelect">风格:
<select id="voiceStyleSelect"></select>
</label>
<label for="rateRange">语速:
<input type="range" id="rateRange" min="0" max="100" value="0">
</label>
<label for="pitchRange">音调:
<input type="range" id="pitchRange" min="0" max="100" value="0">
</label>

<label for="ssmlInput">SSML 文本:</label>
<textarea id="ssmlInput" rows="4" cols="50"></textarea>
<button onclick="playAudio()">播放音频</button>
<button onclick="downloadAudio()">下载音频</button>
<textarea id="ssmlInput" rows="4" cols="50">Azure tts 测试</textarea>
<div class="button-group">
<button onclick="playAudio()">播放音频</button>
<button onclick="downloadAudio()">下载音频</button>

</div>
<div class="button-group">
<button onclick="legado()">一键导入阅读</button>
<button onclick="sourceReader()">复制源阅读导入链接</button>
</div>
</div>
<audio id="audioPlayer" controls></audio>
</main>
Expand Down Expand Up @@ -216,6 +251,30 @@ <h1>语音合成</h1>
link.click();
document.body.removeChild(link);
}
function legado() {
const voice = document.getElementById("voiceSelect").value;
const voiceStyle = document.getElementById("voiceStyleSelect").value;
const rate = document.getElementById("rateRange").value;
const pitch = document.getElementById("pitchRange").value;
const text = document.getElementById("ssmlInput").value;

const url = `/legado?voice=${encodeURIComponent(voice)}&voiceStyle=${encodeURIComponent(voiceStyle)}&rate=${encodeURIComponent(rate)}&pitch=${encodeURIComponent(pitch)}&text=${encodeURIComponent(text)}`;
importUrl = "legado://import/httpTTS?src=" + encodeURIComponent(window.location.origin + url);
window.open(importUrl, '_blank');
}

function sourceReader() {
const voice = document.getElementById("voiceSelect").value;
const voiceStyle = document.getElementById("voiceStyleSelect").value;
const rate = document.getElementById("rateRange").value;
const pitch = document.getElementById("pitchRange").value;
const url = `/audio?text={{speakText}}&rate=${encodeURIComponent(rate)}&pitch=${encodeURIComponent(pitch)}&voice=${encodeURIComponent(voice)}&voiceStyle=${encodeURIComponent(voiceStyle)},{"method":"GET"}`;
navigator.clipboard.writeText(window.location.origin + url).then(function () {
alert('复制成功!');
}, function (err) {
alert('复制失败: ', err);
});
}
</script>
</body>

Expand Down

0 comments on commit b52a6d1

Please sign in to comment.