重构:分离 HTML/CSS/JS,项目结构更清晰

This commit is contained in:
zwbcc
2026-03-28 20:26:10 +08:00
parent cf7a5f365a
commit c1a69cd50d
4 changed files with 764 additions and 6 deletions

171
index.html Normal file
View File

@@ -0,0 +1,171 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MiniMax Speech HD TTS</title>
<link rel="stylesheet" href="style.css" />
</head>
<body>
<div class="container">
<h1>🎙️ MiniMax Speech HD TTS</h1>
<p class="subtitle">HTTP 流式文字转语音 · speech-2.8-hd</p>
<audio id="nativeAudio" controls></audio>
<div class="card">
<label>API Key <span style="font-weight:400;text-transform:none;font-size:0.7rem;color:#4b5563">(自动保存到本地)</span></label>
<input type="password" id="apiKey" placeholder="输入你的 MiniMax API Key如 Group-xxxxxxxx" autocomplete="off" />
<p class="hint">填写后回车或点击空白处保存。刷新页面不丢失。</p>
</div>
<div class="card">
<div class="row">
<div>
<label>音色 (voice_id)</label>
<select id="voiceId">
<optgroup label="中文">
<option value="male-qn-qingse">male-qn-qingse青年女声</option>
<option value="male-qn-baiyang">male-qn-baiyang青年男声-白扬)</option>
<option value="female-tianmei">female-tianmei甜美女声</option>
<option value="female-shaonv">female-shaonv少女声</option>
<option value="male-shaonian">male-shaonian少年声</option>
<option value="male-zhongtan">male-zhongtan中年男声</option>
<option value="female-yujie">female-yujie御姐音</option>
<option value="female-xiaochao">female-xiaochao小潮音色</option>
<option value="male-happyman">male-happyman开心男声</option>
</optgroup>
<optgroup label="英语">
<option value="male-cenek">male-cenek英语男声-Cenek</option>
<option value="female-alice">female-alice英语女声-Alice</option>
<option value="male-joshua">male-joshua英语男声-Joshua</option>
<option value="female-maverick">female-maverick英语女声-Maverick</option>
</optgroup>
<optgroup label="日语">
<option value="male-jp-qingse">male-jp-qingse</option>
<option value="female-jp-qingse">female-jp-qingse</option>
</optgroup>
<optgroup label="韩语">
<option value="male-kr-qingse">male-kr-qingse</option>
<option value="female-kr-qingse">female-kr-qingse</option>
</optgroup>
</select>
</div>
<div>
<label>模型</label>
<select id="model">
<option value="speech-2.8-hd">speech-2.8-hd高清</option>
<option value="speech-2.6-hd">speech-2.6-hd</option>
<option value="speech-02-hd">speech-02-hd克隆音质</option>
<option value="speech-2.8-turbo">speech-2.8-turbo快速</option>
<option value="speech-2.6-turbo">speech-2.6-turbo</option>
<option value="speech-02-turbo">speech-02-turbo</option>
</select>
</div>
</div>
<div style="margin-top:14px">
<label>语速 <span class="speed-val" id="speedVal">1.00x</span></label>
<input type="range" class="speed-slider" id="speed" min="0.5" max="2.0" step="0.05" value="1.0" />
</div>
<div class="row" style="margin-top:14px">
<div>
<label>音频格式</label>
<select id="format">
<option value="mp3">mp3</option>
<option value="wav">wav</option>
<option value="flac">flac</option>
</select>
</div>
<div>
<label>采样率</label>
<select id="sampleRate">
<option value="16000">16000 Hz</option>
<option value="32000" selected>32000 Hz</option>
<option value="44100">44100 Hz</option>
<option value="48000">48000 Hz</option>
</select>
</div>
</div>
<div class="row" style="margin-top:14px">
<div>
<label>音量</label>
<select id="vol">
<option value="0.5">0.5(低)</option>
<option value="0.75">0.75</option>
<option value="1" selected>1.0(正常)</option>
<option value="1.25">1.25</option>
<option value="1.5">1.5(高)</option>
</select>
</div>
<div>
<label>音调</label>
<select id="pitch">
<option value="-5">-5低沉</option>
<option value="-2">-2</option>
<option value="0" selected>0正常</option>
<option value="2">2</option>
<option value="5">5高亢</option>
</select>
</div>
</div>
<div class="row" style="margin-top:14px">
<div>
<label>情绪(仅 HD/Turbo</label>
<select id="emotion">
<option value="">不指定(自动)</option>
<option value="happy">happy</option>
<option value="sad">sad</option>
<option value="angry">angry</option>
<option value="surprised">surprised</option>
<option value="calm">calm</option>
<option value="whisper">whisper2.6turbo</option>
</select>
</div>
<div>
<label>流式输出</label>
<select id="streamMode">
<option value="true">是(实时,边收边播)</option>
<option value="false" selected>否(等完成后再播)</option>
</select>
</div>
</div>
</div>
<div class="card">
<label>输入文字(最多 10000 字符)</label>
<textarea id="textInput" placeholder="输入要转换的文字,例如:真正的危险不是计算机开始像人一样思考,而是人开始像计算机一样思考。" maxlength="10000"></textarea>
<div style="text-align:right;font-size:0.72rem;color:var(--muted);margin-top:4px;">
<span id="charCount">0</span> / 10000
</div>
</div>
<div class="btn-row">
<button class="btn btn-primary" id="btnPlay" onclick="startSynthesis()">▶ 开始合成</button>
<button class="btn btn-danger" id="btnStop" onclick="stopSynthesis()" disabled>■ 停止</button>
</div>
<div class="btn-row" style="margin-top:8px">
<button class="btn btn-secondary" id="btnDownload" onclick="downloadAudio()" disabled>💾 下载音频</button>
<button class="btn btn-secondary" id="btnReplay" onclick="replayAudio()" disabled>🔁 重新播放</button>
</div>
<div class="progress-bar" id="progressBar">
<div class="progress-fill" id="progressFill"></div>
</div>
<canvas id="waveform"></canvas>
<div class="card">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:8px;">
<label style="margin:0">日志</label>
<span class="status-badge status-idle" id="statusBadge">空闲</span>
</div>
<div class="log-area" id="logArea"></div>
</div>
</div>
<script src="app.js"></script>
</body>
</html>