react项目实现语音识别功能

需要调用后端接口将录音文件传给后端,由后端将录音内容转换成文字返回给前端,当然也有一些插件可以实现语音转文字功能,可以自行查找使用插件实现方法

有注释版本,下面还有 一个无注释版本。

import React, { useState, useEffect, useRef } from "react";
import { getTextByAudio } from "./api/audio";const AudioRecorder = () => {const [recording, setRecording] = useState(false); // 是否正在录音const audioData = useRef<MediaStream | null>(null); // 创建一个ref,存储媒体流数据const mediaRecorderRef = useRef<MediaRecorder | null>(null); // 创建一个ref,用于存储媒体记录器实例const chunksRef = useRef<Blob[]>([]); // 创建一个ref,用于存储音频数据块useEffect(() => {const init = async () => {try {// 获取用户媒体设备(麦克风)的媒体流const stream = await navigator.mediaDevices.getUserMedia({audio: true,});// 将获取到的媒体流存储到audioData ref中audioData.current = stream;} catch (error) {console.error("Error accessing microphone:", error);// 如果获取媒体流失败,打印错误信息// 这里可以设置一个错误状态,用于显示给用户}};init();// 组件卸载时清理资源return () => {if (audioData.current) {audioData.current.getTracks().forEach((track) => track.stop());}};}, []);const startRecording = () => {if (audioData.current) {chunksRef.current = [];// 重置chunks数组,用于新的录音mediaRecorderRef.current = new MediaRecorder(audioData.current);// 创建一个新的MediaRecorder实例// 当有数据可用时触发的事件mediaRecorderRef.current.ondataavailable = (event) => {if (event.data && event.data.size > 0) {chunksRef.current.push(event.data);// 将数据块添加到chunks数组中}};mediaRecorderRef.current.start();// 开始录音setRecording(true);// 更新录音状态为正在录音}};const stopRecording = () => {if (mediaRecorderRef.current &&mediaRecorderRef.current.state === "recording") {mediaRecorderRef.current.stop();// 停止录音setRecording(false);// 更新录音状态为未录音// 当录音停止时触发的事件mediaRecorderRef.current.onstop = async () => {// 将chunks数组中的数据合并成一个Blob对象const blob = new Blob(chunksRef.current, { type: "audio/wav" });const formData = new FormData(); // 创建一个FormData对象,用于上传音频文件formData.append("file", blob, "recording.wav");getTextByAudio(formData).then((res: any) => {console.log(res, 999);}).catch((error) => {console.error("Error converting audio to text:", error);// 这里可以设置一个错误状态,用于显示给用户});};}};return (<div><buttononClick={recording ? stopRecording : startRecording}style={{ backgroundColor: recording ? "red" : "white" }}>{recording ? "停止录音" : "开始录音"}</button></div>);
};export default AudioRecorder;

无注释版

import React, { useState, useEffect, useRef } from "react";
import { getTextByAudio } from "./api/audio";const AudioRecorder = () => {const [recording, setRecording] = useState(false);const audioData = useRef<MediaStream | null>(null);const mediaRecorderRef = useRef<MediaRecorder | null>(null);const chunksRef = useRef<Blob[]>([]);useEffect(() => {const init = async () => {try {const stream = await navigator.mediaDevices.getUserMedia({audio: true,});audioData.current = stream;} catch (error) {console.error("Error accessing microphone:", error);}};init();}, []);const handleMouseDown = () => {if (audioData.current) {chunksRef.current = []; // Reset chunks array for new recordingmediaRecorderRef.current = new MediaRecorder(audioData.current);mediaRecorderRef.current.ondataavailable = (event) => {if (event.data && event.data.size > 0) {chunksRef.current.push(event.data);}};mediaRecorderRef.current.start();setRecording(true);}};const handleMouseUp = () => {if (mediaRecorderRef.current &&mediaRecorderRef.current.state === "recording") {mediaRecorderRef.current.stop();setRecording(false);mediaRecorderRef.current.onstop = async () => {const blob = new Blob(chunksRef.current, { type: "audio/wav" });const formData = new FormData();formData.append("file", blob, "recording.wav");getTextByAudio(formData).then((res: any) => {console.log(res.Segments, 6666);});// 以下代码为下载录音// const url = URL.createObjectURL(blob);// console.log(url, 'y');// const a = document.createElement("a");// a.style.display = "none";// a.href = url;// a.download = "recording.wav";// document.body.appendChild(a);// a.click();// document.body.removeChild(a);// URL.revokeObjectURL(url);};}};return (<div><buttononMouseDown={handleMouseDown}onMouseUp={handleMouseUp}onMouseLeave={handleMouseUp}style={{ backgroundColor: recording ? "red" : "white" }}>{recording ? "正在录音..." : "开始录音"}</button></div>);
};export default AudioRecorder;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/37709.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

面试-J.U.C包的梳理

1.J.U.C包的梳理 Java.Util.Concurrent包简称JUC (1)JUC整体架构图 (2)分析 Executor&#xff1a;线程执行器&#xff0c;任务执行和调度的框架。Tools下存在executor相关的executors类&#xff0c;用于创建executorservice&#xff0c;scheduleexecutorservice&#xff0c;…

互斥锁(Mutex)和条件变量(Condition Variable)的作用

互斥锁&#xff08;Mutex&#xff09;的作用 互斥锁&#xff08;Mutex&#xff0c;全称Mutual Exclusion Lock&#xff09;是一种用于多线程编程中的同步原语&#xff0c;其主要作用是确保在任何给定时间只有一个线程可以访问共享资源&#xff0c;以避免多个线程同时对共享资源…

哪吒汽车,正在等待“太乙真人”的拯救

文丨刘俊宏 在360创始人、哪吒汽车股东周鸿祎近日连续且着急的“督战”中&#xff0c;哪吒汽车&#xff08;下简称哪吒&#xff09;终究还是顶不住了。 6月26日&#xff0c;哪吒通过母公司合众新能源在港交所提交了IPO文件&#xff0c;急迫地希望成为第五家登陆港股的造车新势力…

高精度除法的实现

高精度除法与高精度加法的定义、前置过程都是大致相同的&#xff0c;如果想了解具体内容&#xff0c;可以移步至我的这篇博客&#xff1a;高精度加法计算的实现 在这里就不再详细讲解&#xff0c;只讲解主体过程qwq 主体过程 高精度除法的原理和小学学习的竖式除法是一样的。 …

【Sklearn-驯化】一文搞懂机器学习树模型建模可视化过程

【Sklearn-驯化】一文搞懂机器学习树模型建模可视化过程 本次修炼方法请往下查看 &#x1f308; 欢迎莅临我的个人主页 &#x1f448;这里是我工作、学习、实践 IT领域、真诚分享 踩坑集合&#xff0c;智慧小天地&#xff01; &#x1f387; 免费获取相关内容文档关注&#xff…

OpenCV学习之cv2.imshow()函数

OpenCV学习之cv2.imshow()函数 一、简介 cv2.imshow 是 OpenCV 库中用于显示图像的基本函数之一。在图像处理和计算机视觉的过程中&#xff0c;使用该函数可以快速预览处理后的图像&#xff0c;便于调试和结果展示。 二、基本语法 cv2.imshow(WindowName, Imgmat)三、参数说…

如何制作鼠标悬浮后伸缩的搜索框

引言 许多博客都在使用的伸缩搜索框制作教程 成品展示&#xff08;颜色自行搭配&#xff09; 初步布局 居中盒子&&初始化样式 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewpo…

2SK241 LTSpice模型及仿真

2SK241是东芝生产的一款NMOS&#xff0c;早已停产&#xff0c;但是在收音机圈子里还是有很多死忠粉&#xff0c;所以在淘宝上也是一堆打磨改标的假货。 言归正传&#xff0c;在矿坛上找到了2SK241的模型&#xff1a; .model M2SK241bottom NMOS(Level1 Rd1 Rs10 Rg50 Kp8mV…

在高并发场景下,怎样避免 PostgreSQL 的死锁问题?

文章目录 &#xff08;一&#xff09;不当的事务设计&#xff08;二&#xff09;不正确的锁使用&#xff08;三&#xff09;并发操作冲突&#xff08;一&#xff09;优化事务设计&#xff08;二&#xff09;正确使用锁&#xff08;三&#xff09;调整数据库参数&#xff08;四&…

mindspore打卡第9天 transformer的encoder和decoder部分

mindspore打卡第9天 transformer的encoder和decoder部分 import mindspore from mindspore import nn from mindspore import ops from mindspore import Tensor from mindspore import dtype as mstypeclass ScaledDotProductAttention(nn.Cell):def __init__(self, dropout_…

2024年6月29日 (周六) 叶子游戏新闻

老板键工具来唤去: 它可以为常用程序自定义快捷键&#xff0c;实现一键唤起、一键隐藏的 Windows 工具&#xff0c;并且支持窗口动态绑定快捷键&#xff08;无需设置自动实现&#xff09;。 喜马拉雅下载工具: 字面意思 《星刃》性感女主私密部位细节逼真 让玩家感到惊讶《星刃…

clion ctrl+左键只能跳转到虚函数的声明处

右击函数 -> GOTO -> Definition 这样不够便捷&#xff0c;但是我没有找到更好的办法 可能是因为该函数是虚函数的重写&#xff0c;clion 无法识别出该函数是虚函数的哪个重写版&#xff0c;只能跳转到唯一的虚函数位置

springboot注解@ComponentScan注解作用

一 ComponentScan作用 1.1 注解作用 项目会默认扫描SpringBootApplication注解所在路径的同级和下级的所有子包&#xff0c;使用ComponentScan后他会取代掉默认扫描。 ComponentScan 是Spring框架的注解&#xff0c;它的作用是扫描指定的包路径下的标有 Component、Service、…

力扣300. 最长递增子序列(动态规划)

Problem: 300. 最长递增子序列 文章目录 题目描述思路及解法复杂度Code 题目描述 思路及解法 明确题目涉及到求取最值问题因此我们可以考虑使用动态规划来解决问题 1.定义状态&#xff1a;定义int类型的dp数组表示以nums[i]结尾的序列的最长长度&#xff0c;初始化均为1即表示…

Python | Leetcode Python题解之第198题打家劫舍

题目&#xff1a; 题解&#xff1a; class Solution:def rob(self, nums: List[int]) -> int:if not nums:return 0size len(nums)if size 1:return nums[0]first, second nums[0], max(nums[0], nums[1])for i in range(2, size):first, second second, max(first nu…

LNBxx21的功能

LNBxx21功能&#xff1a; LNBxx21 家族是为卫星LNB模块供电/连接LNB块与接收机的集成化解决方案。LNBxx21的很多功能可以让LNB电源/接口符合国际标准&#xff0c;此外&#xff0c;模块内还包括一个I2C总线接口&#xff0c;因为集成了一个升压直流-直流控制器&#xff0c;所以可…

Python Pandas基础使用

Python Pandas基础使用 Python Pandas基础使用数据类型SeriesDataFramePanel 创建SeriesDataFrame 基本使用描述性统计重新索引迭代排序处理文本数据选项和定制索引和选择数据统计函数窗口函数聚合函数缺失数据GroupBy合并/连接日期功能Timedelta Python Pandas基础使用 记录一…

代码随想三刷动态规划篇1

代码随想三刷动态规划篇1 509. 斐波那契数题目代码70. 爬楼梯题目代码746. 使用最小花费爬楼梯题目代码509. 斐波那契数 题目 链接 代码 class Solution {public int fib(int n) {if(n<=1){return n

MySQL高级-InnoDB引擎-事务日志- redo log(事务持久性的保证)

文章目录 1、redo log1.1、重做日志缓冲&#xff08;redo log buffer&#xff09;1.2、重做日志文件&#xff08;redo log file&#xff09; 2、如果没有redo log&#xff0c;可能会存在什么问题的&#xff1f;2.2、我们一起来分析一下。 2.2、那么&#xff0c;如何解决上述的问…

利用Matlab制作Gif图

Gif图相当于是由许多张图片拼接而成的一个“短视频”&#xff0c;因此在制作Gif图之前我们需要先准备多张图片。以下代码实现的是在当前路径下创建了一个image文件夹&#xff0c;并将绘制的HRRP通过saveas函数保存至image文件夹中&#xff0c;并命名为1.png、2.png、 %% 绘制H…