uni-app微信小程序+Java实现百度语音识别

1.准备工作

由于微信小程序和百度语音识别的记录博客少之又少,所以这篇博客就诞生了。

注册登录百度AI开放平台(http://ai.baidu.com/)
找到语音技术 - 应用列表,创建应用,填写相应信息,语音包名选择不需要
uni-app微信小程序+Java实现百度语音识别_第1张图片
创建完成后可以找到:应用列表点击查看App ID、API Key、Secret Key
在这里插入图片描述
注意要领取免费赠送次数,有15万次的短语音识别,我已经用掉94次,不用白不用
uni-app微信小程序+Java实现百度语音识别_第2张图片

2.思路和uni-app开发

1.思路

使用uni-app官方代码,经测试得出经过录音会在小程序上出现临时文件,我们就把这临时文件上传到服务器上供百度语音识别,然后把识别的内容返回到小程序前端展示。

2.uni-app端开发

<template>
	<view>
		
		<view style="padding: 40% 5%;font-size: 40rpx;text-align: center;margin-bottom: 5%;">
			<text>以下是识别内容:</text>
		</view>
		<view style="font-size: 40rpx;text-align: center;">
			<text>{{sbinfo}}</text>
		</view>
		<view style="padding: 50% 5%;">
			<button @touchstart="gtouchstart()" @touchend="gtouchend()" style="background-color: #00CD98;color: #fff;">请长按语音识别</button>
		</view>
	</view>
</template>
<script>
	const recorderManager = uni.getRecorderManager();
	const innerAudioContext = uni.createInnerAudioContext();

	innerAudioContext.autoplay = true;

	export default {
		data() {
			return {
				voicePath: '',
				sbinfo: '',
				timeOutEvent: 0, //计时器
			}
		},
		onLoad() {
			let self = this;
			recorderManager.onStop(function(res) {
				console.log("录音文件属性");
				console.log(res);
				if (res.duration > 60000) {
					uni.showToast({
						icon: 'none',
						position: 'bottom',
						title: '说话时间过长,请控制在60秒内'
					});
				} else {
					self.voicePath = res.tempFilePath;
					if (self.voicePath != null || self.voicePath != '') {
						self.uploadRecord(self.voicePath);
					}
				}

			});
		},
		methods: {
			//开始按
			gtouchstart(item) {
				var self = this;
				this.timeOutEvent = setTimeout(function() {
					/* 开始录音 */
					self.startRecord()
					uni.showToast({
						// icon: 'none',
						image: "../../../static/images/publicity/yysb.png",
						position: 'bottom',
						title: '取消长按识别',
						duration: 60000
					});
				}, 100); //这里设置定时器,定义长按100毫秒触发长按事件
				return false;
			},
			//手释放,则取消长按事件,此时可以执行onclick事件
			gtouchend() {
				/* 结束录音 */
				this.endRecord();
				uni.hideToast();
				clearTimeout(this.timeOutEvent); //清除定时器
				return false;
			},
			uploadRecord(tempFilePath) {
				// tempFilePath为RecorderManager对象返回的录音文件临时地址
				console.log("临时文件:");
				console.log(tempFilePath)
				//正式测试
				const uploadTask = uni.uploadFile({
					url: 'http://192.168.1.101:8080/zh_fsxwh/wxgl/XwhUpload.action',
					filePath: tempFilePath, //录音结束后返回的临时路径
					name: 'upload', // 文件对应的 key值对象名称
					header: {
						'content-type': 'multipart/form-data'
					},
					success: (res) => {
						this.sbinfo = res.data;
						console.log(res);
					},
					fail: (res) => {
						console.log("上传失败" + res);
					}
				})
			},
			startRecord() {
				console.log('开始录音');
				let options = {
					duration: 60000, // 指定录音的时常,单位ms
					sampleRate: 16000, // 采样率 8000(原始数)
					numberOfChannels: 1, // 录音通道数
					encodeBitRate: 96000, // 编码码率 48000(原始数)
					format: 'PCM', // 音频格式
					// format: 'MP3', // 音频格式
					frameSize: 50, // 指定帧大小,单位KB 5(原始数)
				};
				recorderManager.start(options);
			},
			endRecord() {
				console.log('录音结束');
				recorderManager.stop();
			}
		}
	}
</script>

<style>

</style>

对于以上代码的注意事项:

  1. 微信小程序调用uploadFile在真机上测试不能进行上传,一直报错uploadFile:fail Connection refused
    碰到以上问题,只要是小程序的uploadFile的,第一步检测是否有在微信公众平台|小程序配置上传域名,才可以在真机使用。
    第二,检查上传的头文件的Content-Type是否是multipart/form-data,表示表单提交的。

  2. 为方便测试,还有一种方法:把请求地址的ip更换本机网络的ipv4的地址,真机请求务必在同一个网络下,也可以实现上传文件。 不需要在微信公众平台上配置上传域名。如:127.0.0.1:8080;更换成ipv4地址:192.168.1.101:8080

  3. 针对我在网上看到先将前端的mp3格式的录音文件上传到后台服务器转成pcm格式再进行识别也是可以的,在于你的业务场景,我前端不需要播放录音,所以只是简单的把pcm录音文件格式上传识别成文字发送给前端展示。

3.Java后台代码

maven导入百度sdk,或者jar包导入

<dependency>
    <groupId>com.baidu.aip</groupId>
    <artifactId>java-sdk</artifactId>
    <version>4.12.0</version>
</dependency>

jar包连接:https://pan.baidu.com/s/1VR2PVUto4Ps59ru5pRewaA
提取码:njev

由于本次项目是struts2项目,所以就贴上struts2的文件上传代码,大家可以自己编写springMVC的文件上传代码

import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.UUID;

import javax.servlet.ServletContext;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.struts2.ServletActionContext;

public class WxProgram {
	private List<File> upload;
	
	private List<String> uploadContentType;
	
	private List<String> uploadFileName;
	
	private String result;
	
	private String newName;

	public List<File> getUpload() {
		return upload;
	}

	public void setUpload(List<File> upload) {
		this.upload = upload;
	}

	public List<String> getUploadContentType() {
		return uploadContentType;
	}

	public void setUploadContentType(List<String> uploadContentType) {
		this.uploadContentType = uploadContentType;
	}

	public List<String> getUploadFileName() {
		return uploadFileName;
	}

	public void setUploadFileName(List<String> uploadFileName) {
		this.uploadFileName = uploadFileName;
	}

	public String getResult() {
		return result;
	}

	public void setResult(String result) {
		this.result = result;
	}

	public String getNewName() {
		return newName;
	}

	public void setNewName(String newName) {
		this.newName = newName;
	}
	public String WxuploadFile() throws IOException {
	   ServletContext sc = ServletActionContext.getServletContext();
	   String rootPath = sc.getRealPath("/wxUpload");
	   String str ="";
//        String rootPath="E:\\wxUpload";
		File file = new File(rootPath);
		System.out.println("文件数量"+this.upload.size());
		if(!file.exists()){
			System.out.println("文件路径"+rootPath);
			file.mkdir();
		}
		if(this.upload.size()==1) {
			this.setNewName(UUID.randomUUID().toString().replace("-", "")+"."
					+FilenameUtils.getExtension(uploadFileName.get(0)));
			FileUtils.copyFile(upload.get(0), new File(rootPath,this.getNewName()));
			System.out.println("文件名称"+this.getNewName());
			String fileParh = rootPath+"\\"+this.getNewName();
			System.out.println("文件路径"+fileParh);
			//百度识别
			VoiceRecognition recognition = new VoiceRecognition();
			try {
				Boolean i = recognition.recognizeVoice(fileParh);
				if(i) {
					str = recognition.getResultText();
					//停止1秒执行下面内容
					Thread.sleep(1 * 1000);
					File fe = new File(rootPath,this.getNewName()); 
					//如果文件在本地磁盘存在即删除
					if (fe.isFile() && fe.exists()) {  
					    fe.delete();  
					} 
				}else {
					str = "识别错误,请稍后重试。";
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}else {
			str="文件上传数量过多";
		}
		return str;
	}
}

百度语音识别:
为方便大家能在java工程下本地文件测试,分享测试语音文件:
百度网盘链接: https://pan.baidu.com/s/16ajM6agWCQv0Gp6sa3K3kg
提取码: i4hs


import java.io.File;

import org.json.JSONObject;

import com.baidu.aip.speech.AipSpeech;

public class VoiceRecognition {
	 // 设置APPID/AK/SK
    // 百度AI开发平台的控制台中创建一个语音应用即可获得
    public static final String APP_ID = "";
    public static final String API_KEY = "";
    public static final String SECRET_KEY = "";
 
    private static final AipSpeech aipSpeech = getAipSpeech();
 
    private static String resultText;
 
    public static String getResultText() {
        return resultText;
    }
 
    //本地文件测试
    public static void main(String[] args){
    	VoiceRecognition voiceRecognition = new VoiceRecognition();
        try {
			if(voiceRecognition.recognizeVoice("C:\\Users\\Administrator\\Desktop\\sample\\MscInvisibleDemo\\test.pcm")){
			    System.out.println("结果为:" + voiceRecognition.getResultText());
			}else{
			    System.out.println("识别错误");
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
    }
 
    public static AipSpeech getAipSpeech(){
        // 初始化一个AipSpeech
        AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
 
        // 可选:设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);
 
        // 可选:设置代理服务器地址, http和socket二选一,或者均不设置
        //client.setHttpProxy("proxy_host", proxy_port);  // 设置http代理
        //client.setSocketProxy("proxy_host", proxy_port);  // 设置socket代理
 
        // 可选:设置log4j日志输出格式,若不设置,则使用默认配置
        // 也可以直接通过jvm启动参数设置此环境变量
        // System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
 
        return client;
    }
    
    public boolean recognizeVoice(String filePath) throws Exception{
        // 对语音文件进行识别
        String path = new File(filePath).getAbsolutePath();
        System.out.println(path);
        JSONObject asrRes = aipSpeech.asr(path, "pcm", 16000, null);
        System.out.println(asrRes);
 
        if(asrRes.getString("err_msg").equals("success.")){
            resultText = asrRes.getJSONArray("result").getString(0);
            return true;
        }else{
            return false;
        }
        // 对语音二进制数据进行识别
        /*byte[] data = new byte[0];     //readFileByBytes仅为获取二进制数据示例
        try {
            data = Util.readFileByBytes(path);
        } catch (IOException e) {
            e.printStackTrace();
        }
        JSONObject asrRes2 = client.asr(data, "pcm", 16000, null);
        System.out.println(asrRes2);*/

    }
}

以下是效果展示

uni-app微信小程序+Java实现百度语音识别_第3张图片
uni-app微信小程序+Java实现百度语音识别_第4张图片
在这里插入图片描述

你可能感兴趣的:(语音识别,微信小程序,java)