237 lines
5.5 KiB
Markdown
237 lines
5.5 KiB
Markdown
# 语音模型运行时下载方案
|
||
|
||
## ❌ **问题**
|
||
|
||
语音模型文件 `vosk-model-small-cn-0.22.zip` 大小为 **41.87 MB**,超过云端打包限制(40MB)。
|
||
|
||
---
|
||
|
||
## ✅ **解决方案:运行时下载**
|
||
|
||
### **原理**
|
||
|
||
1. 打包时**不包含**模型文件(减小 APK 大小)
|
||
2. 首次启动时从服务器下载模型
|
||
3. 下载后保存到本地存储
|
||
4. 后续使用本地模型
|
||
|
||
---
|
||
|
||
## 📝 **实施步骤**
|
||
|
||
### **步骤1:从 static 目录移除模型文件**
|
||
|
||
**方法A:移动到服务器(推荐)**
|
||
|
||
```bash
|
||
# 将模型文件上传到您的服务器
|
||
# 例如:https://app.liuyingyong.cn/static/vosk-model-small-cn-0.22.zip
|
||
```
|
||
|
||
**方法B:移动到项目外(临时)**
|
||
|
||
```bash
|
||
# 将文件移动到桌面备份
|
||
# fronted_uniapp/static/vosk-model-small-cn-0.22.zip
|
||
# → 桌面/vosk-model-backup/
|
||
```
|
||
|
||
---
|
||
|
||
### **步骤2:修改语音识别页面,添加模型下载逻辑**
|
||
|
||
在 `pages/speech/speech.vue` 中添加:
|
||
|
||
```vue
|
||
<script>
|
||
export default {
|
||
data() {
|
||
return {
|
||
modelDownloaded: false,
|
||
downloadProgress: 0,
|
||
// 模型文件URL(改为您的服务器地址)
|
||
modelUrl: 'https://app.liuyingyong.cn/static/vosk-model-small-cn-0.22.zip',
|
||
// 本地存储路径
|
||
modelPath: ''
|
||
}
|
||
},
|
||
|
||
onLoad() {
|
||
this.checkAndDownloadModel();
|
||
},
|
||
|
||
methods: {
|
||
// 检查并下载模型
|
||
async checkAndDownloadModel() {
|
||
try {
|
||
// 检查本地是否已有模型
|
||
const localPath = plus.io.convertLocalFileSystemURL('_doc/vosk-model-small-cn-0.22.zip');
|
||
const file = plus.io.resolveLocalFileSystemURL(localPath);
|
||
|
||
file.getFile({
|
||
success: (entry) => {
|
||
console.log('模型文件已存在');
|
||
this.modelPath = localPath;
|
||
this.modelDownloaded = true;
|
||
},
|
||
fail: () => {
|
||
console.log('模型文件不存在,开始下载');
|
||
this.downloadModel();
|
||
}
|
||
});
|
||
} catch (e) {
|
||
console.log('检查模型失败,开始下载', e);
|
||
this.downloadModel();
|
||
}
|
||
},
|
||
|
||
// 下载模型
|
||
downloadModel() {
|
||
uni.showLoading({
|
||
title: '下载语音模型...',
|
||
mask: true
|
||
});
|
||
|
||
const downloadTask = uni.downloadFile({
|
||
url: this.modelUrl,
|
||
filePath: plus.io.convertLocalFileSystemURL('_doc/vosk-model-small-cn-0.22.zip'),
|
||
success: (res) => {
|
||
if (res.statusCode === 200) {
|
||
console.log('模型下载成功', res.tempFilePath);
|
||
this.modelPath = res.tempFilePath;
|
||
this.modelDownloaded = true;
|
||
|
||
uni.hideLoading();
|
||
uni.showToast({
|
||
title: '模型下载完成',
|
||
icon: 'success'
|
||
});
|
||
}
|
||
},
|
||
fail: (err) => {
|
||
console.error('模型下载失败', err);
|
||
uni.hideLoading();
|
||
uni.showModal({
|
||
title: '下载失败',
|
||
content: '语音模型下载失败,请检查网络后重试',
|
||
confirmText: '重试',
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.downloadModel();
|
||
}
|
||
}
|
||
});
|
||
}
|
||
});
|
||
|
||
// 监听下载进度
|
||
downloadTask.onProgressUpdate((res) => {
|
||
this.downloadProgress = res.progress;
|
||
console.log('下载进度', res.progress + '%');
|
||
});
|
||
},
|
||
|
||
// 修改原来的语音识别方法
|
||
startRecognition() {
|
||
if (!this.modelDownloaded) {
|
||
uni.showToast({
|
||
title: '模型未下载',
|
||
icon: 'none'
|
||
});
|
||
return;
|
||
}
|
||
|
||
// 原来的语音识别代码
|
||
// ...
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<template>
|
||
<view>
|
||
<!-- 下载进度显示 -->
|
||
<view v-if="!modelDownloaded" class="download-container">
|
||
<text>正在下载语音模型...</text>
|
||
<progress :percent="downloadProgress" show-info />
|
||
</view>
|
||
|
||
<!-- 原来的语音识别界面 -->
|
||
<view v-else>
|
||
<!-- ... -->
|
||
</view>
|
||
</view>
|
||
</template>
|
||
```
|
||
|
||
---
|
||
|
||
### **步骤3:更新插件代码,支持动态模型路径**
|
||
|
||
如果插件硬编码了模型路径,需要修改为接受外部传入的路径。
|
||
|
||
---
|
||
|
||
## 🎯 **优点**
|
||
|
||
- ✅ APK 大小减少 42MB
|
||
- ✅ 可以随时更新模型而不用重新打包
|
||
- ✅ 可以支持多个模型按需下载
|
||
- ✅ 用户可以选择下载时机(WiFi环境)
|
||
|
||
---
|
||
|
||
## ⚠️ **注意事项**
|
||
|
||
1. **服务器要求**
|
||
- 需要有可访问的服务器存放模型文件
|
||
- 建议使用 CDN 加速下载
|
||
- 确保服务器支持大文件下载
|
||
|
||
2. **首次使用体验**
|
||
- 首次使用需要下载 42MB
|
||
- 建议在 WiFi 环境下载
|
||
- 提供下载进度提示
|
||
|
||
3. **存储权限**
|
||
- 确保 APP 有存储权限
|
||
- 检查存储空间是否足够
|
||
|
||
---
|
||
|
||
## 📊 **效果对比**
|
||
|
||
| 项目 | 打包方案 | 运行时下载 |
|
||
|------|---------|-----------|
|
||
| APK大小 | ~100MB | ~58MB ✅ |
|
||
| 首次启动 | 即可使用 | 需下载 42MB |
|
||
| 更新模型 | 需重新打包 | 直接更新 ✅ |
|
||
| 灵活性 | 低 | 高 ✅ |
|
||
|
||
---
|
||
|
||
## 🚀 **快速实施**
|
||
|
||
如果现在着急打包,可以先:
|
||
|
||
1. **临时移除模型文件**
|
||
```
|
||
移动 fronted_uniapp/static/vosk-model-small-cn-0.22.zip
|
||
到桌面备份
|
||
```
|
||
|
||
2. **注释掉语音功能**
|
||
```vue
|
||
<!-- 暂时隐藏语音按钮 -->
|
||
<view v-if="false">
|
||
语音识别按钮
|
||
</view>
|
||
```
|
||
|
||
3. **先完成打包**
|
||
|
||
4. **之后再实施完整的运行时下载方案**
|
||
|
||
---
|
||
|