java & H5 语音技术实例
荒墨丶迷失 发布于2018-01-05 17:37 浏览:17762 回复:107
15
收藏
最后编辑于2019-07-10

各位小伙伴们  2018 又和大家见面了!

新的一年还需要继续努力,突破创新......

今天,给大家带来的是 Global-AI1.0 语音技术的内容,什么是Global-AI1.0呢?

Global-AI1.0 是基于百度的AI接口,通过我这边测试和开发,实现了H5的各个技术的应用示例集合项目。

预计会包括语音技术,人脸识别,UNIT,自然语言,以及图像处理的AI应用,有这一些技术实践的小伙伴也可以一起分享。

好啦,说说今天分享的【语音技术】,主要接入语音识别 和 语音合成 ,在之前的帖子中分别简单的介绍这些实现的原理和Demo源码,可以翻一翻之前的帖子!

当然还是收到许多小伙伴的吐槽,毕竟开源有风险的,哈哈 ~

当然今天分享的内容,会在之前的例子上有所改善和突破,总体如下:

1.H5录音 通过音频流文件上传到后台后,不再是保存为wav格式的音频,而是处理流的形式转为二进制数组,直接调用百度语音识别SDK方法,返回识别结果。

2.前端录音操作,不再是手动的点击结束录音然后上传,而是通过音量控制判断是否需要结束,优化了操作体验。

3.语音合成,返回的音频二进制数组,不再是先保存为MP3格式音频,然后前台用audio播放MP3路径,而是将二进制数据传到前台先转base64然后转化为Blob对象,合成一个Blob音频路径,然后audio直接播放这个Blob音频路径即可

总结:就是增加不说话主动停止录音,语音识别和语音合成播放都通过流转化操作,不再保存任何格式文件形式。

当然了,具体还是根据大家反应的建议,努力提供最好的开源,下面看看这个语音交互页面吧!

下面先简单的讲解上面三条内容的实现方式吧~

1.H5录音 通过音频流文件上传到后台后,不再是保存为wav格式的音频,而是处理流的形式转为二进制数组,直接调用百度语音识别SDK方法,返回识别结果。springMVC 用 MultipartFile 来接收前台上传的音频文件

//音频文件 转化为 byte[]
InputStream content = audioData.getInputStream();
ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while ((rc = content.read(buff, 0, 100)) > 0) {
	swapStream.write(buff, 0, rc);
}
// 获得二进制数组
byte[] byte1 = swapStream.toByteArray();
String Rtext = vsc.getVoiceBySdk(byte1);
System.out.println("语音识别内容:"+Rtext);
modelMap.put("Rtext", Rtext);

通过上述代码 即可将音频文件转化Byte数组的形式调用语音识别。

 

2.前端录音操作,不再是手动的点击结束录音然后上传,而是通过音量控制判断是否需要结束,优化了操作体验。

// 音频采集
		recorder.onaudioprocess = function(e) {
			var data= e.inputBuffer.getChannelData(0);
			var l = Math.floor(data.length / 10);
	        var vol = 0;
	        for(var i = 0; i < l ; i++){
	            vol += Math.abs(data[i*10]);
	        }
	        emptyCheckCount ++;
	        console.log(vol);
	        if(vol < 30){ //设置音量  数值越大越容易停
	            emptydatacount ++;
	            console.log(emptydatacount);
	            if(emptydatacount > 30){  //设置静音停止次数
	            	console.log('stoped');
	            	self.recordStop();
	            }
	        } else {
	            emptydatacount = 0;
	        }
			audioData.input(e.inputBuffer.getChannelData(0));
		};

音频采集的过程中(录音过程),判断输入音量的大小是否小于设置的值,小于的话就停止录音。

 

3.语音合成,返回的音频二进制数组,不再是先保存为MP3格式音频,然后前台用audio播放MP3路径,而是将二进制数据传到前台先转base64然后转化为Blob对象,合成一个Blob音频路径,然后audio直接播放这个Blob音频路径即可

//根据base64音频数据 转化为 blob对象
	function getBlob(base64Data){
		var dataURI = "data:audio/wav;base64,"+base64Data; //base64 字符串
	    var mimeString =  dataURI.split(',')[0].split(':')[1].split(';')[0]; // mime类型
	    var byteString = atob(dataURI.split(',')[1]); //base64 解码
	    var arrayBuffer = new ArrayBuffer(byteString.length); //创建缓冲数组
	    var intArray = new Uint8Array(arrayBuffer); //创建视图
	    for (i = 0; i < byteString.length; i += 1) {
	         intArray[i] = byteString.charCodeAt(i);
	    }
	    return new Blob([intArray], { type:  "audio/wav" }); //转成blob
	}        

根据后台获取base64音频数据调用上诉的方法 转化为 blob对象,再用window.URL.createObjectURL设置audio的src然后播放~

 

关于如何项目部署,大家可以在本贴下方的源码地址,下载Global-AI1.0 进行测试。

如果在测试过程中有任何问题,欢迎下方留言!

git下载地址:https://gitee.com/liyingming/Global_AI_1.0

收藏
点赞
15
个赞
共107条回复 最后由goJhou回复于2019-07-10 14:45
#108goJhou回复于2019-07-10 14:45:29
#107 荒墨丶迷失回复
现在已经跌出前4名了 哈哈

哈哈哈,你看不到第6名,指不定就比你差1分

0
#107荒墨丶迷失回复于2019-07-09 20:41:57
#106 goJhou回复
那是,可是在积分榜首呢

现在已经跌出前4名了 哈哈

1
#106goJhou回复于2019-07-08 20:31:04
#105 驴宝宝来了回复
楼主好棒  

那是,可是在积分榜首呢

0
#105驴宝宝来了回复于2019-07-08 20:02:51

楼主好棒

 

0
#104青林939回复于2019-06-19 20:46:38

楼主能留个qq嘛,很急

0
#103goJhou回复于2019-03-23 23:29:47
#102 荒墨丶迷失回复
不客气 后续还有更多的最新分享

期待荒墨的后续分享~

0
#102荒墨丶迷失回复于2019-03-22 13:41:22
#101 堕落的诸侯回复
感谢楼主的帖子,我刚接触语音识别这方面,对我很有帮助 ,感谢

不客气 后续还有更多的最新分享

1
#101堕落的诸侯回复于2019-03-22 13:37:01

感谢楼主的帖子,我刚接触语音识别这方面,对我很有帮助 ,感谢

0
#100荒墨丶迷失回复于2018-12-23 19:08:35
#98 外星生物狮子回复
设置per参数之后在输入链接下载下来之后用播放器播放还是男声朗读  在百度语音文档查的per是设置 男音女音的参数,但是确实不好用
展开

确实没遇到过你这种情况 提交bug问问 或者直接代码测试试试

1
#99goJhou回复于2018-12-22 11:08:56
#98 外星生物狮子回复
设置per参数之后在输入链接下载下来之后用播放器播放还是男声朗读  在百度语音文档查的per是设置 男音女音的参数,但是确实不好用
展开

可能是会是bug。实在测不出右上角工单看看官方怎么说

0
#98外星生物狮子回复于2018-12-22 09:29:22
#96 goJhou回复
body里应该是需要缓存的pcm流吧?一半语音合成我都放在后台做,没在js里试过
展开

设置per参数之后在输入链接下载下来之后用播放器播放还是男声朗读  在百度语音文档查的per是设置 男音女音的参数,但是确实不好用

0
#97外星生物狮子回复于2018-12-22 09:26:45
#95 荒墨丶迷失回复
body里面乱码的 应该是你用URL post传参数的时候 没有传UTF-8这个编码格式嘛
展开

post传参已经设置utf-8了  

0
#96goJhou回复于2018-12-22 00:28:44
#94 外星生物狮子回复
用postman 测试了  tests 的status状态是 200OK 但是body里面全都乱码不知道什么原因,可能是音频链接就这样
展开

body里应该是需要缓存的pcm流吧?一半语音合成我都放在后台做,没在js里试过

1
#95荒墨丶迷失回复于2018-12-21 23:07:37
#94 外星生物狮子回复
用postman 测试了  tests 的status状态是 200OK 但是body里面全都乱码不知道什么原因,可能是音频链接就这样
展开

body里面乱码的 应该是你用URL post传参数的时候 没有传UTF-8这个编码格式嘛

2
#94外星生物狮子回复于2018-12-21 16:30:58
#91 goJhou回复
先用postman试一下。

用postman 测试了  tests 的status状态是 200OK 但是body里面全都乱码不知道什么原因,可能是音频链接就这样

0
#93外星生物狮子回复于2018-12-21 15:57:59
#92 荒墨丶迷失回复
看上去这个请求没问题呢 你这个URL可以用postman测试也是这样嘛
展开

直接在网上下载下来之后也是男声,语速参数和中英参数都是好用的 只有发音没有作用

0
#92荒墨丶迷失回复于2018-12-21 12:40:24
#90 外星生物狮子回复
您好  我有问题想请教您一下  如果方便的话帮忙看一下好吗 我在前端js 写了一个语音的 url   '<source id="tts_source_id" src="http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&per=1&spd=4&text=123456" type="audio/mpeg">';   参数per  不管是1 2 3 4 都是 男声发音 ,能否帮忙解答一下 ,万分感谢
展开

看上去这个请求没问题呢 你这个URL可以用postman测试也是这样嘛

2
#91goJhou回复于2018-12-21 12:39:33
#90 外星生物狮子回复
您好  我有问题想请教您一下  如果方便的话帮忙看一下好吗 我在前端js 写了一个语音的 url   '<source id="tts_source_id" src="http://tts.baidu.com/text2audio?lan=zh&ie=UTF-8&per=1&spd=4&text=123456" type="audio/mpeg">';   参数per  不管是1 2 3 4 都是 男声发音 ,能否帮忙解答一下 ,万分感谢
展开

先用postman试一下。

1
#90外星生物狮子回复于2018-12-21 09:50:18

您好  我有问题想请教您一下  如果方便的话帮忙看一下好吗

我在前端js 写了一个语音的 url   '';   参数per  不管是1 2 3 4 都是 男声发音 ,能否帮忙解答一下 ,万分感谢

1
#89荒墨丶迷失回复于2018-12-08 22:15:03
#88 goJhou回复
不止是谷歌,麦克风&摄像头的流,必须要通过ssl协议才能向上层传递

我最近想到了一个改进方式就是 用Java客户端来录音 到时候试试效果...

2
TOP
切换版块