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>
<button @click="stopRecording" :disabled="!isRecording">停止录音</button>
<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;
}
}