百度 TTS 接入完整指南

文章目录

  • 前言
    • 项目信息
    • 一、前期准备
      • [1.1 申请百度智能云账号](#1.1 申请百度智能云账号)
      • [1.2 了解百度 TTS API](#1.2 了解百度 TTS API)
    • 二、项目结构
    • 三、核心代码实现
      • [3.1 配置文件 (`src/config/tts.config.ts`)](#3.1 配置文件 (src/config/tts.config.ts))
      • [3.2 TTS 服务封装 (`src/utils/baiduTTS.ts`)](#3.2 TTS 服务封装 (src/utils/baiduTTS.ts))
      • [3.3 音频播放组件 (`src/components/AudioPlayer.vue`)](#3.3 音频播放组件 (src/components/AudioPlayer.vue))
    • 四、遇到的坑及解决方案
      • [坑 1:浏览器 CORS 错误 ❌](#坑 1:浏览器 CORS 错误 ❌)
      • [坑 2:TTS 服务未初始化 ❌](#坑 2:TTS 服务未初始化 ❌)
      • [坑 3:模拟器可以,真机不行 ❌](#坑 3:模拟器可以,真机不行 ❌)
      • [坑 4:API 返回错误 -1100 ❌](#坑 4:API 返回错误 -1100 ❌)
      • [坑 5:音频生成成功但播放失败 ❌ (最关键!)](#坑 5:音频生成成功但播放失败 ❌ (最关键!))
    • 五、完整的开发流程
      • [5.1 浏览器开发(H5)](#5.1 浏览器开发(H5))
      • [5.2 小程序开发](#5.2 小程序开发)
      • [5.3 生产发布](#5.3 生产发布)
    • 六、测试检查清单
    • 七、性能优化建议
      • [7.1 音频缓存](#7.1 音频缓存)
      • [7.2 预生成音频](#7.2 预生成音频)
      • [7.3 使用 CDN](#7.3 使用 CDN)
    • [八、常见问题 FAQ](#八、常见问题 FAQ)
      • [Q1: 为什么模拟器可以,真机不行?](#Q1: 为什么模拟器可以,真机不行?)
      • [Q2: 如何查看真机上的错误日志?](#Q2: 如何查看真机上的错误日志?)
      • [Q3: API Key 有使用限制吗?](#Q3: API Key 有使用限制吗?)
      • [Q4: 可以更换发音人吗?](#Q4: 可以更换发音人吗?)
      • [Q5: 如何处理长文本?](#Q5: 如何处理长文本?)
    • 九、相关资源
    • 十、总结

前言

在小程序开发中,需要做一个文本播放功能,这里是英语播放。可以使用各大厂商的TTS播放服务。

项目信息

  • 项目类型:uni-app(Vue3 + TypeScript)
  • 目标平台:微信小程序
  • TTS 服务:百度智能云语音合成
  • 完成时间:2025-12-14

一、前期准备

1.1 申请百度智能云账号

  1. 访问 百度智能云
  2. 注册并登录账号
  3. 进入控制台 → 产品服务 → 人工智能 → 语音技术
  4. 创建应用,获取 API Key 和 Secret Key

1.2 了解百度 TTS API


二、项目结构

js 复制代码
my-vue3-project/
├── src/
│   ├── config/
│   │   └── tts.config.ts          # TTS 配置文件
│   ├── utils/
│   │   └── baiduTTS.ts            # TTS 服务封装
│   ├── components/
│   │   └── AudioPlayer.vue        # 音频播放组件
│   └── main.ts                    # TTS 初始化
└── server/
    ├── package.json
    └── tts-proxy.js               # 代理服务器(可选)

三、核心代码实现

3.1 配置文件 (src/config/tts.config.ts)

typescript 复制代码
export const BAIDU_TTS_CONFIG = {
  apiKey: '你的API_KEY',
  secretKey: '你的SECRET_KEY',
  useProxy: false,  // 浏览器开发时设为 true
  proxyUrl: 'http://localhost:3000/api/tts',
};

export const DEFAULT_TTS_OPTIONS = {
  lang: 'en' as const,
  spd: 5,  // 语速
  pit: 5,  // 音调
  vol: 8,  // 音量
  per: 0,  // 发音人(0=女声,1=男声)
};

3.2 TTS 服务封装 (src/utils/baiduTTS.ts)

关键实现要点:

typescript 复制代码
class BaiduTTSService {
  // 1. 获取 Access Token(带缓存)
  private async getAccessToken(): Promise<string> {
    if (this.accessToken && Date.now() < this.tokenExpireTime) {
      return this.accessToken;
    }
    // 请求新 token...
  }

  // 2. 文字转语音(使用 POST 方式)
  async textToSpeech(options: TTSOptions): Promise<string> {
    const token = await this.getAccessToken();
    
    // 使用 POST 方式请求
    const response = await uni.request({
      url: 'https://tsn.baidu.com/text2audio',
      method: 'POST',
      data: { tex, tok, cuid, lan, spd, pit, vol, per, aue },
      header: { 'Content-Type': 'application/x-www-form-urlencoded' },
      responseType: 'arraybuffer',
    });

    // 3. 保存为临时文件(关键!)
    const base64 = uni.arrayBufferToBase64(response.data);
    const fs = uni.getFileSystemManager();
    const tempFilePath = `${wx.env.USER_DATA_PATH}/tts_${Date.now()}.mp3`;
    fs.writeFileSync(tempFilePath, base64, 'base64');
    
    return tempFilePath;  // 返回文件路径,不是 Base64
  }
}

3.3 音频播放组件 (src/components/AudioPlayer.vue)

js 复制代码
<script setup>
import { getTTSInstance, initBaiduTTS } from '../utils/baiduTTS';
import { BAIDU_TTS_CONFIG } from '../config/tts.config';

const generateAudio = async () => {
  // 确保 TTS 服务已初始化
  let tts;
  try {
    tts = getTTSInstance();
  } catch (e) {
    tts = initBaiduTTS(BAIDU_TTS_CONFIG);
  }
  
  // 生成音频
  const audioUrl = await tts.textToSpeech({
    text: props.text,
    lang: 'en',
  });
  
  // 初始化播放器
  innerAudioContext = uni.createInnerAudioContext();
  innerAudioContext.src = audioUrl;  // 使用临时文件路径
  innerAudioContext.play();
};
</script>

四、遇到的坑及解决方案

坑 1:浏览器 CORS 错误 ❌

问题

json 复制代码
Access to XMLHttpRequest at 'https://aip.baidubce.com/...' 
has been blocked by CORS policy

原因:浏览器的同源策略阻止跨域请求

解决方案

  1. 开发阶段 :使用代理服务器
    • 创建 Node.js 代理服务器(见 server/tts-proxy.js
    • 配置 useProxy: true
  2. 生产环境
    • 小程序:配置合法域名白名单
    • App:直接调用 API
    • Web:部署代理服务器

坑 2:TTS 服务未初始化 ❌

问题

js 复制代码
Error: 请先调用 initBaiduTTS 初始化服务

原因:组件加载时 TTS 服务还未初始化完成

解决方案

js 复制代码
// 在组件中动态初始化
let tts;
try {
  tts = getTTSInstance();
} catch (e) {
  console.log('TTS 服务未初始化,正在初始化...');
  tts = initBaiduTTS(BAIDU_TTS_CONFIG);
}

坑 3:模拟器可以,真机不行 ❌

问题:微信开发者工具模拟器中正常,真机预览失败

原因

  1. 真机预览会检查域名白名单
  2. 模拟器勾选"不校验合法域名"后可以访问任何域名

解决方案

  1. 临时方案:使用"真机调试"而不是"预览"
  2. 正式方案 :在微信公众平台配置合法域名
    • 登录 微信公众平台

    • 开发 → 开发管理 → 开发设置 → 服务器域名

    • 添加 request 合法域名:

      复制代码
      https://aip.baidubce.com
      https://tsn.baidu.com

坑 4:API 返回错误 -1100 ❌

问题

js 复制代码
INNERERRORCODE:-1100, ERRMSG:在此服务器上找不到所请求的URL
errCode: 10001

原因

  1. 使用 GET 方式请求,参数可能被截断
  2. 参数类型不正确(字符串 vs 数字)

解决方案

typescript 复制代码
// ❌ 错误:使用 GET 方式
uni.request({
  url: `https://tsn.baidu.com/text2audio?${queryString}`,
  method: 'GET',
});

// ✅ 正确:使用 POST 方式
uni.request({
  url: 'https://tsn.baidu.com/text2audio',
  method: 'POST',
  data: {
    tex: text,
    tok: token,
    spd: 5,  // 数字类型,不是字符串
    // ...
  },
  header: {
    'Content-Type': 'application/x-www-form-urlencoded'
  },
});

坑 5:音频生成成功但播放失败 ❌ (最关键!)

问题

复制代码
[AudioPlayer Error]
type: "AudioPlayerError"

原因 :小程序的 innerAudioContext 在真机上不支持直接播放 Base64 格式的音频

错误做法

typescript 复制代码
// ❌ 直接返回 Base64
const base64 = uni.arrayBufferToBase64(response.data);
return `data:audio/mp3;base64,${base64}`;

正确做法

typescript 复制代码
// ✅ 保存为临时文件
const base64 = uni.arrayBufferToBase64(response.data);
const fs = uni.getFileSystemManager();
const tempFilePath = `${wx.env.USER_DATA_PATH}/tts_${Date.now()}.mp3`;

fs.writeFileSync(tempFilePath, base64, 'base64');
return tempFilePath;  // 返回文件路径

为什么这样做

  • Base64 URL 在真机上播放不稳定
  • 临时文件路径更可靠
  • 系统会自动清理临时文件

五、完整的开发流程

5.1 浏览器开发(H5)

bash 复制代码
# 1. 启动代理服务器
cd server
npm install
npm start

# 2. 修改配置
# src/config/tts.config.ts
useProxy: true

# 3. 启动开发服务器
npm run dev:h5

5.2 小程序开发

bash 复制代码
# 1. 构建小程序
npm run dev:mp-weixin

# 2. 配置
# src/config/tts.config.ts
useProxy: false

# 3. 微信开发者工具
# - 导入项目:dist/dev/mp-weixin
# - 详情 → 本地设置 → 勾选"不校验合法域名"
# - 使用"真机调试"测试

5.3 生产发布

bash 复制代码
# 1. 配置合法域名(微信公众平台)
https://aip.baidubce.com
https://tsn.baidu.com

# 2. 构建生产版本
npm run build:mp-weixin

# 3. 上传代码
# 微信开发者工具 → 上传

# 4. 提交审核
# 微信公众平台 → 版本管理 → 提交审核

六、测试检查清单

开发阶段

  • 模拟器中能正常播放
  • 真机调试能正常播放
  • 切换句子时音频正常切换
  • 网络错误时有友好提示
  • 音频加载时显示加载状态

发布前

  • 已配置合法域名白名单
  • 真机预览(不是调试)能正常播放
  • API Key 和 Secret Key 正确
  • 测试不同网络环境(WiFi、4G)
  • 测试不同机型(iOS、Android)

七、性能优化建议

7.1 音频缓存

typescript 复制代码
// 缓存已生成的音频
const audioCache = new Map<string, string>();

async textToSpeech(options: TTSOptions): Promise<string> {
  const cacheKey = `${options.text}_${options.lang}`;
  
  if (audioCache.has(cacheKey)) {
    return audioCache.get(cacheKey)!;
  }
  
  const audioUrl = await this.generateAudio(options);
  audioCache.set(cacheKey, audioUrl);
  
  return audioUrl;
}

7.2 预生成音频

对于固定的句子,可以预先生成所有音频:

bash 复制代码
node scripts/generateAudio.js

7.3 使用 CDN

将生成的音频文件上传到 CDN,直接使用 URL。


八、常见问题 FAQ

Q1: 为什么模拟器可以,真机不行?

A: 真机预览会检查域名白名单。使用"真机调试"或配置合法域名。

Q2: 如何查看真机上的错误日志?

A: 使用"真机调试"模式,在开发者工具的"调试器"标签中查看。

Q3: API Key 有使用限制吗?

A: 百度 TTS 有免费额度,超出后需要付费。查看控制台了解详情。

Q4: 可以更换发音人吗?

A: 可以,修改 per 参数:

  • 0:女声
  • 1:男声
  • 3:情感合成-度逍遥
  • 4:情感合成-度丫丫

Q5: 如何处理长文本?

A: 百度 TTS 单次请求有字符限制(约 1024 字节),长文本需要分段处理。


九、相关资源

官方文档

项目文档

  • BAIDU_TTS_SETUP.md - 基础设置指南
  • CORS_TTS_SOLUTION.md - CORS 问题解决方案
  • MINIPROGRAM_TTS_TROUBLESHOOTING.md - 小程序故障排查
  • TTS_QUICK_START.md - 快速开始指南

十、总结

关键要点

  1. 使用 POST 方式请求 TTS API
  2. 保存为临时文件而不是使用 Base64
  3. 配置域名白名单才能在真机预览中使用
  4. 使用真机调试查看详细日志
  5. Token 缓存避免频繁请求

最终效果

  • 模拟器:✅ 正常播放
  • 真机调试:✅ 正常播放
  • 真机预览:✅ 正常播放(需配置域名)
  • 音频质量:✅ 清晰流畅
  • 用户体验:✅ 加载快速,播放稳定

相关推荐
陈思杰系统思考Jason2 小时前
系统思考:结构性重复
百度·微信·微信公众平台·新浪微博·微信开放平台
biotechbd15 小时前
基因功能研究:CD3与CD9
百度·微信公众平台
semantist@语校1 天前
第五十四篇|从事实字段到推理边界:名古屋国际外语学院Prompt生成中的过度推断防御设计
大数据·linux·服务器·人工智能·百度·语言模型·prompt
陈思杰系统思考Jason1 天前
企业经营误区:被动应激与主动经营
百度·微信·微信公众平台·新浪微博·微信开放平台
biotechbd1 天前
卡梅德:活性NLRP3蛋白表达策略
百度·微信公众平台
biotechbd1 天前
药物研发速递:胸腺基质淋巴细胞生成素(TSLP)
百度·微信公众平台·微信开放平台
热点速递1 天前
AI成广告新引擎:从百度、快手到Meta,智能技术如何拯救互联网广告下滑!
人工智能·百度
wan55cn@126.com2 天前
人类文明可通过技术手段(如加强航天器防护、改进电网设计)缓解地球两极反转带来的影响
人工智能·笔记·搜索引擎·百度·微信