黑豹程序员-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;
    }
}
相关推荐
逐·風4 小时前
unity关于自定义渲染、内存管理、性能调优、复杂物理模拟、并行计算以及插件开发
前端·unity·c#
Devil枫4 小时前
Vue 3 单元测试与E2E测试
前端·vue.js·单元测试
尚梦5 小时前
uni-app 封装刘海状态栏(适用小程序, h5, 头条小程序)
前端·小程序·uni-app
GIS程序媛—椰子5 小时前
【Vue 全家桶】6、vue-router 路由(更新中)
前端·vue.js
前端青山6 小时前
Node.js-增强 API 安全性和性能优化
开发语言·前端·javascript·性能优化·前端框架·node.js
毕业设计制作和分享6 小时前
ssm《数据库系统原理》课程平台的设计与实现+vue
前端·数据库·vue.js·oracle·mybatis
清灵xmf8 小时前
在 Vue 中实现与优化轮询技术
前端·javascript·vue·轮询
大佩梨8 小时前
VUE+Vite之环境文件配置及使用环境变量
前端
GDAL8 小时前
npm入门教程1:npm简介
前端·npm·node.js
小白白一枚1119 小时前
css实现div被图片撑开
前端·css