简介:本文详细介绍在uniapp开发安卓APP时集成文字转语音功能的实现方法,包括原生API调用、第三方插件使用及性能优化技巧。
文字转语音(Text-to-Speech, TTS)技术通过将文本内容转换为自然流畅的语音输出,在移动应用开发中广泛应用于无障碍阅读、语音导航、有声内容生成等场景。uniapp作为跨平台开发框架,在安卓端实现TTS功能需考虑平台特性与兼容性。
安卓系统原生提供TextToSpeech类,该类封装了语音合成引擎的核心功能,支持多语言、多音调设置及事件回调机制。uniapp通过plus.android.runtimeMainActivity()获取安卓上下文后,可直接调用原生API。相较于WebView方案,原生API具有更低的延迟和更高的语音质量,尤其适合需要实时交互的场景。
// 初始化TTS引擎function initTTS() {const main = plus.android.runtimeMainActivity();const TTS = plus.android.importClass('android.speech.tts.TextToSpeech');const Context = plus.android.importClass('android.content.Context');this.tts = new TTS(main,new TTS.OnInitListener({onInit: function(status) {if (status === TTS.SUCCESS) {const result = this.tts.setLanguage(plus.android.invoke('java.util.Locale', 'US'));if (result === TTS.LANG_MISSING_DATA || result === TTS.LANG_NOT_SUPPORTED) {console.log('语言包未安装');}}}}),null);}// 语音合成function speak(text) {if (this.tts) {this.tts.speak(text, TTS.QUEUE_FLUSH, null, null);}}
关键参数说明:
QUEUE_FLUSH:立即停止当前语音并播放新内容QUEUE_ADD:将新内容添加到播放队列末尾setPitch(float pitch)设置,1.0为默认值setSpeechRate(float rate)设置,1.0为默认值
// 获取可用语音引擎列表function getAvailableEngines() {const pm = plus.android.invoke(plus.android.runtimeMainActivity().getPackageManager(),'getInstalledApplications',0);const engines = [];const len = pm.size();for (let i = 0; i < len; i++) {const appInfo = pm.get(i);if (appInfo.packageName.includes('tts')) {engines.push(appInfo.packageName);}}return engines;}
// 设置语音播放完成回调function setOnUtteranceCompletedListener() {const UtteranceProgressListener = plus.android.importClass('android.speech.tts.UtteranceProgressListener');const listener = new UtteranceProgressListener({onStart: function(utteranceId) { console.log('播放开始'); },onDone: function(utteranceId) { console.log('播放完成'); },onError: function(utteranceId) { console.log('播放错误'); }});this.tts.setOnUtteranceProgressListener(listener);}
优势:
cordova.plugins.tts.speak('文本')局限:
实现示例:
// 安装插件后const tts = uni.requireNativePlugin('uni-tts');tts.speak({text: '欢迎使用uniapp',lang: 'zh-CN',pitch: 1.2,rate: 0.8}, res => {console.log(res.code); // 0表示成功});
性能对比:
| 指标 | 原生API | cordova-plugin-tts | uni-tts |
|———————|————-|——————————|————-|
| 初始化耗时 | 200ms | 350ms | 280ms |
| 内存占用 | 12MB | 18MB | 15MB |
| 语音流畅度 | ★★★★★ | ★★★★ | ★★★★☆ |
// 应用启动时初始化TTSapp.onLaunch = function() {setTimeout(() => {initTTS();// 预加载常用语音preloadVoices(['欢迎使用', '操作成功', '网络错误']);}, 1000);};function preloadVoices(texts) {texts.forEach(text => {if (this.tts) this.tts.synthesizeToFile(text, null, 'sdcard/tts_cache/' + md5(text) + '.wav');});}
/sdcard/Android/data/[package_name]/cache/tts/
// 语音合成错误处理function safeSpeak(text) {try {if (!this.tts) throw new Error('TTS未初始化');const result = this.tts.isLanguageAvailable(plus.android.invoke('java.util.Locale', 'ZH'));if (result === TTS.LANG_NOT_SUPPORTED) {downloadLanguagePack('zh-CN');return;}this.tts.speak(text, TTS.QUEUE_FLUSH, null, 'unique_id');} catch (e) {console.error('TTS错误:', e.message);showFallbackUI();}}
// 监听文本变化自动朗读function setupAccessibilityMode() {const observer = new MutationObserver(mutations => {mutations.forEach(mutation => {if (mutation.type === 'childList') {const text = getVisibleText();if (text.length > 10) safeSpeak(text);}});});observer.observe(document.body, {childList: true,subtree: true,characterData: true});}
// 方向提示语音合成function navigate(direction) {const directions = {'left': '请向左转弯','right': '请向右转弯','straight': '请直行'};const params = {text: directions[direction],lang: 'zh-CN',interrupt: true // 立即中断当前语音};uni.requireNativePlugin('uni-tts').speak(params);}
现象:setLanguage()返回LANG_MISSING_DATA
解决方案:
// 跳转系统TTS设置界面function openTTSSettings() {const Intent = plus.android.importClass('android.content.Intent');const Settings = plus.android.importClass('android.provider.Settings');const intent = new Intent(Settings.ACTION_VOICE_INPUT_SETTINGS);plus.android.runtimeMainActivity().startActivity(intent);}
必需权限:
<!-- manifest.json中配置 -->"permissions": [{"name": "android.permission.INTERNET","reason": "语音数据下载"},{"name": "android.permission.WRITE_EXTERNAL_STORAGE","reason": "语音缓存存储"}]
// 语言代码映射表const LANG_CODES = {'zh-CN': plus.android.invoke('java.util.Locale', 'CHINA'),'en-US': plus.android.invoke('java.util.Locale', 'US'),'ja-JP': plus.android.invoke('java.util.Locale', 'JAPAN')};// 动态切换语言function setTTSLanguage(langCode) {if (LANG_CODES[langCode]) {const result = this.tts.setLanguage(LANG_CODES[langCode]);if (result === TTS.LANG_NOT_SUPPORTED) {downloadLanguagePack(langCode);}}}
建议开发者持续关注安卓TextToSpeech.Engine类的版本更新,特别是Android 12引入的OnDeviceTTS特性,可显著减少网络依赖。对于商业项目,可考虑集成专业语音合成SDK(如科大讯飞、捷通华声)以获得更丰富的音色选择。