当前位置: 首页 > article >正文

【微信小程序(云开发模式)变通实现DeepSeek支持语音】

整体架构

  1. 前端(微信小程序):
    • 使用微信小程序云开发能力,实现录音功能。
    • 将录音文件上传到云存储。
    • 调用云函数进行语音识别和 DeepSeek 处理。
    • 界面模仿 DeepSeek,支持文本编辑。
  2. 后端(云函数 + Node.js):
    • 使用云函数调用腾讯云语音识别(ASR)服务。
    • 调用 DeepSeek API 处理文本。

步骤 1:初始化云开发环境

  1. 在微信开发者工具中创建小程序项目,并开通云开发。

  2. project.config.json 中配置云函数目录:

    json

    复制

    {"cloudfunctionRoot": "cloud/functions/"
    }
    
  3. 初始化云开发环境:

    javascript

    复制

    wx.cloud.init({env: 'your-env-id', // 替换为你的云环境 IDtraceUser: 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: 腾讯云 SecretId
  • TENCENT_SECRET_KEY: 腾讯云 SecretKey
  • DEEPSEEK_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"><buttonbindtap="{{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><textareavalue="{{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><textareavalue="{{resultText}}"placeholder="处理结果将显示在这里"disabledclass="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:测试

  1. 在微信开发者工具中运行小程序。
  2. 测试录音、语音识别、文本编辑和 DeepSeek 处理功能。

注意事项

  1. 云函数部署:
    • 确保云函数已上传并部署。
  2. 环境变量:
    • 在云开发控制台中正确配置环境变量。
  3. 录音权限:
    • 确保小程序已获取录音权限。

相关文章:

【微信小程序(云开发模式)变通实现DeepSeek支持语音】

整体架构 前端&#xff08;微信小程序&#xff09;&#xff1a; 使用微信小程序云开发能力&#xff0c;实现录音功能。将录音文件上传到云存储。调用云函数进行语音识别和 DeepSeek 处理。界面模仿 DeepSeek&#xff0c;支持文本编辑。 后端&#xff08;云函数 Node.js&#…...

从WebRTC到嵌入式:EasyRTC如何借助大模型提升音视频通信体验

随着人工智能技术的快速发展&#xff0c;WebRTC与大模型的结合正在为音视频通信领域带来革命性的变革。WebRTC作为一种开源实时通信技术&#xff0c;以其低延迟、跨平台兼容性和强大的音视频处理能力&#xff0c;成为智能硬件和物联网设备的重要技术支撑。 而EasyRTC作为基于W…...

前端样式库推广——TailwindCss

官方网址&#xff1a; https://tailwindcss.com/docs/installation/using-vite 中文官方文档&#xff1a;https://www.tailwindcss.cn/ github地址&#xff1a;tailwindcss 正在使用tailwindcss的网站&#xff1a;https://tailwindcss.com/showcase 一看github&#xff0c;竟然…...

Gemini分析屏幕截图时,如何处理图像模态(如界面元素、文字内容)与文本模态(用户指令)的语义对齐?

在通过Gemini大语言模型进行屏幕截图分析时&#xff0c;实现图像模态&#xff08;界面元素/文字内容&#xff09;与文本模态&#xff08;用户指令&#xff09;的语义对齐&#xff0c;需要结合多模态融合技术和领域知识。以下是具体的技术实现路径和挑战应对方案&#xff1a; 1.…...

【6】组合计数学习笔记

前言 关于今天发现自己连快速幂都忘记怎么写这件事 这篇博客是组合计数基础&#xff0c;由于大部分内容都是 6 6 6 级&#xff0c;所以我就给整个提高级的组合数学评了 6 6 6 级。 组合计数基础 加法原理与乘法原理 加法原理&#xff08;分类计数原理&#xff09;&#…...

Ai客服机器人系统源码

我将基于常见的自然语言处理库&#xff0c;用 Python 编写一个简单的 AI 客服机器人功能代码示例&#xff0c;它能处理常见问题并根据用户输入提供相应回复。 import nltk​ from nltk.chat.util import Chat, reflections​ ​ # 下载必要的NLTK数据​ nltk.download(pun…...

Redis——事务实现以及应用场景

本文介绍Redis事务相关的原理以及知识点&#xff0c;从redis的常用命令出发&#xff0c;深入理解redis在日常工作中的实际场景使用用法。 本文目录 一、Redis事务简介二、事务相关命令三、事务应用场景 一、Redis事务简介 Redis 事务本质上是一个命令队列。用户可以使用MULTI命…...

SpringBoot 第二课(Ⅰ) 整合springmvc(详解)

目录 一、SpringBoot对静态资源的映射规则 1. WebJars 资源访问 2. 静态资源访问 3. 欢迎页配置 二、SpringBoot整合springmvc 概述 Spring MVC组件的自动配置 中央转发器&#xff08;DispatcherServlet&#xff09; 控制器&#xff08;Controller&#xff09; 视图解…...

Kafka 八股文

一、基础概念 1. Kafka 是什么&#xff1f;它的核心组件有哪些&#xff1f; Kafka 的定义 Kafka 是一个 分布式流处理平台&#xff0c;最初由 LinkedIn 开发&#xff0c;后成为 Apache 顶级项目。它主要用于 高吞吐量的实时数据流处理&#xff0c;支持发布-订阅模式的消息传递…...

OpenHarmony 开源鸿蒙北向开发——3.配置SDK

安装、配置完成之后我们就要配置SDK。 我们创建工程后&#xff0c;点击右上角设置 进入设置 进入OpenHarmony SDK&#xff0c;选择编辑 这里配置一下SDK安装位置 点击完成 这里我们API版本勾选第一个即可 确认安装 勾选接受 这里要等一会 安装完成后&#xff0c;点击完成...

电子工程师转战汽车OEM主机厂之路

文章目录 1 电子工程师2 汽车系统工程师 第一篇分享一个笔者2018年的一个心得文章&#xff0c;回头想想从事汽车行业也小8年了&#xff0c;从懵懂稚嫩到所谓的老油条&#xff0c;也是难忘的经历&#xff0c;希望我的经历对从事电子行业和汽车行业的小伙伴有所帮助。 1 电子工程…...

vulhub Matrix-Breakout

1.下载靶机&#xff0c;打开靶机和kali虚拟机 2.查询kali和靶机ip 3.浏览器访问 访问81端口有登陆界面 4.扫描敏感目录 kali dirb 扫描 一一访问 robot.txt提示我们继续找找&#xff0c;可能是因为我们的字典太小了&#xff0c;我们换个扫描器换个字典试下,利用kali自带的最大…...

Unity3D开发AI桌面精灵/宠物系列 【二】 语音唤醒 ivw 的两种方式-Windows本地或第三方讯飞等

Unity3D 交互式AI桌面宠物开发系列【二】ivw 语音唤醒 该系列主要介绍怎么制作AI桌面宠物的流程&#xff0c;我会从项目开始创建初期到最终可以和AI宠物进行交互为止&#xff0c;项目已经开发完成&#xff0c;我会仔细梳理一下流程&#xff0c;分步讲解。 这篇文章主要讲有关于…...

三月九次前端面试复盘:当场景题成为通关密钥

三月初集中面了包括字节、美团、滴滴在内的9家公司&#xff0c;经历7场技术面2场Leader面后&#xff0c;发现如今的面试逻辑已发生根本转变。这里分享真实经历与题目&#xff0c;供近期求职者参考。 一、面试形态变化&#xff1a;从理论背诵到实战推演 1. 八股文边缘化&#…...

STM32 —— 嵌入式系统、通用计算机系统、物联网三层架构

目录 一、嵌入式系统的概念 二、通用计算机系统与嵌入式系统的比较 用途 硬件 软件 性能与功耗 开发与维护 三、嵌入式系统与物联网的关系 四、物联网的三层架构 1. 感知层&#xff08;Perception Layer&#xff09; 2. 网络层&#xff08;Network Layer&#xff09; …...

如何选择合适的 AI 模型?(开源 vs 商业 API,应用场景分析)

1. 引言 在 AI 迅猛发展的今天&#xff0c;各类 AI 模型层出不穷&#xff0c;从开源模型&#xff08;如 DeepSeek、Llama、Qwen&#xff09;到商业 API&#xff08;如 OpenAI 的 ChatGPT、Anthropic 的 Claude、Google Gemini&#xff09;&#xff0c;每种方案都有其优势与适用…...

视频对讲系统中,强插和强拆;视频分发功能

强插和强拆 在视频对讲系统中&#xff0c;强插和强拆是两个具有特定功能的操作&#xff0c;具体含义如下&#xff1a; 强插功能&#xff1a;指在视频对讲过程中&#xff0c;具有更高权限的用户或管理员可以强行插入正在进行的通话或视频连接。例如&#xff0c;当小区保安室监控…...

C++输入输出流第一弹:标准输入输出流 详解(带测试代码)

目录 C输入输出流 流的四种状态&#xff08;重点&#xff09; 标准输入输出流 标准输入流 逗号表达式 1. 逗号表达式的基本规则 示例 2. 图片中的代码分析 关键点解析 3. 常见误区 误区 1&#xff1a;逗号表达式等同于逻辑与 && 误区 2&#xff1a;忽略输入…...

{瞎掰} 手机安装app问题:app签名,手机 or OS官方商店 其他非官方app源,安全防护 突破限制

以下&#xff0c;在华为安卓系统手机中&#xff0c;在安装app过程中得到的一些可能是错误的经验。 商品化 app 的收钱方式&#xff1a;通过商店来收钱&#xff0c;通过 app 本身提供的注册码功能来收钱&#xff0c;或是其他的收钱方式。 手机安装 app的特点 从官方商店里安装…...

鸿蒙NEXT项目实战-百得知识库05

代码仓地址&#xff0c;大家记得点个star IbestKnowTeach: 百得知识库基于鸿蒙NEXT稳定版实现的一款企业级开发项目案例。 本案例涉及到多个鸿蒙相关技术知识点&#xff1a; 1、布局 2、配置文件 3、组件的封装和使用 4、路由的使用 5、请求响应拦截器的封装 6、位置服务 7、三…...

记录一次,rabbitmq开启stomp插件之后,还是连不上15674端口的问题

原因是装在docker 里面的rabbitmq 没有映射15674端口&#xff0c;需重新删除容器之后重新运行 docker run -d --name rabbitmq -p 5672:5672 -p 15672:15672 -p 15674:15674 -p 1883:1883 -p 15675:15675 rabbitmq:版本号 进入docker容器开启插件 docker exec -it rabbitm…...

黑马node.js教程(nodejs教程)——AJAX-Day01-04.案例_地区查询——查询某个省某个城市所有地区(代码示例)

文章目录 代码示例效果 代码示例 axiosTest.html <!DOCTYPE html> <!-- 文档类型声明&#xff0c;告诉浏览器这是一个HTML5文档 --> <html lang"en"> <!-- HTML根元素&#xff0c;设置文档语言为英语 --><head> <!-- 头部区域&am…...

vue 自制列表,循环滚动

需求人员表示&#xff0c;超过高度的表格内容需要滚动展示&#xff0c;所以效果图如下&#xff1a; 自定义列表样式&#xff0c;主要是通过flex布局&#xff0c;控制 类th 与 类td 的宽度保持一致&#xff0c;标签结构还是参考了table的结构&#xff0c;由thead与tbody包裹tr再…...

【QA】模板方法模式在Qt中有哪些应用?

在 Qt 框架中&#xff0c;模板方法模式&#xff08;Template Method Pattern&#xff09;被广泛应用于框架的设计中&#xff0c;通过定义算法骨架并允许子类在不改变结构的情况下重写部分步骤。以下是 Qt 中典型的应用场景及示例&#xff1a; 1. 事件处理&#xff08;Event Ha…...

图论——kruskal算法

53. 寻宝(第七期模拟笔试) 题目描述 在世界的某个区域,有一些分散的神秘岛屿,每个岛屿上都有一种珍稀的资源或者宝藏。国王打算在这些岛屿上建公路,方便运输。 不同岛屿之间,路途距离不同,国王希望你可以规划建公路的方案,如何可以以最短的总公路距离将 所有岛屿联通…...

Windows主机、虚拟机Ubuntu、开发板,三者之间文件互传

以下内容源于日常学习的整理&#xff0c;欢迎交流。 下图是Windows主机、虚拟机Ubuntu、开发者三者之间文件互传的方式示意图&#xff1a; 注意&#xff0c;下面谈及的所有方式&#xff0c;都要求两者的IP地址处于同一网段&#xff0c;涉及到的软件资源见felm。 一、Windows主…...

Flutter Dart 泛型详解

引言 在 Flutter 开发中&#xff0c;Dart 语言的泛型是一项强大且实用的特性。泛型允许我们在定义类、方法或接口时使用类型参数&#xff0c;这样可以编写更加灵活、可复用且类型安全的代码。下面将详细介绍 Dart 泛型的各个方面&#xff0c;并结合代码示例进行说明。 1. 泛型…...

Windows Docker 报错: has no HTTPS proxy,换源

pull python 3.7报错&#xff1a; 尝试拉取Docker 测试库hello world也失败 尝试使用临时镜像源&#xff0c;可以成功拉取&#xff1a; sudo docker pull docker.m.daocloud.io/hello-world说明确实是网络问题&#xff0c;需要配置镜像源&#xff0c;为了方便&#xff0c;在d…...

Java:Arrays类:操作数组的工具类

文章目录 Arrays类常见方法SetAll(); 代码排序如果数组中存储的是自定义对象 Arrays类 常见方法 SetAll(); 注意&#xff1a; 不能用新的数组接是因为修改的是原数组&#xff0c;所以完了要输出原数组发现会产生变化参数是数组下标变成灰色是因为还能简化&#xff08;Lambda…...

【面试场景题-Redis中String类型和map类型的区别】

今天在面试中碰到一个场景题&#xff1a;在 Redis 中存储 100 万用户数据时&#xff0c;使用 String 类型和 Hash&#xff08;Map&#xff09;类型的主要区别是什么&#xff1f;体现在以下几个方面&#xff1a; 1. 存储结构与内存占用 String 类型 存储方式&#xff1a;每个用…...