黑豹程序员-h5前端录音、播放

H5支持页面中调用录音机进行录音

H5加入录音组件,录音后可以进行播放,并形成录音文件,其采样率固化48000,传言是google浏览器的BUG,它无法改动采样率。
大BUG,目前主流的支持16000hz的采样率。

界面

在这里插入图片描述

录音组件

D:\workspace\vue\vzx-admin\src\components\Recorder\recorder.vue

<template>
  <div>
    <button @click="startRecording" :disabled="isRecording">开始录音</button>&nbsp;
    <button @click="stopRecording" :disabled="!isRecording">停止录音</button>&nbsp;
    <el-checkbox size="small" checked="isplay">是否播放</el-checkbox>
  </div>
</template>

<script>
import axios from "axios";

export default {
  data() {
    return {
      mediaRecorder: null,
      isRecording: false,
      chunks: [],
      isplay: true
    };
  },
  methods: {
    async startRecording() {
      const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
      let track = stream.getAudioTracks()[0];

      //获取音频文件的信息
      console.log(track.getCapabilities());

      this.mediaRecorder = new MediaRecorder(stream);
      this.chunks = [];

      this.mediaRecorder.ondataavailable = (event) => {
        if (event.data.size > 0) {
          this.chunks.push(event.data);
        }
      };

      this.mediaRecorder.onstop = () => {
        const audioBlob = new Blob(this.chunks, { type: 'audio/wav' });
        const audioUrl = URL.createObjectURL(audioBlob);

        // ==在这里你可以处理录制完成的音频,比如播放或上传到服务器===========
        // 创建FormData对象
        let formData = new FormData();
        // 第一个参数是后台接收的文件参数名,第二个参数是blob数据,第三个参数是文件名
        formData.append('file', audioBlob, 'rd.wav');

        // 发送ajax请求
        axios.post('http://localhost:6070/basic/coursepic', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          }
        }).then(response => {
          // 处理响应数据
          console.log(response)
        }).catch(error => {
          // 处理错误
          console.log(error)
        })

        //==播放=================
        if(this.isplay){
          var audio=document.createElement("audio");
          audio.controls=true;
          document.body.appendChild(audio);
          audio.src=audioUrl;
          audio.play(); //这样就能播放了
          audio.style.display = "none";

          //注意不用了时需要revokeObjectURL,否则霸占内存
          setTimeout(function(){ URL.revokeObjectURL(audio.src) },5000);
        }
      };

      this.mediaRecorder.start();
      this.isRecording = true;
    },
    stopRecording() {
      if (this.mediaRecorder && this.isRecording) {
        this.mediaRecorder.stop();
        this.isRecording = false;
      }
    },
  },
};
</script>


测试页面

<template>
	<Recorder />
</template>

<script setup>
import Recorder from '../../components/Recorder/recorder.vue';

</script>


后台上传类 FileUploadController

H5会将用户的语音转成一个采样率48khz的wav文件(二进制流),配合SpringMVC的multipartFiles,就可以实现将音频文件上传保存。
注意目前H5的谷歌浏览器无法设置采样率,这是一个公开的bug,因为目前市场主流都使用16khz采样。如:科大讯飞语音识别只支持8k,16k,不支持48k。

下面是写好的一个图片上传的工具类,大家可以将就,我们的重点在h5录音,当然也可以稍加改造即可。

package com.zx.basic.controller;

import com.zx.basic.service.FileUploadService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;

/**
 * @version v1.0 创建时间:16:22
 * @author: 作者:陈子枢
 * @web CSDN:https://blog.csdn.net/nutony
 * @description 描述:
 */
@RestController
@CrossOrigin
public class FileUploadController {
    @Autowired
    private FileUploadService fileUploadService;

    //上传课程图片
    @PostMapping("/basic/coursepic")
    public String coursePic(@RequestParam("file") MultipartFile[] multipartFiles) throws IOException {

        return fileUploadService.coursePic(multipartFiles);
    }
}

package com.zx.basic.service;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.UUID;

/**
 * @version v1.0 创建时间:15:47
 * @author: 作者:陈子枢
 * @web CSDN:https://blog.csdn.net/nutony
 * @description 描述:文件上传的服务
 */
@Service
public class FileUploadService {
    @Value("${upload-web.dir}")
    private String dir;

    public String coursePic(MultipartFile[] multipartFile) throws IOException {
        /*
                上传图片文件:
                1. 不能覆盖之前的文件?           起新文件名:uuid,后缀?使用源文件的后缀
                2. 一个目录下不要太多的文件?      会按文件的年/月/日/时...来创建文件并存储
                C:\Users\nutony\Documents\WeChat Files\tony52399178\FileStorage\File\2023-09
         */
        String src = multipartFile[0].getOriginalFilename();
        String extName = src.substring(src.lastIndexOf("."));   //扩展名
        String newFilename = UUID.randomUUID() + extName;   //防止同名覆盖,防止多用户

        //相对路径
        String subDir = "/" + DateUtil.now().substring(0,10) + "/";

        //利于hutool工具类包产生当前时间,当前日期
        FileUtil.mkdir(dir + subDir);    //创建多级目录

        Files.write(Paths.get(dir + subDir + newFilename), multipartFile[0].getBytes());
        return subDir + newFilename;
    }
}


你可能感兴趣的:(黑豹程序员,Vue,front-end,大前端,前端,语音)