Skip to content

Commit 20dc236

Browse files
author
developer
committed
更新
1 parent 2162bd1 commit 20dc236

File tree

3 files changed

+143
-44
lines changed

3 files changed

+143
-44
lines changed

index.html

+46-25
Original file line numberDiff line numberDiff line change
@@ -8,42 +8,63 @@
88
<link rel="stylesheet" href="style.css">
99
</head>
1010
<body>
11-
<div class="container mt-5">
12-
<div class="card">
13-
<div class="card-header text-center">
14-
<h2>文本转语音</h2>
15-
</div>
16-
<div class="card-body">
17-
<form id="text2voice-form">
11+
12+
<div class="container mt-5">
13+
<div class="card">
14+
<div class="card-header text-center">
15+
<h2>文本转语音</h2>
16+
</div>
17+
<div class="card-body">
18+
<form id="text2voice-form">
19+
<!-- 新增的API选择 -->
20+
<div class="form-group">
21+
<label for="api">选择API:</label>
22+
<select class="form-control" id="api" required>
23+
<option value="aivoicenet">API 1</option>
24+
<option value="leftsite">API 2</option>
25+
</select>
26+
</div>
27+
<div id="commonParams">
1828
<div class="form-group">
19-
<label for="api">选择API:</label>
20-
<select class="form-control" id="api" required>
21-
<option value="aivoice">API 1</option>
22-
<option value="aivoicenet">API 2</option>
23-
</select>
29+
<label for="text">输入文本:</label>
30+
<textarea class="form-control" id="text" rows="4" required></textarea>
2431
</div>
2532
<div class="form-group">
2633
<label for="speaker">选择讲述人:</label>
2734
<select class="form-control" id="speaker" required></select>
2835
</div>
29-
<div class="form-group">
30-
<label for="text">输入文本:</label>
31-
<textarea class="form-control" id="text" rows="4" required></textarea>
32-
</div>
33-
<button type="submit" class="btn btn-primary btn-block">生成语音</button>
34-
</form>
35-
<div class="mt-4" id="result" style="display: none;">
36-
<audio id="audio" controls class="w-100"></audio>
37-
<a id="download" class="btn btn-success btn-block mt-3" href="#" download="voice.mp3">下载语音文件</a>
3836
</div>
39-
<div class="mt-4" id="loading" style="display: none;">
40-
正在生成语音,请稍候...
37+
<div id="leftsiteParams" style="display: none;">
38+
<div class="slider-container">
39+
<label for="rate">语速: <span id="rateValue">0</span></label>
40+
<input type="range" id="rate" name="rate" min="-100" max="100" value="0">
41+
</div>
42+
<div class="slider-container">
43+
<label for="pitch">语调: <span id="pitchValue">0</span></label>
44+
<input type="range" id="pitch" name="pitch" min="-100" max="100" value="0">
45+
</div>
4146
</div>
47+
<button type="submit" class="btn btn-primary btn-block">生成语音</button>
48+
</form>
49+
<div class="mt-4" id="result" style="display: none;">
50+
<audio id="audio" controls class="w-100"></audio>
51+
<a id="download" class="btn btn-success btn-block mt-3" href="#" download="voice.mp3">下载语音文件</a>
52+
</div>
53+
<div class="mt-4" id="loading" style="display: none;">
54+
正在生成语音,请稍候...
4255
</div>
4356
</div>
4457
</div>
58+
</div>
59+
60+
<div id="history" class="container mt-5">
61+
<h2>历史记录</h2>
62+
<button onclick="clearHistory()" class="btn btn-warning btn-block">清除历史</button>
63+
<div id="historyItems"></div>
64+
</div>
4565

46-
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
47-
<script src="script.js"></script>
66+
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
67+
<script src="script.js"></script>
68+
4869
</body>
4970
</html>

script.js

+73-19
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,4 @@
11
const apiConfig = {
2-
aivoice: {
3-
url: "https://api.pearktrue.cn/api/aivoice/",
4-
speakers: [
5-
"清萍微调", "晓田微调", "晓华", "晓田", "开放", "菲菲", "琳琳", "艾希"
6-
]
7-
},
82
aivoicenet: {
93
url: "https://api.pearktrue.cn/api/aivoicenet",
104
speakers: [
@@ -27,6 +21,22 @@ const apiConfig = {
2721
"Sadie", "Daniel", "Jacob", "Natalie", "Tyler", "Lily", "Thomas", "Harper", "Henry", "Naomi",
2822
"Ethan", "Emma", "Ava", "Lucas", "Chloe", "Caleb", "Sofia", "Gabriel", "Ivy"
2923
]
24+
},
25+
leftsite: {
26+
url: "https://t.leftsite.cn/tts",
27+
speakers: [
28+
"zh-CN-XiaoxiaoMultilingualNeural", "zh-CN-XiaoxiaoNeural", "zh-CN-YunxiNeural", "zh-CN-YunjianNeural",
29+
"zh-CN-XiaoyiNeural", "zh-CN-YunyangNeural", "zh-CN-XiaochenNeural", "zh-CN-XiaohanNeural",
30+
"zh-CN-XiaomengNeural", "zh-CN-XiaomoNeural", "zh-CN-XiaoqiuNeural", "zh-CN-XiaorouNeural",
31+
"zh-CN-XiaoruiNeural", "zh-CN-XiaoshuangNeural", "zh-CN-XiaoyanNeural", "zh-CN-XiaoyouNeural",
32+
"zh-CN-XiaozhenNeural", "zh-CN-YunfengNeural", "zh-CN-YunhaoNeural", "zh-CN-YunjieNeural",
33+
"zh-CN-YunxiaNeural", "zh-CN-YunyeNeural", "zh-CN-YunzeNeural", "zh-CN-YunfanMultilingualNeural",
34+
"zh-CN-YunxiaoMultilingualNeural", "zh-CN-guangxi-YunqiNeural", "zh-CN-henan-YundengNeural",
35+
"zh-CN-liaoning-XiaobeiNeural", "zh-CN-liaoning-YunbiaoNeural", "zh-CN-shaanxi-XiaoniNeural",
36+
"zh-CN-shandong-YunxiangNeural", "zh-CN-sichuan-YunxiNeural", "zh-HK-HiuMaanNeural",
37+
"zh-HK-WanLungNeural", "zh-HK-HiuGaaiNeural", "zh-TW-HsiaoChenNeural", "zh-TW-YunJheNeural",
38+
"zh-TW-HsiaoYuNeural"
39+
]
3040
}
3141
};
3242

@@ -37,16 +47,19 @@ function updateSpeakerOptions(apiName) {
3747
speakers.forEach(speaker => {
3848
speakerSelect.append(new Option(speaker, speaker));
3949
});
50+
51+
const showAdditionalParams = apiName === 'leftsite';
52+
$('#leftsiteParams').toggle(showAdditionalParams);
4053
}
4154

4255
$(document).ready(function () {
43-
// Update speaker options based on selected API
56+
// 更新所选 API 的讲述人选项
4457
$('#api').on('change', function () {
4558
updateSpeakerOptions(this.value);
4659
});
4760

48-
// Set initial speaker options
49-
updateSpeakerOptions('aivoice');
61+
// 设置初始的讲述人选项
62+
updateSpeakerOptions('aivoicenet');
5063

5164
$('#text2voice-form').on('submit', function (event) {
5265
event.preventDefault();
@@ -55,7 +68,18 @@ $(document).ready(function () {
5568
const apiUrl = apiConfig[apiName].url;
5669
const speaker = $('#speaker').val();
5770
const text = $('#text').val();
58-
const params = new URLSearchParams({ speak: speaker, text: text });
71+
const params = new URLSearchParams({
72+
speak: speaker,
73+
text: text
74+
});
75+
76+
if (apiName === 'leftsite') {
77+
const rate = $('#rate').val();
78+
const pitch = $('#pitch').val();
79+
params.append('r', rate);
80+
params.append('p', pitch);
81+
params.append('o', 'audio-24khz-48kbitrate-mono-mp3');
82+
}
5983

6084
$('#loading').show();
6185
$('#result').hide();
@@ -64,15 +88,11 @@ $(document).ready(function () {
6488
url: `${apiUrl}?${params.toString()}`,
6589
method: 'GET',
6690
success: function (data) {
67-
if (data.code === 200) {
68-
const voiceUrl = apiName === 'aivoice' ? data.voice : data.voiceurl;
69-
$('#audio').attr('src', voiceUrl);
70-
$('#download').attr('href', voiceUrl);
71-
$('#result').show();
72-
} else {
73-
alert('生成失败,请重试');
74-
}
75-
91+
const voiceUrl = apiName === 'aivoicenet' ? data.voiceurl : `${apiUrl}?${params.toString()}`;
92+
$('#audio').attr('src', voiceUrl);
93+
$('#download').attr('href', voiceUrl);
94+
$('#result').show();
95+
addHistoryItem(text, voiceUrl); // 添加到历史记录
7696
$('#loading').hide();
7797
},
7898
error: function () {
@@ -82,3 +102,37 @@ $(document).ready(function () {
82102
});
83103
});
84104
});
105+
106+
function addHistoryItem(text, audioURL) {
107+
const historyItems = $('#historyItems');
108+
const historyItem = $(`
109+
<div class="history-item">
110+
<span>${text}</span>
111+
<div>
112+
<button class="btn btn-secondary" onclick="playAudio('${audioURL}')">播放</button>
113+
<button class="btn btn-info" onclick="downloadAudio('${audioURL}')">下载</button>
114+
</div>
115+
</div>
116+
`);
117+
historyItems.append(historyItem);
118+
}
119+
120+
function playAudio(audioURL) {
121+
const audioSource = $('#audioSource');
122+
audioSource.attr('src', audioURL);
123+
124+
const audioElement = $('#audioPlayer audio')[0];
125+
audioElement.load();
126+
audioElement.play();
127+
}
128+
129+
function downloadAudio(audioURL) {
130+
const link = document.createElement('a');
131+
link.href = audioURL;
132+
link.download = 'audio.mp3';
133+
link.click();
134+
}
135+
136+
function clearHistory() {
137+
$('#historyItems').empty();
138+
}

style.css

+24
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,27 @@ body {
1111
text-align: center;
1212
font-style: italic;
1313
}
14+
15+
.slider-container {
16+
margin-top: 10px;
17+
}
18+
19+
.slider-container label {
20+
display: flex;
21+
justify-content: space-between;
22+
}
23+
24+
#history {
25+
margin-top: 20px;
26+
}
27+
28+
.history-item {
29+
display: flex;
30+
justify-content: space-between;
31+
align-items: center;
32+
margin-top: 10px;
33+
}
34+
35+
.history-item button {
36+
margin-left: 10px;
37+
}

0 commit comments

Comments
 (0)