Expo Speech中Speech.speak如何在每个分隔符(如空格)处触发回调函数?
在Expo Speech中实现单词级回调的解决方案
首先得明确:Expo Speech的onBoundary和onMark回调确实依赖于底层系统TTS引擎的事件支持,但官方文档缺失且跨平台行为不一致,这也是你尝试后没得到预期效果的原因。这两个回调通常是针对句子、段落或预定义标记触发,而非自动识别空格分隔的单词,而且不同平台(iOS/Android)的TTS引擎对边界事件的支持差异很大,很难保证在每个单词后稳定触发。
下面给你两个可行的解决方案,都兼容Expo Go:
方案1:手动拆分文本,逐个朗读单词并触发回调
这是最可靠的方式,直接把文本按空格拆分成单词列表,逐个调用Speech.speak,在每个单词朗读完成的onDone回调里执行你的自定义逻辑。
代码示例
import * as Speech from 'expo-speech'; const speakWithWordCallback = async (text, onWordFinished) => { // 按空格拆分单词(若有连续空格可用正则:text.split(/\s+/)) const words = text.trim().split(' '); for (const word of words) { await new Promise((resolve) => { Speech.speak(word, { language: 'en-US', pitch: 1, rate: 1, onDone: () => { // 执行自定义回调,传入当前完成的单词 onWordFinished(word); resolve(); }, }); }); // 可选:在单词间添加短暂停顿,模拟自然朗读节奏 await new Promise(resolve => setTimeout(resolve, 100)); } }; // 使用示例 speakWithWordCallback("Hey this is an interesting sentence", (word) => { console.log(`读完单词:${word}`); // 这里执行你的自定义逻辑,比如更新UI、统计数据等 });
优缺点
- ✅ 完全兼容Expo Go,跨平台行为一致
- ✅ 精准控制每个单词后的回调时机
- ❌ 单词间的停顿需要手动调整,可能和连贯朗读的自然节奏有差异(可通过调整停顿时间优化)
方案2:使用Expo兼容的替代TTS库
如果希望更贴近原生TTS的连贯朗读体验,同时获得更丰富的事件支持,可以考虑使用react-native-tts——不过注意这个库是原生模块,无法直接在Expo Go中使用,需要通过Expo Dev Client构建自定义客户端来运行。它支持更精细的 utterance 事件监听,包括单词级边界。
基本使用思路(需适配Expo Dev Client)
- 安装依赖:
npx expo install react-native-tts - 配置项目以支持原生模块(参考Expo官方文档关于Dev Client的说明)
- 监听单词边界事件:
import TTS from 'react-native-tts'; TTS.addEventListener('tts-start', (event) => console.log('开始朗读')); TTS.addEventListener('tts-finish', (event) => console.log('朗读结束')); TTS.addEventListener('tts-progress', (event) => { // 部分平台可通过event参数获取当前朗读的单词边界信息 console.log('当前进度:', event); }); TTS.speak("Hey this is an interesting sentence", { language: 'en-US', });
总结
如果你需要快速在Expo Go中实现需求,方案1是最优选择;如果追求更原生的朗读体验且愿意搭建Dev Client环境,可以尝试方案2。
内容的提问来源于stack exchange,提问作者smal
相关产品推荐
相关产品推荐

