<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML5语音合成演示</title>
<style>
body {
font-family: 'Arial', sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background-color: #f5f5f5;
}
h1 {
color: #333;
text-align: center;
}
.container {
background-color: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
}
textarea {
width: 100%;
height: 100px;
margin-bottom: 15px;
padding: 10px;
border: 1px solid #ddd;
border-radius: 4px;
resize: vertical;
}
button {
background-color: #4CAF50;
color: white;
border: none;
padding: 10px 15px;
border-radius: 4px;
cursor: pointer;
font-size: 16px;
margin-right: 10px;
}
button:hover {
background-color: #45a049;
}
button:disabled {
background-color: #cccccc;
cursor: not-allowed;
}
.controls {
margin-top: 20px;
}
.voice-select {
margin: 15px 0;
}
select, input {
padding: 8px;
border-radius: 4px;
border: 1px solid #ddd;
}
.link {
margin-top: 30px;
text-align: center;
font-size: 14px;
color: #666;
}
</style>
</head>
<body>
<div class="container">
<h1>HTML5语音合成演示</h1>
<div class="voice-select">
<label for="voice-select">选择语音: </label>
<select id="voice-select"></select>
<label for="rate" style="margin-left: 15px;">语速: </label>
<input type="range" id="rate" min="0.5" max="2" step="0.1" value="1">
<span id="rate-value">1</span>
<label for="pitch" style="margin-left: 15px;">音调: </label>
<input type="range" id="pitch" min="0.5" max="2" step="0.1" value="1">
<span id="pitch-value">1</span>
</div>
<textarea id="text-to-speak" placeholder="在这里输入要朗读的文字...">欢迎使用HTML5语音合成API,这是一个演示如何将文本转换为语音并播放的示例。</textarea>
<div class="controls">
<button id="speak-btn">朗读</button>
<button id="pause-btn" disabled>暂停</button>
<button id="resume-btn" disabled>继续</button>
<button id="stop-btn" disabled>停止</button>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const textInput = document.getElementById('text-to-speak');
const speakBtn = document.getElementById('speak-btn');
const pauseBtn = document.getElementById('pause-btn');
const resumeBtn = document.getElementById('resume-btn');
const stopBtn = document.getElementById('stop-btn');
const voiceSelect = document.getElementById('voice-select');
const rateInput = document.getElementById('rate');
const pitchInput = document.getElementById('pitch');
const rateValue = document.getElementById('rate-value');
const pitchValue = document.getElementById('pitch-value');
let speechSynthesis = window.speechSynthesis;
let speechUtterance = null;
// 填充语音列表
function populateVoiceList() {
voiceSelect.innerHTML = '';
const voices = speechSynthesis.getVoices();
// 筛选中文语音(优先显示)
const chineseVoices = voices.filter(voice => voice.lang.includes('zh') || voice.lang.includes('cmn'));
const otherVoices = voices.filter(voice => !voice.lang.includes('zh') && !voice.lang.includes('cmn'));
// 添加中文语音选项
chineseVoices.forEach(voice => {
const option = document.createElement('option');
option.textContent = `${voice.name} (${voice.lang})${voice.default ? ' - 默认' : ''}`;
option.setAttribute('data-name', voice.name);
voiceSelect.appendChild(option);
});
// 添加分隔线
if (chineseVoices.length > 0 && otherVoices.length > 0) {
const separator = document.createElement('option');
separator.disabled = true;
separator.textContent = '──────────';
voiceSelect.appendChild(separator);
}
// 添加其他语音选项
otherVoices.forEach(voice => {
const option = document.createElement('option');
option.textContent = `${voice.name} (${voice.lang})${voice.default ? ' - 默认' : ''}`;
option.setAttribute('data-name', voice.name);
voiceSelect.appendChild(option);
});
}
// 语音列表加载
speechSynthesis.onvoiceschanged = populateVoiceList;
populateVoiceList(); // 如果语音已经加载
// 更新滑块值显示
rateInput.addEventListener('input', () => {
rateValue.textContent = rateInput.value;
});
pitchInput.addEventListener('input', () => {
pitchValue.textContent = pitchInput.value;
});
// 朗读按钮点击事件
speakBtn.addEventListener('click', () => {
if (textInput.value.trim() === '') {
alert('请输入要朗读的文字');
return;
}
// 停止当前正在朗读的内容
speechSynthesis.cancel();
// 创建新的语音实例
speechUtterance = new SpeechSynthesisUtterance(textInput.value);
// 设置选中的语音
const selectedOption = voiceSelect.selectedOptions[0];
if (selectedOption) {
const voices = speechSynthesis.getVoices();
const selectedVoice = voices.find(voice => voice.name === selectedOption.getAttribute('data-name'));
if (selectedVoice) {
speechUtterance.voice = selectedVoice;
}
}
// 设置语速和音调
speechUtterance.rate = parseFloat(rateInput.value);
speechUtterance.pitch = parseFloat(pitchInput.value);
// 启用/禁用按钮
speakBtn.disabled = true;
pauseBtn.disabled = false;
stopBtn.disabled = false;
// 朗读完成事件
speechUtterance.onend = () => {
speakBtn.disabled = false;
pauseBtn.disabled = true;
resumeBtn.disabled = true;
stopBtn.disabled = true;
};
// 开始朗读
speechSynthesis.speak(speechUtterance);
});
// 暂停按钮点击事件
pauseBtn.addEventListener('click', () => {
speechSynthesis.pause();
pauseBtn.disabled = true;
resumeBtn.disabled = false;
});
// 继续按钮点击事件
resumeBtn.addEventListener('click', () => {
speechSynthesis.resume();
pauseBtn.disabled = false;
resumeBtn.disabled = true;
});
// 停止按钮点击事件
stopBtn.addEventListener('click', () => {
speechSynthesis.cancel();
speakBtn.disabled = false;
pauseBtn.disabled = true;
resumeBtn.disabled = true;
stopBtn.disabled = true;
});
});
</script>
</body>
</html>
1万+

被折叠的 条评论
为什么被折叠?



