Skip to content

ToSpeech 组件演示

基于 Vue3 和 Web Speech API 的文本转语音组件,提供灵活的插槽设计和完整的播放控制功能。

✨ 特性

  • 📖 博客阅读: 为文章提供语音朗读功能
  • 🎓 在线教育: 辅助学习者理解课程内容
  • ♿ 无障碍应用: 为视障用户提供内容访问
  • 🚗 多任务场景: 驾驶、运动时收听内容
  • 🌍 语言学习: 帮助学习正确发音和语调
  • 📱 移动应用: 在手机上提供免提阅读体验

💡 最佳实践

  1. 文本长度控制: 对于长文本,建议分段处理以提升体验
  2. 错误处理: 检测浏览器支持情况并提供降级方案
  3. 用户体验: 提供清晰的播放状态反馈
  4. 性能优化: 避免频繁创建新的语音实例
  5. 响应式设计: 确保在不同设备上都有良好体验

📦 安装使用

单个引入

在你要使用的页面中引入组件

md
<script setup>
    import { defineClientComponent } from 'vitepress'
    import { ToSpeech } from '@leelaa/vitepress-plugin-extended'
    const ToSpeechView = defineClientComponent(() => ToSpeech)
</script>

全局引入

在你的.vitepress/theme/index.ts中引入组件

js
import { defineAsyncComponent, h } from "vue";
import DefaultTheme from "vitepress/theme";
import { ToSpeech } from "@leelaa/vitepress-plugin-extended";
export default {
  enhanceApp({ app }) {
    app.component("ToSpeech", ToSpeech);
  },
};

🚀 快速开始

安装使用

vue
<script setup>
import ToSpeech from "@/components/ToSpeech.vue";

const content = "这是要转换为语音的文本内容";
</script>

<template>
  <!-- 默认按钮 -->
  <ToSpeech :text="content" />
</template>

✨ 功能演示

默认播放按钮

最简单的使用方式,提供一个方形播放按钮:

vue
<ToSpeech :text="content" />

自定义播放器

通过插槽完全自定义播放界面:

vue
<ToSpeech :text="content">
  <template #default="{ isPlaying, currentTime, totalTime, progress, toggle, setRate, rate }">
    <div class="custom-player">
      <!-- 播放按钮 -->
      <button @click="toggle">
        {{ isPlaying ? '⏸️ 暂停' : '▶️ 播放' }}
      </button>
      <!-- 时间显示 -->
      <div>{{ formatTime(currentTime) }} / {{ formatTime(totalTime) }}</div>
      <!-- 进度条(仅显示) -->
      <div class="progress-bar">
        <div class="progress-fill" :style="{ width: progress + '%' }"></div>
      </div>
      <!-- 倍速控制 -->
      <button 
        v-for="speed in [0.5, 1, 1.5, 2]" 
        :key="speed"
        @click="setRate(speed)"
        :class="{ active: rate === speed }"
      >
        {{ speed }}×
      </button>
    </div>
  </template>
</ToSpeech>

极简播放按钮

在标题旁添加小型播放按钮:

vue
<div class="article-title">
  <h3>文章标题</h3>
  <ToSpeech :text="content">
    <template #default="{ isPlaying, toggle }">
      <button @click="toggle" class="mini-button">
        {{ isPlaying ? '⏸️' : '🔊' }}
      </button>
    </template>
  </ToSpeech>
</div>

📖 API 文档

Props

参数类型默认值说明
textstring""要合成的文本内容(必需)
ratenumber1.0播放速度 (0.5-3.0)
volumenumber1.0音量大小 (0.0-1.0)
autoplaybooleanfalse是否自动播放

插槽参数

参数类型说明
isPlayingboolean是否正在播放
currentTimenumber当前播放时间(秒)
totalTimenumber总时长(秒,估算值)
progressnumber播放进度百分比 (0-100)
ratenumber当前播放速度
loadingboolean是否正在加载
play() => Promise<boolean>播放方法
pause() => void暂停方法
toggle() => void切换播放/暂停
setRate(rate: number) => void设置播放速度

组件方法

通过 ref 访问组件方法:

vue
<script setup>
import { ref } from "vue";

const ttsRef = ref();

const controlPlay = () => ttsRef.value.play();
const controlPause = () => ttsRef.value.pause();
</script>

<template>
  <ToSpeech ref="ttsRef" :text="content" />
  <button @click="controlPlay">外部播放</button>
  <button @click="controlPause">外部暂停</button>
</template>

⚠️ 重要说明

Web Speech API 特性

  1. 进度显示: 基于估算时长显示播放进度
  2. 不支持跳转: 语音是实时合成的,无法跳转到指定位置
  3. 时长估算: 基于文本长度和语速估算,可能与实际时长有差异
  4. 浏览器支持: 需要现代浏览器支持 Web Speech API
  5. 语音质量: 依赖浏览器和系统的语音引擎

浏览器兼容性

javascript
if ("speechSynthesis" in window) {
  // 支持语音合成
} else {
  // 不支持,显示替代方案
}

🛠️ 实用工具

时间格式化

javascript
const formatTime = (seconds) => {
  const mins = Math.floor(seconds / 60);
  const secs = Math.floor(seconds % 60);
  return `${mins}:${secs.toString().padStart(2, "0")}`;
};

文本预处理

javascript
const preprocessText = (text) => {
  return text
    .replace(/\s+/g, " ") // 合并多个空格
    .replace(/[^\u4e00-\u9fa5a-zA-Z0-9\s.,!?;:]/g, "") // 清理特殊字符
    .trim();
};

基于 MIT 许可发布