当前位置:   article > 正文

利用科大讯飞API实现语音识别,SWT实现客户端封装_科大讯飞的语音识别api免费可用多久啊

科大讯飞的语音识别api免费可用多久啊

利用科大讯飞API来实现语音识别,利用Java SWT来封装界面。

科大讯飞API

语音识别的API可以免费试用5小时,许多厂家已经开放了语音识别的API例如百度,阿里等,这里使用科大讯飞的API来实现。其实也可以自己训练数据来实现语音识别的功能,只不过识别率可能不是太高,具体实现原理可以参考如下:日后有时间可以研究一下。

https://blog.ailemon.me/2018/08/29/asrt-a-chinese-speech-recognition-system/

https://github.com/nl8590687/ASRT_SpeechRecognition

声学模型通过采用卷积神经网络(CNN)和连接性时序分类(CTC)方法,使用大量中文语音数据集进行训练,将声音转录为中文拼音,并通过语言模型,将拼音序列转换为中文文本。

登录科大讯飞网址:https://www.xfyun.cn/services/lfasr

   

下载Java  SDK

   

新建应用,获取appId以及secret

       

在SDK中配置appId以及secret

  1. # APP ID
  2. app_id=
  3. # secret key
  4. secret_key=
  5. # we support both http and https prototype
  6. lfasr_host=http://raasr.xfyun.cn/api
  7. # file piece size
  8. file_piece_size=10485760
  9. # store path: this is not the store path for the result json file, but the path for the file piece during upload
  10. store_path=F://

Demo中给出一个测试用例:

使用过程如下:

初始化LFASRClient实例

  1. // 初始化LFASRClient实例
  2. LfasrClientImp lc = null;
  3. try {
  4. lc = LfasrClientImp.initLfasrClient();
  5. } catch (LfasrException e) {
  6. // 初始化异常,解析异常描述信息
  7. Message initMsg = JSON.parseObject(e.getMessage(), Message.class);
  8. System.out.println("ecode=" + initMsg.getErr_no());
  9. System.out.println("failed=" + initMsg.getFailed());
  10. }

上传语音文件

  1. // 上传音频文件
  2. Message uploadMsg = lc.lfasrUpload(local_file, type, params);
  3. // 判断返回值
  4. int ok = uploadMsg.getOk();
  5. if (ok == 0) {
  6. // 创建任务成功
  7. task_id = uploadMsg.getData();

循环等待任务处理结果:

  1. // 循环等待音频处理结果
  2. while (true) {
  3. try {
  4. // 等待20s在获取任务进度
  5. Thread.sleep(sleepSecond * 1000);
  6. System.out.println("waiting ...");
  7. } catch (InterruptedException e) {
  8. e.printStackTrace();
  9. }
  10. try {
  11. // 获取处理进度
  12. Message progressMsg = lc.lfasrGetProgress(task_id);
  13. // 如果返回状态不等于0,则任务失败
  14. if (progressMsg.getOk() != 0) {
  15. System.out.println("task was fail. task_id:" + task_id);
  16. System.out.println("ecode=" + progressMsg.getErr_no());
  17. System.out.println("failed=" + progressMsg.getFailed());
  18. return;
  19. } else {
  20. ProgressStatus progressStatus = JSON.parseObject(progressMsg.getData(), ProgressStatus.class);
  21. if (progressStatus.getStatus() == 9) {
  22. // 处理完成
  23. System.out.println("task was completed. task_id:" + task_id);
  24. break;
  25. } else {
  26. // 未处理完成
  27. System.out.println("task is incomplete. task_id:" + task_id + ", status:" + progressStatus.getDesc());
  28. continue;
  29. }
  30. }
  31. } catch (LfasrException e) {
  32. // 获取进度异常处理,根据返回信息排查问题后,再次进行获取
  33. Message progressMsg = JSON.parseObject(e.getMessage(), Message.class);
  34. System.out.println("ecode=" + progressMsg.getErr_no());
  35. System.out.println("failed=" + progressMsg.getFailed());
  36. }
  37. }

获取最终结果:

  1. // 获取任务结果
  2. try {
  3. Message resultMsg = lc.lfasrGetResult(task_id);
  4. // 如果返回状态等于0,则获取任务结果成功
  5. if (resultMsg.getOk() == 0) {
  6. // 打印转写结果
  7. System.out.println(resultMsg.getData());
  8. System.out.println(Test.getFinalResult(resultMsg.getData()));
  9. } else {
  10. // 获取任务结果失败
  11. System.out.println("ecode=" + resultMsg.getErr_no());
  12. System.out.println("failed=" + resultMsg.getFailed());
  13. }
  14. } catch (LfasrException e) {
  15. // 获取结果异常处理,解析异常描述信息
  16. Message resultMsg = JSON.parseObject(e.getMessage(), Message.class);
  17. System.out.println("ecode=" + resultMsg.getErr_no());
  18. System.out.println("failed=" + resultMsg.getFailed());
  19. }

resultMsg.getData()返回一个json数组,里面有多个元素,在此将“onebest”元素取出拼接组成最终的输出文本。

  1. String str = "[{\"bg\":\"0\",\"ed\":\"2180\",\"onebest\":\"科大讯飞是中国最大!\",\"si\":\"0\",\"speaker\":\"0\","
  2. + "\"wordsResultList\":[{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"6\",\"wordEd\":\"114\",\"wordsName\":"
  3. + "\"科大讯飞\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"118\",\"wordEd\":\"147\",\"wordsName\""
  4. + ":\"\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"148\",\"wordEd\":\"193\",\"wordsName\":\"中国\","
  5. + "\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"194\",\"wordEd\":\"213\",\"wordsName\":\"\","
  6. + "\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"214\",\"wordEd\":\"218\",\"wordsName\":\"\","
  7. + "\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"0.0000\",\"wordBg\":\"218\",\"wordEd\":\"218\",\"wordsName\":\"\","
  8. + "\"wp\":\"p\"},{\"alternativeList\":[],\"wc\":\"0.0000\",\"wordBg\":\"218\",\"wordEd\":\"218\",\"wordsName\":\"\","
  9. + "\"wp\":\"g\"}]},{\"bg\":\"2190\",\"ed\":\"3080\",\"onebest\":\"的智能。\",\"si\":\"1\",\"speaker\":\"0\","
  10. + "\"wordsResultList\":[{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"15\",\"wordEd\":\"42\","
  11. + "\"wordsName\":\"\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"47\",\"wordEd\":\"89\","
  12. + "\"wordsName\":\"智能\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"0.0000\",\"wordBg\":\"89\",\"wordEd\":\"89\","
  13. + "\"wordsName\":\"\",\"wp\":\"p\"},{\"alternativeList\":[],\"wc\":\"0.0000\",\"wordBg\":\"89\",\"wordEd\":\"89\","
  14. + "\"wordsName\":\"\",\"wp\":\"g\"}]},{\"bg\":\"3090\",\"ed\":\"4950\",\"onebest\":\"语音技术提供商,\",\"si\":\"2\","
  15. + "\"speaker\":\"0\",\"wordsResultList\":[{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"4\",\"wordEd\":\"46\","
  16. + "\"wordsName\":\"语音\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"47\",\"wordEd\":\"92\","
  17. + "\"wordsName\":\"技术\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"1.0000\",\"wordBg\":\"93\",\"wordEd\":\"164\","
  18. + "\"wordsName\":\"提供商\",\"wp\":\"n\"},{\"alternativeList\":[],\"wc\":\"0.0000\",\"wordBg\":\"164\",\"wordEd\":\"164\","
  19. + "\"wordsName\":\"\",\"wp\":\"p\"}]}]";
  1. public static String getFinalResult(String data){
  2. JSONArray ja = JSONArray.parseArray(data);
  3. StringBuilder sb = new StringBuilder();
  4. for(int i=0; i<ja.size(); i++){
  5. //System.out.println(ja.get(i));
  6. sb.append(JSON.parseObject(ja.get(i).toString()).get("onebest"));
  7. //System.out.println(JSON.parseObject(ja.get(i).toString()).get("onebest"));
  8. }
  9. return sb.toString();
  10. }

SWT界面

直接使用有点费劲,想利用SWT来封装一个客户端,这里使用Eclipse来开发,首先安装SWT环境

参考地址如下:https://www.cnblogs.com/xinyan123/p/6225194.html

下载SWT插件:https://www.eclipse.org/windowbuilder/download.php

                                 

将安装包features以及plugins放入到eclipse安装目录对应文件夹下,重启eclipse

        

新建SWT工程

                                     

新建一个ApplicationWindow

                                    

可以使用图形化界面来进行界面UI设计

                                         

SWT核心实现:开始转换按钮的实现逻辑

  1. //开始转换按钮
  2. Button startThansfer = new Button(container, SWT.NONE);
  3. startThansfer.addSelectionListener(new SelectionAdapter() {
  4. @Override
  5. public void widgetSelected(SelectionEvent e) {
  6. logDetailText.append(datePrefix + "开始转换........" + "\n");
  7. startThansfer.setEnabled(false);
  8. voicePath = voicePathText.getText();
  9. textPath = textPathText.getText();
  10. int status = 0;
  11. Callable<Integer> f = new TransferThread(logDetailText, countDownLatch, datePrefix, voicePath, textPath);
  12. //Callable<Integer> f = new TransferThreadAsyc(parent, logDetailText, countDownLatch, datePrefix, voicePath, textPath);
  13. try {
  14. status = f.call();
  15. } catch (Exception e2) {
  16. // TODO Auto-generated catch block
  17. e2.printStackTrace();
  18. }
  19. try {
  20. countDownLatch.await();
  21. } catch (InterruptedException e1) {
  22. // TODO Auto-generated catch block
  23. e1.printStackTrace();
  24. }
  25. if(status == 1){
  26. logDetailText.append(datePrefix + "转换完成" + "\n");
  27. }else{
  28. logDetailText.append(datePrefix + "转换失败" + "\n");
  29. }
  30. startThansfer.setEnabled(true);
  31. }
  32. });

转换执行线程工作类:

  1. package com.voice.text;
  2. import java.io.FileOutputStream;
  3. import java.util.HashMap;
  4. import java.util.concurrent.Callable;
  5. import java.util.concurrent.CountDownLatch;
  6. import org.eclipse.swt.widgets.Text;
  7. import com.alibaba.fastjson.JSON;
  8. import com.iflytek.msp.cpdb.lfasr.client.LfasrClientImp;
  9. import com.iflytek.msp.cpdb.lfasr.exception.LfasrException;
  10. import com.iflytek.msp.cpdb.lfasr.model.LfasrType;
  11. import com.iflytek.msp.cpdb.lfasr.model.Message;
  12. import com.iflytek.msp.cpdb.lfasr.model.ProgressStatus;
  13. import com.iflytek.voicecloud.lfasr.demo.Test;
  14. public class TransferThread implements Callable<Integer> {
  15. private Text logDetailText;
  16. private CountDownLatch countDownLatch;
  17. private LfasrType type = LfasrType.LFASR_STANDARD_RECORDED_AUDIO;
  18. private int sleepSecond = 20;
  19. private String datePrefix;
  20. private String voicePath;
  21. private String textPath;
  22. public TransferThread(Text logDetailText, CountDownLatch countDownLatch, String datePrefix, String voicePath, String textPath) {
  23. this.logDetailText = logDetailText;
  24. this.countDownLatch = countDownLatch;
  25. this.datePrefix = datePrefix;
  26. this.voicePath = voicePath;
  27. this.textPath = textPath;
  28. }
  29. @Override
  30. public Integer call() throws Exception {
  31. // 初始化LFASRClient实例
  32. LfasrClientImp lc = null;
  33. try {
  34. lc = LfasrClientImp.initLfasrClient();
  35. } catch (LfasrException e) {
  36. // 初始化异常,解析异常描述信息
  37. Message initMsg = JSON.parseObject(e.getMessage(), Message.class);
  38. logDetailText.append(datePrefix + "ecode=" + initMsg.getErr_no() + "\n");
  39. System.out.println("ecode=" + initMsg.getErr_no());
  40. logDetailText.append(datePrefix + "failed=" + initMsg.getFailed() + "\n");
  41. //System.out.println(datePrefix + "failed=" + initMsg.getFailed());
  42. countDownLatch.countDown();
  43. return -1;
  44. }
  45. // 获取上传任务ID
  46. String task_id = "";
  47. HashMap<String, String> params = new HashMap<String, String>();
  48. params.put("has_participle", "true");
  49. //合并后标准版开启电话版功能
  50. //params.put("has_seperate", "true");
  51. try {
  52. // 上传音频文件
  53. Message uploadMsg = lc.lfasrUpload(voicePath, type, params);
  54. // 判断返回值
  55. int ok = uploadMsg.getOk();
  56. if (ok == 0) {
  57. // 创建任务成功
  58. task_id = uploadMsg.getData();
  59. //System.out.println("创建任务成功 task_id=" + task_id);
  60. logDetailText.append(datePrefix + "创建任务成功 task_id=" + task_id + "\n");
  61. } else {
  62. // 创建任务失败-服务端异常
  63. //System.out.println(datePrefix + "ecode=" + uploadMsg.getErr_no());
  64. logDetailText.append(datePrefix + "ecode=" + uploadMsg.getErr_no() + "\n");
  65. //System.out.println(datePrefix + "failed=" + uploadMsg.getFailed());
  66. logDetailText.append(datePrefix + "failed=" + uploadMsg.getFailed() + "\n");
  67. countDownLatch.countDown();
  68. return -1;
  69. }
  70. } catch (LfasrException e) {
  71. // 上传异常,解析异常描述信息
  72. Message uploadMsg = JSON.parseObject(e.getMessage(), Message.class);
  73. //System.out.println(datePrefix + "ecode=" + uploadMsg.getErr_no());
  74. logDetailText.append(datePrefix + "ecode=" + uploadMsg.getErr_no() + "\n");
  75. //System.out.println(datePrefix + "failed=" + uploadMsg.getFailed());
  76. logDetailText.append(datePrefix + "failed=" + uploadMsg.getFailed() + "\n");
  77. countDownLatch.countDown();
  78. return -1;
  79. }
  80. // 循环等待音频处理结果
  81. while (true) {
  82. try {
  83. // 等待20s在获取任务进度
  84. Thread.sleep(sleepSecond * 1000);
  85. //System.out.println("waiting ...");
  86. logDetailText.append(datePrefix + "failed=" + "waiting ..." + "\n");
  87. } catch (InterruptedException e) {
  88. e.printStackTrace();
  89. }
  90. try {
  91. // 获取处理进度
  92. Message progressMsg = lc.lfasrGetProgress(task_id);
  93. // 如果返回状态不等于0,则任务失败
  94. if (progressMsg.getOk() != 0) {
  95. //System.out.println("task was fail. task_id:" + task_id);
  96. //System.out.println("ecode=" + progressMsg.getErr_no());
  97. //System.out.println("failed=" + progressMsg.getFailed());
  98. logDetailText.append(datePrefix + "task was fail. task_id:" + task_id + "\n");
  99. logDetailText.append(datePrefix + "ecode=" + progressMsg.getErr_no() + "\n");
  100. logDetailText.append(datePrefix + "failed=" + progressMsg.getFailed() + "\n");
  101. countDownLatch.countDown();
  102. return -1;
  103. } else {
  104. ProgressStatus progressStatus = JSON.parseObject(progressMsg.getData(), ProgressStatus.class);
  105. if (progressStatus.getStatus() == 9) {
  106. // 处理完成
  107. //System.out.println(datePrefix + "task was completed. task_id:" + task_id + "\n");
  108. logDetailText.append(datePrefix + "task was completed. task_id:" + task_id + "\n");
  109. break;
  110. } else {
  111. // 未处理完成
  112. //System.out.println(datePrefix + "task is incomplete. task_id:" + task_id + ", status:" + progressStatus.getDesc() + "\n");
  113. logDetailText.append(datePrefix + "task is incomplete. task_id:" + task_id + ", status:" + progressStatus.getDesc() + "\n");
  114. continue;
  115. }
  116. }
  117. } catch (LfasrException e) {
  118. // 获取进度异常处理,根据返回信息排查问题后,再次进行获取
  119. Message progressMsg = JSON.parseObject(e.getMessage(), Message.class);
  120. //System.out.println(datePrefix + "ecode=" + progressMsg.getErr_no() + "\n");
  121. //System.out.println(datePrefix + "failed=" + progressMsg.getFailed() + "\n");
  122. logDetailText.append(datePrefix + "ecode=" + progressMsg.getErr_no() + "\n");
  123. logDetailText.append(datePrefix + "failed=" + progressMsg.getFailed() + "\n");
  124. }
  125. }
  126. // 获取任务结果
  127. try {
  128. Message resultMsg = lc.lfasrGetResult(task_id);
  129. // 如果返回状态等于0,则获取任务结果成功
  130. if (resultMsg.getOk() == 0) {
  131. // 打印转写结果
  132. String result = Test.getFinalResult(resultMsg.getData());
  133. String output = textPath + "\\" + System.currentTimeMillis() + ".txt";
  134. FileOutputStream f = new FileOutputStream(output);
  135. f.write(result.getBytes());
  136. //System.out.println(result);
  137. logDetailText.append(datePrefix + "结果存放路径: " + output + "\n");
  138. logDetailText.append(datePrefix + "最终转换结果: " + "\n");
  139. logDetailText.append(datePrefix + result + "\n");
  140. } else {
  141. // 获取任务结果失败
  142. //System.out.println(datePrefix + "ecode=" + resultMsg.getErr_no() + "\n");
  143. //System.out.println(datePrefix + "failed=" + resultMsg.getFailed() + "\n");
  144. logDetailText.append(datePrefix + "ecode=" + resultMsg.getErr_no() + "\n");
  145. logDetailText.append(datePrefix + "failed=" + resultMsg.getFailed() + "\n");
  146. countDownLatch.countDown();
  147. return -1;
  148. }
  149. } catch (LfasrException e) {
  150. // 获取结果异常处理,解析异常描述信息
  151. Message resultMsg = JSON.parseObject(e.getMessage(), Message.class);
  152. //System.out.println(datePrefix + "ecode=" + resultMsg.getErr_no() + "\n");
  153. //System.out.println(datePrefix + "failed=" + resultMsg.getFailed() + "\n");
  154. logDetailText.append(datePrefix + "ecode=" + resultMsg.getErr_no() + "\n");
  155. logDetailText.append(datePrefix + "failed=" + resultMsg.getFailed() + "\n");
  156. countDownLatch.countDown();
  157. return -1;
  158. }
  159. countDownLatch.countDown();
  160. return 1;
  161. }
  162. }

整合代码,实现最终效果如下:

                                         

代码位置:https://github.com/ChenWenKaiVN/VoiceToText

下一阶段优化方向

1.主线程会出现假死现象。需要深入研究一下SWT UI线程与非UI线程的运行机制。

https://blog.csdn.net/dollyn/article/details/38582743/

2.研究一下进度条的问题,显示转换进度。

3.配置界面需要与SDK配置文件进一步相结合,许多变量还是写死在SDK配置文件中。

4.研究一下可执行jar的打包方法,将JRE一起加入到可执行jar中。

5.研究一下语音识别的技术原理

https://github.com/nl8590687/ASRT_SpeechRecognition

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/225480
推荐阅读
相关标签
  

闽ICP备14008679号