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

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

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

大BUG,目前主流的支持16000hz的采样率。

界面

录音组件

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

cpp 复制代码
<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>

测试页面

cpp 复制代码
<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录音,当然也可以稍加改造即可。

cpp 复制代码
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);
    }
}
cpp 复制代码
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;
    }
}
相关推荐
会说法语的猪35 分钟前
uniapp使用uni.navigateBack返回页面时携带参数到上个页面
前端·uni-app
古蓬莱掌管玉米的神9 小时前
vue3语法watch与watchEffect
前端·javascript
林涧泣9 小时前
【Uniapp-Vue3】uni-icons的安装和使用
前端·vue.js·uni-app
雾恋9 小时前
AI导航工具我开源了利用node爬取了几百条数据
前端·开源·github
拉一次撑死狗9 小时前
Vue基础(2)
前端·javascript·vue.js
祯民10 小时前
两年工作之余,我在清华大学出版社出版了一本 AI 应用书籍
前端·aigc
热情仔10 小时前
mock可视化&生成前端代码
前端
m0_7482463510 小时前
SpringBoot返回文件让前端下载的几种方式
前端·spring boot·后端
wjs040610 小时前
用css实现一个类似于elementUI中Loading组件有缺口的加载圆环
前端·css·elementui·css实现loading圆环
爱趣五科技10 小时前
无界云剪音频教程:提升视频质感
前端·音视频