整体架构
- 前端(微信小程序):
- 使用微信小程序云开发能力,实现录音功能。
- 将录音文件上传到云存储。
- 调用云函数进行语音识别和 DeepSeek 处理。
- 界面模仿 DeepSeek,支持文本编辑。
- 后端(云函数 + Node.js):
- 使用云函数调用腾讯云语音识别(ASR)服务。
- 调用 DeepSeek API 处理文本。
步骤 1:初始化云开发环境
在微信开发者工具中创建小程序项目,并开通云开发。
在
project.config.json
中配置云函数目录:json
复制
{ "cloudfunctionRoot": "cloud/functions/" }
初始化云开发环境:
javascript
复制
wx.cloud.init({ env: 'your-env-id', // 替换为你的云环境 ID traceUser: true });
步骤 2:编写云函数
1. 云函数结构
复制
cloud/
├── functions/
│ ├── asr/ # 语音识别云函数
│ │ ├── index.js
│ │ ├── config.json
│ │ └── package.json
│ ├── deepseek/ # DeepSeek 处理云函数
│ │ ├── index.js
│ │ ├── config.json
│ │ └── package.json
2. 语音识别云函数 (asr/index.js
)
javascript
复制
const tencentcloud = require('tencentcloud-sdk-nodejs');
const AsrClient = tencentcloud.asr.v20190614.Client;
const fs = require('fs');
const path = require('path');
exports.main = async (event, context) => {
const { fileID } = event;
// 下载录音文件
const fileContent = await wx.cloud.downloadFile({
fileID: fileID
});
const audioPath = fileContent.tempFilePath;
const audioData = fs.readFileSync(audioPath, { encoding: 'base64' });
// 调用腾讯云语音识别
const client = new AsrClient({
credential: {
secretId: process.env.TENCENT_SECRET_ID, // 从环境变量获取
secretKey: process.env.TENCENT_SECRET_KEY
},
region: 'ap-guangzhou',
profile: {
httpProfile: {
endpoint: 'asr.tencentcloudapi.com'
}
}
});
const params = {
EngineModelType: '16k_zh',
VoiceFormat: 'wav',
Data: audioData
};
try {
const response = await client.SentenceRecognition(params);
return {
success: true,
data: response.Result
};
} catch (error) {
return {
success: false,
message: error.message
};
}
};
3. DeepSeek 处理云函数 (deepseek/index.js
)
javascript
复制
const axios = require('axios');
exports.main = async (event, context) => {
const { text } = event;
try {
const response = await axios.post(
'https://api.deepseek.com/v1/chat/completions',
{
model: 'deepseek-chat',
messages: [
{ role: 'system', content: '你是一个文本处理助手。' },
{ role: 'user', content: text }
]
},
{
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${process.env.DEEPSEEK_API_KEY}` // 从环境变量获取
}
}
);
return {
success: true,
data: response.data.choices[0].message.content
};
} catch (error) {
return {
success: false,
message: error.message
};
}
};
4. 安装依赖
在云函数目录下运行:
bash
复制
npm install tencentcloud-sdk-nodejs axios
5. 配置环境变量
在云开发控制台中,为云函数配置环境变量:
TENCENT_SECRET_ID
: 腾讯云 SecretIdTENCENT_SECRET_KEY
: 腾讯云 SecretKeyDEEPSEEK_API_KEY
: DeepSeek API 密钥
步骤 3:编写小程序前端
1. 页面结构
复制
miniprogram/
├── pages/
│ ├── index/
│ │ ├── index.js # 页面逻辑
│ │ ├── index.wxml # 页面结构
│ │ └── index.wxss # 页面样式
├── app.js # 小程序逻辑
├── app.json # 小程序配置
└── app.wxss # 全局样式
2. 页面逻辑 (index.js
)
javascript
复制
Page({
data: {
isRecording: false, // 是否正在录音
recordTime: 0, // 录音时长
resultText: '', // 识别结果
editedText: '', // 编辑后的文本
isLoading: false // 加载状态
},
// 开始录音
startRecord() {
this.setData({ isRecording: true, recordTime: 0 });
this.recorderManager = wx.getRecorderManager();
this.recorderManager.start({
format: 'wav',
sampleRate: 16000,
numberOfChannels: 1,
encodeBitRate: 48000
});
this.timer = setInterval(() => {
this.setData({ recordTime: this.data.recordTime + 1 });
}, 1000);
this.recorderManager.onStop(async (res) => {
clearInterval(this.timer);
this.setData({ isRecording: false });
await this.uploadAudio(res.tempFilePath); // 上传录音文件
});
},
// 停止录音
stopRecord() {
if (this.recorderManager) {
this.recorderManager.stop();
}
},
// 上传录音文件
async uploadAudio(filePath) {
this.setData({ isLoading: true });
try {
// 上传到云存储
const uploadRes = await wx.cloud.uploadFile({
cloudPath: `audios/${Date.now()}.wav`,
filePath: filePath
});
// 调用语音识别云函数
const asrRes = await wx.cloud.callFunction({
name: 'asr',
data: { fileID: uploadRes.fileID }
});
if (asrRes.result.success) {
this.setData({ resultText: asrRes.result.data, editedText: asrRes.result.data });
} else {
wx.showToast({ title: '识别失败', icon: 'none' });
}
} catch (error) {
wx.showToast({ title: '上传失败', icon: 'none' });
} finally {
this.setData({ isLoading: false });
}
},
// 编辑文本
handleEditText(e) {
this.setData({ editedText: e.detail.value });
},
// 调用 DeepSeek 处理文本
async processText() {
const { editedText } = this.data;
if (!editedText) {
wx.showToast({ title: '请输入文本', icon: 'none' });
return;
}
this.setData({ isLoading: true });
try {
const deepseekRes = await wx.cloud.callFunction({
name: 'deepseek',
data: { text: editedText }
});
if (deepseekRes.result.success) {
this.setData({ resultText: deepseekRes.result.data });
} else {
wx.showToast({ title: '处理失败', icon: 'none' });
}
} catch (error) {
wx.showToast({ title: '网络错误', icon: 'none' });
} finally {
this.setData({ isLoading: false });
}
}
});
3. 页面结构 (index.wxml
)
xml
复制
<view class="container">
<!-- 录音按钮 -->
<view class="record-button">
<button
bindtap="{{isRecording ? 'stopRecord' : 'startRecord'}}"
class="{{isRecording ? 'stop-button' : 'start-button'}}"
>
{{isRecording ? '停止录音' : '开始录音'}}
</button>
<text class="record-time" wx:if="{{isRecording}}">录音中:{{recordTime}}s</text>
</view>
<!-- 识别结果 -->
<view class="result-box">
<text class="result-title">识别结果:</text>
<textarea
value="{{editedText}}"
bindinput="handleEditText"
placeholder="识别结果将显示在这里"
class="result-text"
></textarea>
</view>
<!-- 处理按钮 -->
<button bindtap="processText" class="process-button">调用 DeepSeek 处理</button>
<!-- 处理结果 -->
<view class="result-box">
<text class="result-title">处理结果:</text>
<textarea
value="{{resultText}}"
placeholder="处理结果将显示在这里"
disabled
class="result-text"
></textarea>
</view>
<!-- 加载状态 -->
<view class="loading" wx:if="{{isLoading}}">
<text>处理中...</text>
</view>
</view>
运行 HTML
4. 页面样式 (index.wxss
)
css
复制
.container {
padding: 20px;
background-color: #F5F5F5;
min-height: 100vh;
}
.record-button {
display: flex;
flex-direction: column;
align-items: center;
margin-bottom: 20px;
}
.start-button {
background-color: #07C160;
color: white;
width: 80%;
}
.stop-button {
background-color: #F5222D;
color: white;
width: 80%;
}
.record-time {
margin-top: 10px;
font-size: 14px;
color: #666666;
}
.result-box {
width: 100%;
margin-top: 20px;
}
.result-title {
font-size: 16px;
font-weight: bold;
color: #333333;
margin-bottom: 10px;
}
.result-text {
width: 100%;
height: 100px;
background-color: #FFFFFF;
border: 1px solid #CCCCCC;
border-radius: 5px;
padding: 10px;
font-size: 14px;
color: #333333;
}
.process-button {
margin-top: 20px;
background-color: #1890FF;
color: white;
width: 80%;
}
.loading {
margin-top: 20px;
font-size: 14px;
color: #666666;
text-align: center;
}
步骤 4:测试
- 在微信开发者工具中运行小程序。
- 测试录音、语音识别、文本编辑和 DeepSeek 处理功能。
注意事项
- 云函数部署:
- 确保云函数已上传并部署。
- 环境变量:
- 在云开发控制台中正确配置环境变量。
- 录音权限:
- 确保小程序已获取录音权限。