JAVA实现JS录音接收WAV文件存入服务器

借鉴问题:https://blog.csdn.net/u012757419/article/details/119829351

https://www.jianshu.com/p/ed2c55b7a37d?u_atoken=1782efe2-a343-45e2-887d-c1e4d6ba30fc&u_asession=01D3yxVL3iagjUgXhqszBxeFtw3xk0IpT6_9Nnp-gcmEkUqJ0-shFbQkJ6qKFiAgAcX0KNBwm7Lovlpxjd_P_q4JsKWYrT3W_NKPr8w6oU7K_pWnMe1bamEXTa-T7ZN5hDhUF3o-sVtq6Wun3JL3SJe2BkFo3NEHBv0PZUm6pbxQU&u_asig=05jvzEToeIBylYTqO6AnQYpyrkVLoa0bIbNawz6MDceuXiKGX9Vj745SvWOd1eqdn_bdBAkFbFUyClKsMVqrLnfxyq-_WZIdBjbuXLnE-iJx-ouxCwBU2I86exR0ied4IMMJbQSKJT5g_WdaXPITjAdqft8kZYg6Psh9cidPIq6xD9JS7q8ZD7Xtz2Ly-b0kmuyAKRFSVJkkdwVUnyHAIJzeXaROX0W1RD3zhOpI6qlO1LZMBrZ4YRms3DZiN-_RHdom7nzSzR1LP16f45fIKp-e3h9VXwMyh6PgyDIVSG1W-biEIF782dzGP25U9CtLRUIA_x6eH4B6QCtHBvxE9JXyHfhJHm_fLb2iHw_QXj6xRnWYAJcv_v_g0vrGyTuvn9mWspDxyAEEo4kbsryBKb9Q&u_aref=lfoIQluaDC619atMHeZWeHQ%2B66w%3D

借鉴:https://blog.csdn.net/qq_45043019/article/details/121303431

https://blog.csdn.net/weixin_43088706/article/details/104000600?spm=1001.2101.3001.6650.3&utm_medium=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-104000600-blog-91425440.pc_relevant_default&depth_1-utm_source=distribute.pc_relevant.none-task-blog-2%7Edefault%7ECTRLIST%7ERate-3-104000600-blog-91425440.pc_relevant_default&utm_relevant_index=4

前端HTML的代码:

recorder.js源码

/*!
 * 
 * js-audio-recorder - js audio recorder plugin
 * 
 * @version v0.5.3
 * @homepage https://github.com/2fps/recorder
 * @author 2fps <echoweb@126.com> (https://www.zhuyuntao.cn)
 * @license MIT
 *         
 */
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.Recorder=e():t.Recorder=e()}(this,function(){return function(t){var e={};function i(n){if(e[n])return e[n].exports;var r=e[n]={i:n,l:!1,exports:{}};return t[n].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var r in t)i.d(n,r,function(e){return t[e]}.bind(null,r));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";Object.defineProperty(e,"__esModule",{value:!0});var n=function(){function t(t){void 0===t&&(t={}),this.isplaying=!1,this.lBuffer=[],this.rBuffer=[],this.tempPCM=[],this.inputSampleBits=16,this.playStamp=0,this.playTime=0,this.totalPlayTime=0,this.offset=0,this.fileSize=0;var e,i=new(window.AudioContext||window.webkitAudioContext);this.inputSampleRate=i.sampleRate,this.config={sampleBits:~[8,16].indexOf(t.sampleBits)?t.sampleBits:16,sampleRate:~[11025,16e3,22050,24e3,44100,48e3].indexOf(t.sampleRate)?t.sampleRate:this.inputSampleRate,numChannels:~[1,2].indexOf(t.numChannels)?t.numChannels:1,compiling:!!t.compiling||!1},this.outputSampleRate=this.config.sampleRate,this.oututSampleBits=this.config.sampleBits,this.littleEdian=(e=new ArrayBuffer(2),new DataView(e).setInt16(0,256,!0),256===new Int16Array(e)[0]),this.initUserMedia()}return t.prototype.initRecorder=function(){var t=this;this.context&&this.destroy(),this.context=new(window.AudioContext||window.webkitAudioContext),this.analyser=this.context.createAnalyser(),this.analyser.fftSize=2048;var e=this.context.createScriptProcessor||this.context.createJavaScriptNode;this.recorder=e.apply(this.context,[4096,this.config.numChannels,this.config.numChannels]),this.recorder.onaudioprocess=function(e){if(t.isrecording&&!t.ispause){var i,n=e.inputBuffer.getChannelData(0),r=null;if(t.lBuffer.push(new Float32Array(n)),t.size+=n.length,2===t.config.numChannels&&(r=e.inputBuffer.getChannelData(1),t.rBuffer.push(new Float32Array(r)),t.size+=r.length),t.config.compiling){var o=t.transformIntoPCM(n,r);t.tempPCM.push(o),t.fileSize=o.byteLength*t.tempPCM.length}else t.fileSize=Math.floor(t.size/Math.max(t.inputSampleRate/t.outputSampleRate,1))*(t.oututSampleBits/8);i=100*Math.max.apply(Math,n),t.duration+=4096/t.inputSampleRate,t.onprocess&&t.onprocess(t.duration),t.onprogress&&t.onprogress({duration:t.duration,fileSize:t.fileSize,vol:i,data:t.tempPCM})}}},t.prototype.start=function(){var t=this;if(!this.isrecording)return this.clear(),this.initRecorder(),this.isrecording=!0,navigator.mediaDevices.getUserMedia({audio:!0}).then(function(e){t.audioInput=t.context.createMediaStreamSource(e),t.stream=e}).then(function(){t.audioInput.connect(t.analyser),t.analyser.connect(t.recorder),t.recorder.connect(t.context.destination)})},t.prototype.pause=function(){this.isrecording&&!this.ispause&&(this.ispause=!0,this.recorder.disconnect())},t.prototype.resume=function(){this.isrecording&&this.ispause&&(this.ispause=!1,this.audioInput&&this.audioInput.connect(this.analyser),this.analyser.connect(this.recorder),this.recorder.connect(this.context.destination))},t.prototype.stop=function(){this.isrecording=!1,this.audioInput&&this.audioInput.disconnect(),this.recorder.disconnect()},t.prototype.play=function(){this.stop(),this.source&&this.source.stop(),this.isplaying=!0,this.playTime=0,this.playAudioData()},t.prototype.getPlayTime=function(){var t=0;return(t=this.isplaying?this.context.currentTime-this.playStamp+this.playTime:this.playTime)>=this.totalPlayTime&&(t=this.totalPlayTime),t},t.prototype.pausePlay=function(){!this.isrecording&&this.isplaying&&(this.source&&this.source.disconnect(),this.playTime+=this.context.currentTime-this.playStamp,this.isplaying=!1)},t.prototype.resumePlay=function(){this.isrecording||this.isplaying||0===this.playTime||(this.isplaying=!0,this.playAudioData())},t.prototype.stopPlay=function(){this.isrecording||(this.playTime=0,this.isplaying=!1,this.source&&this.source.stop())},t.prototype.getWholeData=function(){return this.tempPCM},t.prototype.getNextData=function(){var t=this.tempPCM.length,e=this.tempPCM.slice(this.offset);return this.offset=t,e},t.prototype.playAudioData=function(){var e=this;this.context.decodeAudioData(this.getWAV().buffer,function(t){e.source=e.context.createBufferSource(),e.source.buffer=t,e.totalPlayTime=e.source.buffer.duration,e.source.connect(e.analyser),e.analyser.connect(e.context.destination),e.source.start(0,e.playTime),e.playStamp=e.context.currentTime},function(e){t.throwError(e)})},t.prototype.getRecordAnalyseData=function(){if(this.ispause)return this.prevDomainData;var t=new Uint8Array(this.analyser.frequencyBinCount);return this.analyser.getByteTimeDomainData(t),this.prevDomainData=t},t.prototype.getPlayAnalyseData=function(){return this.getRecordAnalyseData()},t.prototype.initUserMedia=function(){void 0===navigator.mediaDevices&&(navigator.mediaDevices={}),void 0===navigator.mediaDevices.getUserMedia&&(navigator.mediaDevices.getUserMedia=function(t){var e=navigator.getUserMedia||navigator.webkitGetUserMedia||navigator.mozGetUserMedia;return e?new Promise(function(i,n){e.call(navigator,t,i,n)}):Promise.reject(new Error("浏览器不支持 getUserMedia !"))})},t.prototype.getPCM=function(){if(this.tempPCM.length){var e=new ArrayBuffer(this.tempPCM.length*this.tempPCM[0].byteLength),i=new DataView(e),n=0;this.tempPCM.forEach(function(t){for(var e=0,r=t.byteLength;e<r;++e)i.setInt8(n,t.getInt8(e)),n++}),this.PCM=i,this.tempPCM=[]}if(this.PCM)return this.PCM;var r=this.flat();return r=t.compress(r,this.inputSampleRate,this.outputSampleRate),this.PCM=t.encodePCM(r,this.oututSampleBits,this.littleEdian)},t.prototype.getPCMBlob=function(){return this.stop(),new Blob([this.getPCM()])},t.prototype.downloadPCM=function(t){void 0===t&&(t="recorder");var e=this.getPCMBlob();this.download(e,t,"pcm")},t.prototype.getWAV=function(){var e=this.getPCM();return t.encodeWAV(e,this.inputSampleRate,this.outputSampleRate,this.config.numChannels,this.oututSampleBits,this.littleEdian)},t.prototype.getWAVBlob=function(){return this.stop(),new Blob([this.getWAV()],{type:"audio/wav"})},t.prototype.downloadWAV=function(t){void 0===t&&(t="recorder");var e=this.getWAVBlob();this.download(e,t,"wav")},t.prototype.transformIntoPCM=function(e,i){var n=new Float32Array(e),r=new Float32Array(i),o=t.compress({left:n,right:r},this.inputSampleRate,this.outputSampleRate);return t.encodePCM(o,this.oututSampleBits,this.littleEdian)},t.prototype.destroy=function(){return this.stopStream(),this.closeAudioContext()},t.prototype.stopStream=function(){this.stream&&this.stream.getTracks&&(this.stream.getTracks().forEach(function(t){return t.stop()}),this.stream=null)},t.prototype.closeAudioContext=function(){return this.context.close?this.context.close():new Promise(function(t){t()})},t.prototype.download=function(e,i,n){try{var r=document.createElement("a");r.href=window.URL.createObjectURL(e),r.download=i+"."+n,r.click()}catch(e){t.throwError(e)}},t.prototype.clear=function(){this.lBuffer.length=0,this.rBuffer.length=0,this.size=0,this.fileSize=0,this.PCM=null,this.audioInput=null,this.duration=0,this.ispause=!1,this.isplaying=!1,this.playTime=0,this.totalPlayTime=0,this.source&&(this.source.stop(),this.source=null)},t.prototype.flat=function(){var t=null,e=new Float32Array(0);1===this.config.numChannels?t=new Float32Array(this.size):(t=new Float32Array(this.size/2),e=new Float32Array(this.size/2));for(var i=0,n=0;n<this.lBuffer.length;n++)t.set(this.lBuffer[n],i),i+=this.lBuffer[n].length;i=0;for(n=0;n<this.rBuffer.length;n++)e.set(this.rBuffer[n],i),i+=this.rBuffer[n].length;return{left:t,right:e}},t.playAudio=function(t){var e=document.createElement("audio");e.src=window.URL.createObjectURL(t),e.play()},t.compress=function(t,e,i){for(var n=e/i,r=Math.max(n,1),o=t.left,s=t.right,a=Math.floor((o.length+s.length)/n),u=new Float32Array(a),h=0,c=0;h<a;){var l=Math.floor(c);u[h]=o[l],h++,s.length&&(u[h]=s[l],h++),c+=r}return u},t.encodePCM=function(t,e,i){void 0===i&&(i=!0);var n=0,r=t.length*(e/8),o=new ArrayBuffer(r),s=new DataView(o);if(8===e)for(var a=0;a<t.length;a++,n++){var u=(h=Math.max(-1,Math.min(1,t[a])))<0?128*h:127*h;u=+u+128,s.setInt8(n,u)}else for(a=0;a<t.length;a++,n+=2){var h=Math.max(-1,Math.min(1,t[a]));s.setInt16(n,h<0?32768*h:32767*h,i)}return s},t.encodeWAV=function(t,e,i,n,o,s){void 0===s&&(s=!0);var a=i>e?e:i,u=o,h=new ArrayBuffer(44+t.byteLength),c=new DataView(h),l=n,p=0;r(c,p,"RIFF"),p+=4,c.setUint32(p,36+t.byteLength,s),r(c,p+=4,"WAVE"),r(c,p+=4,"fmt "),p+=4,c.setUint32(p,16,s),p+=4,c.setUint16(p,1,s),p+=2,c.setUint16(p,l,s),p+=2,c.setUint32(p,a,s),p+=4,c.setUint32(p,l*a*(u/8),s),p+=4,c.setUint16(p,l*(u/8),s),p+=2,c.setUint16(p,u,s),r(c,p+=2,"data"),p+=4,c.setUint32(p,t.byteLength,s),p+=4;for(var f=0;f<t.byteLength;)c.setUint8(p,t.getUint8(f)),p++,f++;return c},t.throwError=function(t){throw new Error(t)},t}();function r(t,e,i){for(var n=0;n<i.length;n++)t.setUint8(e+n,i.charCodeAt(n))}e.default=n}]).default});
//# sourceMappingURL=recorder.js.map
<script type="text/javascript"
		src="../../lib/js/recorder.js"></script>
	
<button type="button" onclick="recorderStart()"	class="btn  backgroundColor btn-circle  btn-xs  fontWeightBold">&nbsp;recorderStart&nbsp;</button>	
<button type="button" onclick="recorderStop()"	class="btn  backgroundColor btn-circle  btn-xs  fontWeightBold">&nbsp;recorderStop&nbsp;</button>

前端JS代码:

const recorder = new Recorder({
	sampleBits: 16,                 // 采样位数,支持 8 或 16,默认是16
	sampleRate: 48000,              // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
	numChannels: 1,                 // 声道,支持 1 或 2, 默认是1
//	compiling: false,(0.x版本中生效,1.x增加中)  // 是否边录边转换,默认是false
})

//绑定事件-打印的是当前录音数据
recorder.onprogress = function(params) {
	console.log('--------------START---------------')
	console.log('录音时长(秒)', params.duration);
	console.log('录音大小(字节)', params.fileSize);
	console.log('录音音量百分比(%)', params.vol);
	console.log('当前录音的总数据([DataView, DataView...])', params.data);

	console.log('--------------END---------------')
}
function recorderStart(){
	recorder.start().then(
			() => {
				// 开始录音
				console.log('开始录音了=========')
			},
			(error) => {
				// 出错了
				console.log(error)
			}
	)
}
function recorderStop(){
	recorder.stop();
//	recorder.downloadWAV();
	let wavBlob = recorder.getWAVBlob();
	let renameFile =new File([wavBlob], '文件名.wav', { type: 'audio/wav' })
	uploadWAVFile(wavBlob);
}
function uploadWAVFile(formData){
	$.ajax({
		type:'POST',
		url:'/getVoiceWAVFile',
		cache: false, //上传文件无需缓存
		data:formData,
		async:false,
		processData:false,
		contentType:false,
		success:function(data){
			console.log("uploadWAVFileOKOKOK");
		},error:function(data){
			console.log("error");
		}
	});
}

后端代码:

/**
	 * 上传录音文件
	 * @param request
	 * @return
	 */
	@RequestMapping(value="/getVoiceWAVFile")
	@ResponseBody
	public Map<String, Object> getVoiceWAVFile(HttpServletRequest request) {
		logger.info("---271-getVoiceWAVFile1111:"+request.getContentType());
		try {
			final ServletInputStream compressed = request.getInputStream();
			InputStream input=compressed;
			String filePath="/home/tao/image/testteatstes.WAV";
			File f = new File(filePath);
			copyInputStreamToFile(input,f);
			logger.info("---271-getVoiceWAVFile---3333:"+request.getContentType());
		}catch ( Exception e) {
			e.printStackTrace();
		}
		Map<String,Object> map = new HashMap<String,Object>();
		map.put("list",1 );
		return map; // 返回文件地址
	}
	private static void copyInputStreamToFile(InputStream inputStream, File file) 
			throws IOException {
		try (FileOutputStream outputStream = new FileOutputStream(file)) {
			int read;
			byte[] bytes = new byte[1024*10];
			while ((read = inputStream.read(bytes)) != -1) {
				outputStream.write(bytes, 0, read);
			}
		}
	}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值