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

AI 音频产品开发模板及流程(一)

1. 准备工作

前提条件

  • 已阅读 Ray 新手村任务,了解 Ray 框架的基础知识。
  • 已阅读 使用 Ray 开发万能面板,了解 Ray 面板开发的基础知识。

构建内容

您可以利用面板小程序开发构建出一个基于 Ray 框架的 AI 音频设备面板,并实现以下功能:

  • 面对面翻译:选择好需要互转的语言,使用不同语言的双方对话时,App 会自动断句并转写、翻译,设备自动播放翻译结果。
  • 同声传译:设置输入语言和翻译语言,点击开始后 App 会自动进行断句,转写文字并进行翻译。
  • 现场录音:将耳机等拾音设备放置在桌面上,点击开始录音,就会自动录下现场声音,结束后可以进行转写和 AI 总结。
  • 转录和 AI 总结:将音频内容转换为文字,AI 根据模板总结内容,并生成 Markdown 格式文本。

所需条件

  • 智能生活 App
  • Tuya MiniApp IDE
  • NVM 及 Node 开发环境(建议使用 18.x 系列版本)
  • Yarn 依赖管理工具

详见 面板小程序 > 搭建环境。

2. 创建产品

首先需要创建一个产品,定义产品有哪些功能点,然后再在面板中一一实现这些功能点。

注册登录 涂鸦开发者平台,并在平台创建产品:

  1. 单击页面左侧 产品 > 产品开发,在 产品开发 页面单击 创建产品

  1. 在 标准类目 下选择 影音穿戴 > AI 耳机

  1. 选择 智能化方式 和 产品方案,完善产品信息,单击 创建产品

  1. 在 添加标准功能 页面,根据实际需求选择对应的功能点,单击 确定

🎉 完成以上步骤后,您已成功创建了一个支持 AI 音频实时、离线转录的设备产品。

3. 创建项目

开发者平台创建面板小程序

面板小程序的开发在 小程序开发者 平台上进行操作,首先请前往 小程序开发者平台 完成平台的注册登录。

IDE 基于模板创建项目工程

打开 IDE 创建一个基于 AI 耳机模版 的 AI 音频面板小程序项目,需要在 Tuya MiniApp IDE 上进行操作。

4. 关键能力依赖

  • App 版本
    • 智能生活 v6.3.0 及以上版本
  • Kit 依赖
    • BaseKit:v3.0.6
    • MiniKit:v3.0.1
    • DeviceKit:v4.14.0
    • BizKit:v4.2.0
    • WearKit:v1.1.6
    • baseversion:v2.27.0
  • 组件依赖
    • @ray-js/ray^1.7.14

5. 面对面翻译

  • 实现现场跨语言交流,打破语言壁垒,让不同语言用户可以顺畅沟通。
  • 自动断句、转写和翻译,提高交流效率。
  • 翻译结果可由设备自动播放,沟通体验更自然。
  • 支持多语言互转,适用场景广泛,提升产品智能化和国际化能力。

功能展示

代码片段

  // 开始录音const handleStartRecord = useCallback((type: 'left' | 'right') => {const startRecordFn = async (type: 'left' | 'right') => {// 需要设备在线if (!isOnline) return;try {showLoading({ title: '' });const config: any = {// 录音类型,0:呼叫、1:会议、2:同声传译、3:面对面翻译recordType: 3,// DP 控制超时时间,单位秒controlTimeout: 5,// 灌流超时时间,单位秒dataTimeout: 10,// 0:文件转写、1:实时转写transferType: 1,// 是否需要翻译needTranslate: true,// 输入语言originalLanguage: type === 'left' ? leftLanguage : rightLanguage,// 输出语言targetLanguage: type === 'left' ? rightLanguage : leftLanguage,// 智能体 ID,后面具体根据提供的 SDK 获取 agentId。agentId: '',// 录音通道,0:BLE、1:Bt、2:microrecordChannel: isCardStyle || isDevOnline === false ? 2 : 1,// 0:代表左耳、1:代表右耳f2fChannel: type === 'left' ? 0 : 1,// TTS 流编码方式,通过编码后将流写入到耳机设备,0:opus_silk、1:opus_celtttsEncode: isOpusCelt ? 1 : 0,// 是否需要 TTSneedTts: true,};await tttStartRecord({deviceId,config,},true);setActiveType(type);hideLoading();setIntervals(1000);lastTimeRef.current = Date.now();} catch (error) {ty.showToast({title: Strings.getLang('error_simultaneous_recording_start'),icon: 'error',});hideLoading();}};ty.authorize({scope: 'scope.record',success: () => {startRecordFn(type);},fail: e => {ty.showToast({ title: Strings.getLang('no_record_permisson'), icon: 'error' });},});},[deviceId, isOnline, rightLanguage, leftLanguage]);
  // 暂停const handlePauseRecord = async () => {try {const d = await tttPauseRecord(deviceId);setActiveType('');console.log('pauseRecord', d);setIntervals(undefined);} catch (error) {console.log('handlePauseRecord fail', error);}};
  // 继续录音const handleResumeRecord = async () => {if (!isOnline) return;try {const d = await tttResumeRecord(deviceId);setIntervals(1000);lastTimeRef.current = Date.now();} catch (error) {console.log('handleResumeRecord fail', error);}};
  // 停止录音const handleStopRecord = async () => {try {showLoading({ title: '' });const d = await tttStopRecord(deviceId);hideLoading();console.log('stopRecord', d);backToHome(fromType);} catch (error) {hideLoading();}};
  // 监听 ASR 和翻译返回onRecordTransferRealTimeRecognizeStatusUpdateEvent(handleRecrodChange);// 处理 ASR 和翻译const handleRecrodChange = d => {try {const {// 阶段,0:任务、4:ASR、5:翻译、6:skill、7:TTSphase,// 阶段状态,0:未开启、1:进行中、2:结束、3:取消status,requestId,// 转写的文本text,// 错误码errorCode,} = d;// ASR 阶段接收并实时更新对应 requestId 文本if (phase === 4) {const currTextItemIdx = currTextListRef.current.findIndex(item => item.id === requestId);if (currTextItemIdx > -1) {const newList = currTextListRef.current.map(item =>item.id === requestId ? { ...item, text } : item);currTextListRef.current = newList;setTextList(newList);} else {if (!text) return;const newList = [...currTextListRef.current,{id: requestId,text,},];currTextListRef.current = newList;setTextList(newList);}// 翻译返回阶段,接收并展示 status=2 即已完成翻译的} else if (phase === 5 && status === 2) {let resText = '';if (text && text !== 'null') {if (isJsonString(text)) {const textArr = JSON.parse(text);const isArr = Array.isArray(textArr);// 数字的 string 类型如 111,isJsonString 判断为 json 字符串,会导致 .join 失败resText = isArr ? textArr?.join('\n') : textArr;} else {resText = text;}}if (!resText) {return;}const newList = currTextListRef.current.map(item => {return item.id === requestId ? { ...item, text: `${item.text}\n${resText}` } : item;});currTextListRef.current = newList;setTextList(newList);}} catch (error) {console.warn(error);}};

 AI 音频产品开发模板及流程(二)

http://www.dtcms.com/a/292373.html

相关文章:

  • 网络安全第三次作业搭建前端页面并解析
  • allegro 16.6配置CIS库报错 ORCIS-6129 ORCIS-6469
  • LeetCode 658.找到K个最接近的元素
  • .NET使用EPPlus导出EXCEL的接口中,文件流缺少文件名信息
  • Unity笔记——事件中心
  • 力扣-300.最长递增子序列
  • 以太坊网络发展分析:技术升级与市场动态的双重驱动
  • 快手开源 Kwaipilot-AutoThink 思考模型,有效解决过度思考问题
  • Cy3-COOH 花菁染料Cy3-羧基
  • linux-日志服务
  • Gitlab-CI实现组件自动推送
  • 常用 Flutter 命令大全:从开发到发布全流程总结
  • 检索增强型生成助力无人机精准数学推理!RAG-UAV:基于RAG的复杂算术推理方法
  • Lua语言
  • MybatisPlus-16.扩展功能-枚举处理器
  • ORACLE DATABASE 11.2.0.4 RAC Install
  • Vue-22-通过flask接口提供的数据使用plotly.js绘图(一)
  • Oracle定时清理归档日志
  • RAG(检索增强生成)里的文档管理
  • 二次供水管理系统:远程监控+智能调控+故障预警解决方案
  • 用ffmpeg 进行视频的拼接
  • 【指南】网络安全领域:HW 行动(国家网络安全攻防演练)是什么?
  • 一些Avalonia与WPF内容的对应关系和不同用法
  • 单一职责原则(SRP):构建高质量软件的基石
  • Java 并发性深度解析
  • JS WebAPIs DOM节点概述
  • 网络层传输
  • 4G车载录像机的作用详解:提升行车安全与智能管理的核心技术
  • 数字签名(Digital Signature)
  • XSS内容分享