在Android中调用CMU Sphinx4时遇means文件未找到异常问题
我之前帮好几个开发者排查过Sphinx4在Android上的这个问题,means文件缺失通常不是模型本身的问题,而是咱们在项目配置或代码路径上踩了坑,下面是最常见的几个解决方案:
先确认声学模型包是完整的
首先别着急改代码,先检查你下载的CMU Sphinx声学模型(比如常用的en-us模型)是不是完整的——打开模型文件夹,里面必须有means、variances、transition_matrices这些核心文件。如果是下载时解压漏了,重新下载完整的模型包再试。把模型放到正确的assets目录,禁用Gradle压缩
把整个模型文件夹(比如en-us)直接放到项目的src/main/assets目录下,别嵌套多余的层级。然后关键的一步:Android默认会压缩assets里的二进制文件,这会导致Sphinx4读不到means这类文件。你需要在app模块的build.gradle里添加规则,不让Gradle压缩这些模型相关文件:
如果你用的是Groovy版的build.gradle:android { // ...其他已有的配置 aaptOptions { noCompress "3gpp", "amr", "bin", "cmu", "dic", "lm", "means", "mfcc", "mp3", "properties", "slm", "variances" } }要是用Kotlin DSL的话:
android { // ...其他已有的配置 aaptOptions { listOf("3gpp", "amr", "bin", "cmu", "dic", "lm", "means", "mfcc", "mp3", "properties", "slm", "variances").forEach { noCompress.add(it) } } }配置完后clean一下项目再重新构建。
修正代码里的模型路径写法
在Android中调用Sphinx4时,访问assets里的模型要使用正确的URI格式,别用普通的文件路径。正确的写法应该是这样:Configuration config = new Configuration(); // 注意是asset:///开头,后面跟assets里的模型文件夹名 config.setAcousticModelPath("asset:///en-us/"); // 接着设置字典、语言模型等其他路径 config.setDictionaryPath("asset:///en-us/cmudict-en-us.dict");之前很多人用
file:///android_asset/的写法,反而容易出问题,换成asset:///更稳妥。如果用外部存储的模型,记得申请权限
要是你把模型放在SD卡等外部存储里,别忘了在AndroidManifest.xml里加读取权限:<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />而且Android 6.0及以上版本需要在运行时动态请求这个权限,不然会因为权限不足读不到文件,看起来像是文件缺失。
先按这几步排查,大概率能解决means文件找不到的问题。
内容的提问来源于stack exchange,提问作者Roma Jain

