• 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>
          <button
            onClick={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 recording
          mediaRecorderRef.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>
          <button
            onMouseDown={handleMouseDown}
            onMouseUp={handleMouseUp}
            onMouseLeave={handleMouseUp}
            style={{ backgroundColor: recording ? "red" : "white" }}
          >
            {recording ? "正在录音..." : "开始录音"}
          </button>
        </div>
      );
    };
    
    export default AudioRecorder;
    
  • 相关阅读:
    Vue_路由VueRoute
    java基础巩固15
    以梦为马,不负韶华|电巢科技&延安大学飞鹰计划实习班精彩回顾
    在虚拟机安装JDK
    基于51单片机的秒表系统设计
    k8s之配置资源管理
    VR全景展示的功能有哪些?你了解多少?
    多表操作-外键级联操作
    kubernetes集群编排(13)
    Java常用类
  • 原文地址:https://blog.csdn.net/weixin_43503080/article/details/139963177