Android 利用 Voice Search语音接口 进行语音识别结果太不准
公司最近在做语音识别的项目,但是又要求要录音,纠结了很久,后来发现谷歌的借口了,但是去识别不准。唉。。。。直接上代码大神们帮我看看吧,小弟在此谢过了。
public class MainActivity extends Activity {/ 日志TAG.private static final String TAG = "MainActivity";// title的文本内容.private TextView yuyinShow;private static String mFileName = null;private static String mNewFileName = null;private static String mshuFileName = null;private static String result;private byte[] head;private byte[] body;private Button btnok, btnCancel, btnSb;// 音频获取源private int audioSource = MediaRecorder.AudioSource.MIC;// 设置音频采样率,44100是目前的标准,但是某些设备仍然支持22050,16000,11025private static int sampleRateInHz = 44100;// 设置音频的录制的声道CHANNEL_IN_STEREO为双声道,CHANNEL_CONFIGURATION_MONO为单声道private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;// 音频数据格式:PCM 16位每个样本。保证设备支持。PCM 8位每个样本。不一定能得到设备支持。private static int audioFormat = AudioFormat.ENCODING_PCM_16BIT;// 缓冲区字节大小private int bufferSizeInBytes = 0;private MediaPlayer mPlayer = null;private AudioRecord audioRecord;private boolean isRecord = false;// 设置正在录制的状态private ProgressDialog dialog;boolean mStartPlaying = false;boolean playOK = false;String text = "";Handler updateDate = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 2:btnCancel.setEnabled(true);break;case 3:showOkCircleProgressDialog("识别中", "正在识别请稍等");Toast.makeText(MainActivity.this, "开始网络了啊!!!",Toast.LENGTH_SHORT).show();yuyinShow.setText("");break;case 4:// startPlaying(mzhuanFileName);break;case 5:closeCircleProgressDialog();Toast.makeText(MainActivity.this, "开始打分喽!!", Toast.LENGTH_SHORT).show();startPlaying(mshuFileName);yuyinShow.setText(result);break;}}};@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);yuyinShow = (TextView) findViewById(R.id.yuyinShow);btnok = (Button) findViewById(R.id.btn_ok);// btnSb = (Button) findViewById(R.id.btn_ok);mFileName = Environment.getExternalStorageDirectory().getAbsolutePath();mFileName += "/reverseme.pcm";mNewFileName = Environment.getExternalStorageDirectory().getAbsolutePath();mNewFileName += "/reverNew.wav";mshuFileName = Environment.getExternalStorageDirectory().getAbsolutePath();mshuFileName += "/shuNew.wav";// 获得缓冲区字节大小bufferSizeInBytes = AudioRecord.getMinBufferSize(sampleRateInHz,channelConfig, audioFormat);// 创建AudioRecord对象btnCancel = (Button) findViewById(R.id.btn_cancel);PackageManager pm = getPackageManager();List<ResolveInfo> list = pm.queryIntentActivities(new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH), 0);if (list.size() != 0) {// 语音识别可用btnok.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubif (!isRecord) {btnok.setText("停止录制");body = null;audioRecord = new AudioRecord(audioSource,sampleRateInHz, channelConfig, audioFormat,bufferSizeInBytes);onRecord(isRecord);} else {btnok.setText("开始录制");stopRecord();}}});} else {// 语音识别不可用btnok.setEnabled(false);}btnCancel.setEnabled(false);ex_bindListenters();}@Overrideprotected void onActivityResult(int requestCode, int resultCode,Intent intent) {// requestCode 自己传的代码// resultCode 返回的结果状态// TODO Auto-generated method stubif (5 == requestCode && resultCode == RESULT_OK) {Toast.makeText(MainActivity.this, "返回结果正常", Toast.LENGTH_SHORT).show();ArrayList<String> result = intent.getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS); // 获取语言的字符String resultString = result.get(0);yuyinShow.setText(resultString);}super.onActivityResult(requestCode, resultCode, intent);}// 当录音按钮被click时调用此方法,开始或停止录音private void onRecord(boolean start) {if (!start) {startRecord();}}// 当播放按钮被click时调用此方法,开始或停止播放private void onPlay(boolean start) {if (start) {startPlaying(mNewFileName);} else {stopPlaying();}}private void startRecord() {audioRecord.startRecording();// 让录制状态为trueisRecord = true;// 开启音频文件写入线程new Thread(new AudioRecordThread()).start();}private void stopRecord() {close();}private void close() {if (audioRecord != null) {isRecord = false;// 停止文件写入audioRecord.stop();audioRecord.release();// 释放资源audioRecord = null;}}class AudioRecordThread implements Runnable {@Overridepublic void run() {writeDateTOFile();// 往文件中写入裸数据copyWaveFile(mFileName, mNewFileName);// 给裸数据加上头文件updateDate.sendEmptyMessage(2);}}/*** 这里将数据写入文件,但是并不能播放,因为AudioRecord获得的音频是原始的裸音频,* 如果需要播放就必须加入一些格式或者编码的头信息。但是这样的好处就是你可以对音频的 裸数据进行处理,比如你要做一个爱说话的TOM* 猫在这里就进行音频的处理,然后重新封装 所以说这样得到的音频比较容易做一些音频的处理。*/private void writeDateTOFile() {// new一个byte数组用来存一些字节数据,大小为缓冲区大小byte[] audiodata = new byte[bufferSizeInBytes];int mPCMSize = 0;FileOutputStream fos = null;int readsize = 0;try {File file = new File(mFileName);if (file.exists()) {file.delete();}fos = new FileOutputStream(file);// 建立一个可存取字节的文件} catch (Exception e) {e.printStackTrace();}while (isRecord == true) {readsize = audioRecord.read(audiodata, 0, bufferSizeInBytes);if (AudioRecord.ERROR_INVALID_OPERATION != readsize) {try {fos.write(audiodata);copybyte(audiodata);} catch (IOException e) {e.printStackTrace();}}}try {fos.close();// 关闭写入流} catch (IOException e) {e.printStackTrace();}}public void copybyte(byte[] audiodata) {if (body != null) {byte[] c = new byte[body.length + audiodata.length];System.arraycopy(body, 0, c, 0, body.length);System.arraycopy(audiodata, 0, c, body.length, audiodata.length);body = c;Log.i(TAG, "" + body.length);} else {body = audiodata;}}// public void writeDateshengyi(byte[] audiodata) {// FileOutputStream fos = null;// int readsize = 0;// try {// File file = new File(mzhuanFileName);// if (file.exists()) {// file.delete();// }// fos = new FileOutputStream(file);// 建立一个可存取字节的文件//// fos.write(audiodata);//// fos.close();// 关闭写入流// updateDate.sendEmptyMessage(4);// } catch (IOException e) {// e.printStackTrace();// }// }// 这里得到可播放的音频文件public void copyWaveFile(String inFilename, String outFilename) {FileInputStream in = null;FileOutputStream out = null;long totalAudioLen = 0;long totalDataLen = totalAudioLen + 36;long longSampleRate = sampleRateInHz;int channels = 2;long byteRate = 16 * sampleRateInHz * channels / 8;byte[] data = new byte[bufferSizeInBytes];try {in = new FileInputStream(inFilename);out = new FileOutputStream(outFilename);totalAudioLen = in.getChannel().size();totalDataLen = totalAudioLen + 36;util.WriteWaveFileHeader(out, totalAudioLen, totalDataLen,longSampleRate, channels, byteRate);while (in.read(data) != -1) {out.write(data);}in.close();out.close();} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();}}private void startPlaying(String mNewFileName) {mPlayer = new MediaPlayer();try {// 设置要播放的文件mPlayer.setDataSource(mNewFileName);mPlayer.prepare();// 播放之mPlayer.start();} catch (IOException e) {}}// 停止播放private void stopPlaying() {mPlayer.release();mPlayer = null;}private void postHttpURLConnection() {if (head == null && body == null) {} else {
// byte[] mVoiceData = util.getThreeArray(head, body);new Thread(new PostDateThread()).start();}}class PostDateThread implements Runnable {
// byte[] mVoiceData;
//
// PostDateThread(byte[] mVoiceData) {
// this.mVoiceData = mVoiceData;
// }@Overridepublic void run() {try {// writeDateshengyi(mVoiceData);URL httpUrl = null;httpUrl = new URL("http://www.google.com.hk/speech-api/v1/recognize?xjerr=1&client=chromium&lang=zh-CN&maxresults=1");HttpURLConnection urlConnection = null;urlConnection = (HttpURLConnection) httpUrl.openConnection();urlConnection.setConnectTimeout(7000);urlConnection.setReadTimeout(10000);urlConnection.setDoOutput(true);urlConnection.setDoInput(true);urlConnection.setRequestMethod("POST");urlConnection.setUseCaches(false);// urlConnection.setAllowUserInteraction(true);urlConnection.setInstanceFollowRedirects(true);urlConnection.setRequestProperty("User-Agent", "Mozilla/5.0");urlConnection.setRequestProperty("Content-Type","audio/L16; rate=16000");// urlConnection.setRequestProperty("Connection", "Keep-Alive");DataOutputStream writer = new DataOutputStream(urlConnection.getOutputStream());writer.write(util.readfileByYte(mNewFileName));writer.flush();writer.close();FileOutputStream out = null;out = new FileOutputStream(mshuFileName);out.write(util.readfileByYte(mNewFileName));out.close();// FileInputStream input = new FileInputStream();
// byte[] buffer = new byte[bufferSizeInBytes]; //
// 必须用户自己创建一个buffer。
// int read = input.read(buffer);
// while (read != -1) // 判断文件读完的条件
// {
// writer.write(buffer, 0, read);
// read = input.read(buffer);
// }
// writer.flush();
// writer.close();
// input.close();result = "";updateDate.sendEmptyMessage(3);if (urlConnection.getResponseCode() == 200) {// 为输出创建BufferReaderString inputLine = null;// 得到读取的内容InputStreamReader reder = new InputStreamReader(urlConnection.getInputStream(), "utf-8");BufferedReader breader = new BufferedReader(reder);// 使用循环来读取获得的数据while ((inputLine = breader.readLine()) != null) {// // 我们在每一行后面加\nresult += inputLine + "\n";JSONObject jsonObject = new JSONObject(inputLine);JSONArray jsonArray = jsonObject.optJSONArray("hypotheses");jsonObject = jsonArray.optJSONObject(0);if (jsonObject != null) {result = jsonObject.optString("utterance","对不起未能识别您的语音请重试!");} else {result = "对不起未能识别您的语音请重试!";}updateDate.sendEmptyMessage(5);}Log.i(TAG, result);}} catch (Exception e) {// TODO Auto-generated catch blocke.printStackTrace();}}}private void ex_bindListenters() {btnCancel.setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stub// onPlay(mStartPlaying);if (mStartPlaying) {postHttpURLConnection();btnCancel.setText("停止播放");} else {btnCancel.setText("播放录音");}mStartPlaying = !mStartPlaying;}});}public ProgressDialog showOkCircleProgressDialog(String title, String msg) {if (dialog != null) {try {dialog.cancel();dialog = null;} catch (Exception e) {}}dialog = new ProgressDialog(this);dialog.setIndeterminate(false);dialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);dialog.setTitle(title);dialog.setMessage(msg);try {dialog.show();Log.e("iitalk", "显示等待框了啊??");} catch (Exception e) {dialog = null;}return dialog;}// // 关闭加载对话框public void closeCircleProgressDialog() {if (dialog != null) {try {dialog.cancel();Log.e("iitalk", "关闭等待框了啊??");dialog = null;} catch (Exception e) {}}}
}
public class util {/*** 这里提供一个头信息。插入这些信息就可以得到可以播放的文件。 为我为啥插入这44个字节,这个还真没深入研究,不过你随便打开一个wav* 音频的文件,可以发现前面的头文件可以说基本一样哦。每种格式的文件都有 自己特有的头文件。*/public static File readFlacByByte(String fileName) {File file = new File(fileName);InputStream input = null;try {
// System.out.println("yi字节的方式读取文件");input = new FileInputStream(file) ;
// int tempByte = 0;
// while ((tempByte = input.read())!= -1) {System.out.println(tempByte);
//
// }input.close();} catch (Exception e) {e.printStackTrace();return null;// TODO: handle exception}return file;}public static byte[] readfileByYte(String filename) throws IOException {File file = readFlacByByte(filename);long len = file.length();byte[] voice = new byte[(int) len];FileInputStream fileInputStream = new FileInputStream(file);fileInputStream.read(voice, 0, (int)len);fileInputStream.close();return voice;}public static byte[] getThreeArray(byte[] head, byte[] body) {if (body != null) {byte[] c = new byte[head.length + body.length];System.arraycopy(head, 0, c, 0, head.length);System.arraycopy(body, 0, c, head.length, body.length);return c;} else {return head;}}public static void WriteWaveFileHeader(FileOutputStream out, long totalAudioLen, long totalDataLen, long longSampleRate, int channels, long byteRate) throws IOException { byte[] header = new byte[44]; header[0] = 'R'; // RIFF/WAVE header header[1] = 'I'; header[2] = 'F'; header[3] = 'F'; header[4] = (byte) (totalDataLen & 0xff); header[5] = (byte) ((totalDataLen >> 8) & 0xff); header[6] = (byte) ((totalDataLen >> 16) & 0xff); header[7] = (byte) ((totalDataLen >> 24) & 0xff); header[8] = 'W'; header[9] = 'A'; header[10] = 'V'; header[11] = 'E'; header[12] = 'f'; // 'fmt ' chunk header[13] = 'm'; header[14] = 't'; header[15] = ' '; header[16] = 16; // 4 bytes: size of 'fmt ' chunk header[17] = 0; header[18] = 0; header[19] = 0; header[20] = 1; // format = 1 header[21] = 0; header[22] = (byte) channels; header[23] = 0; header[24] = (byte) (longSampleRate & 0xff); header[25] = (byte) ((longSampleRate >> 8) & 0xff); header[26] = (byte) ((longSampleRate >> 16) & 0xff); header[27] = (byte) ((longSampleRate >> 24) & 0xff); header[28] = (byte) (byteRate & 0xff); header[29] = (byte) ((byteRate >> 8) & 0xff); header[30] = (byte) ((byteRate >> 16) & 0xff); header[31] = (byte) ((byteRate >> 24) & 0xff); header[32] = (byte) (2 * 16 / 8); // block align header[33] = 0; header[34] = 16; // bits per sample header[35] = 0; header[36] = 'd'; header[37] = 'a'; header[38] = 't'; header[39] = 'a'; header[40] = (byte) (totalAudioLen & 0xff); header[41] = (byte) ((totalAudioLen >> 8) & 0xff); header[42] = (byte) ((totalAudioLen >> 16) & 0xff); header[43] = (byte) ((totalAudioLen >> 24) & 0xff); out.write(header, 0, 44); }
}
Android 利用 Voice Search语音接口 进行语音识别结果太不准相关推荐
- Android利用RecognizerIntent识别语音并简单实现打电话动作
关于Android利用RecognizerIntent识别语音并简单实现打电话,具体看实现代码如下: package com.example.recognizerintentactivity;impo ...
- Android 讯飞离线语音听写/离线语音识别SDK
平台 Android + 讯飞离线语音SDK SDK包 下载路径及方法见讯飞官方SDK文档: 离线语音听写 Android SDK 文档 # 在开发者控制台, 可以直接下载SDK. SDK包中的文件结 ...
- Android基于讯飞语音SDK实现语音识别
一.准备工作 1.你需要android手机应用开发基础 2.科大讯飞语音识别SDK android版 3.科大讯飞语音识别开发API文档 4.android手机 关于科大讯飞SDK及API文档,请到科 ...
- 微信公众号之语音接口
文章目录 简介 微信开发者工具的使用 语音接口 代码 语音识别 每日一笑 专栏目录请点击 简介 当验证信息通过后,我们一般就会微信提供的接口 在使用微信提供的接口前,我们需要调用api来验证当前,我们 ...
- Android 语音识别+语音搜索源码 Voice Search
http://blog.csdn.net/u014051380/article/details/21114389 1.判断是否已安装语音搜索功能 [java] view plaincopyprint? ...
- android之基于百度语音合讯飞语音识别的语音交互
app:http://fir.im/gval 这里面包含拨盘UI 开发平台:android studio 模拟一个 原始需求如下: 1) 在界面上,通过声音提示用户讲话: 2) 将语音内容转换为 ...
- 利用微信网页录音接口实现语音搜索
微信网页接口有3个录音相关接口 开始录音接口 wx.startRecord(); 停止录音接口 wx.stopRecord({ success: function (res) { var localI ...
- python科大讯飞语音接口不能用_【】科大讯飞语音识别支持python吗
科大讯飞语音识别支持python吗 我上过一门课的大作业是用Python自己实现一个小型语音识别系统.不过,如果你不是专攻这个方向的,而只是想使用现成的语音识别模块的话,你不会想自己写的. pytho ...
- unity学习笔记-番外(接入百度和轻语的AI智能接口实现语音识别和语音播放)
接入百度和轻语的AI智能接口实现语音识别和语音播放 语音识别 思路 代码 语音合成 思路 总结 语音识别 思路 先在百度和轻语申请接口,获得appkey和secretkey(这是为了获得鉴权,也就是t ...
最新文章
- 如何优雅而又不失内涵的在centos7下安装tree命令
- php获取日期中的月份,年份
- jstack调试_增压的jstack:如何以100mph的速度调试服务器
- 出现这些迹象,说明你面试可能没戏了
- 程序员应学习蜡笔小新的心态
- Unity代码里的Position和界面上的Position
- SCCM2012软件更新(WSUS补丁)同步成功无法获取补丁问题
- 2021李宏毅机器学习课程笔记——Auto Encoder
- android 控制音乐,Android音乐控制接口RemoteController使用
- 孙鑫VC学习笔记:第十三讲 (二) 设置文档标题
- Xshell6 + Xftp6 绿色破解永久授权激活版 免安装 解压即用,最好的SSH工具(Xshell 6 plus套件)
- python 大智慧自定义数据_大智慧自定义指数
- 华为手机如何换成鸿蒙,如何将自己的华为手机升级成鸿蒙系统
- Origin2021学习版申请与安装
- 时序分析-利用深度时空残差网络预测城市范围的交通流量
- Problem K. Road Network - ACPC2015(求树的直径 dp)
- EVE-NG模拟器简述
- 词法分析器的构成(含源代码)
- 网站广告联盟点击作弊概述(转)
- 关于数据结构的内存分配问题