index.vue 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  1. <template>
  2. <div class="container">
  3. <div class="container-box">
  4. <div class="titbox">
  5. <h2 class="font-ui">语音识别</h2>
  6. </div>
  7. <div class="audio-box">
  8. <div>
  9. <!-- <h3>录音时长:<span v-if="recorder.duration">{{recorder.duration.toFixed(4)}}</span></h3> -->
  10. <el-button type="primary" plain @click="handleStart">开始录音</el-button>
  11. <el-button type="info" plain @click="handlePause">暂停录音</el-button>
  12. <el-button type="success" plain @click="handleResume">继续录音</el-button>
  13. <el-button type="warning" plain @click="handleStop">停止录音</el-button>
  14. </div>
  15. <div style="padding-top: 10px;">
  16. <!-- <h3>播放时长:
  17. <span v-if="recorder.duration && playTime">{{recorder&&(playTime>recorder.duration?recorder.duration.toFixed(4):playTime.toFixed(4))}}</span>
  18. </h3> -->
  19. <el-button type="primary" plain @click="handlePlay">播放录音</el-button>
  20. <el-button type="info" plain @click="handlePausePlay">暂停播放</el-button>
  21. <el-button type="success" plain @click="handleResumePlay">继续播放</el-button>
  22. <el-button type="warning" plain @click="handleStopPlay">停止播放</el-button>
  23. </div>
  24. </div>
  25. <div style="margin: 20px">
  26. <el-button type="primary" @click="uploadRecord(1)">开始识别</el-button>
  27. <el-button type="primary" @click="uploadRecord(2)">录音下载</el-button>
  28. </div>
  29. <div class="voice-box">
  30. <span>选择文件:</span>
  31. <div class="vfile" @click="cleartxt">
  32. <myUpload @uploadBack="uploadBack" :fileInfo="fileInfo" :fileList="fileInfo.fileList"></myUpload>
  33. </div>
  34. </div>
  35. <div class="voice-box">
  36. <span>识别结果:</span>
  37. <div class="vtxt">{{voice}}</div>
  38. </div>
  39. </div>
  40. </div>
  41. </template>
  42. <script>
  43. import myUpload from "../../../components/upload";
  44. import Recorder from 'js-audio-recorder'
  45. export default {
  46. components: {
  47. myUpload
  48. },
  49. data() {
  50. return {
  51. fileInfo: {
  52. limit: 1,
  53. type: 'voice',
  54. url: '/market/nlp/recognition',
  55. fileList: []
  56. },
  57. voice: '',
  58. recorder: null,
  59. playTime: null,
  60. uploadRecordModal:false,
  61. }
  62. },
  63. methods: {
  64. cleartxt(){
  65. this.voice = '';
  66. this.fileInfo.fileList = [];
  67. },
  68. uploadBack(v) {
  69. this.voice = '';
  70. let voice = JSON.parse(v.body);
  71. for (let i = 0; i < voice.length; i++) {
  72. this.voice += voice[i];
  73. }
  74. },
  75. // 开始录音
  76. handleStart() {
  77. this.recorder = new Recorder()
  78. Recorder.getPermission().then(() => {
  79. console.log('开始录音')
  80. this.recorder.start() // 开始录音
  81. }, (error) => {
  82. this.$Message.info('请先允许该网页使用麦克风')
  83. console.log(`${error.name} : ${error.message}`)
  84. })
  85. },
  86. handlePause() {
  87. console.log('暂停录音')
  88. this.recorder.pause() // 暂停录音
  89. },
  90. handleResume() {
  91. console.log('恢复录音')
  92. this.recorder.resume() // 恢复录音
  93. },
  94. handleStop() {
  95. console.log(this.recorder)
  96. this.recorder.stop() // 停止录音
  97. },
  98. handlePlay() {
  99. console.log('播放录音')
  100. this.recorder.play() // 播放录音
  101. // 播放时长
  102. this.timer = setInterval(() => {
  103. try {
  104. this.playTime = this.recorder.getPlayTime()
  105. } catch (error) {
  106. this.timer = null
  107. }
  108. }, 100)
  109. },
  110. handlePausePlay() {
  111. console.log('暂停播放')
  112. this.recorder.pausePlay() // 暂停播放
  113. // 播放时长
  114. this.playTime = this.recorder.getPlayTime()
  115. this.time = null
  116. },
  117. handleResumePlay() {
  118. console.log('恢复播放')
  119. this.recorder.resumePlay() // 恢复播放
  120. // 播放时长
  121. this.timer = setInterval(() => {
  122. try {
  123. this.playTime = this.recorder.getPlayTime()
  124. } catch (error) {
  125. this.timer = null
  126. }
  127. }, 100)
  128. },
  129. handleStopPlay() {
  130. console.log('停止播放')
  131. this.recorder.stopPlay() // 停止播放
  132. // 播放时长
  133. this.playTime = this.recorder.getPlayTime()
  134. this.timer = null
  135. },
  136. handleDestroy() {
  137. console.log('销毁实例')
  138. this.recorder.destroy() // 毁实例
  139. this.timer = null
  140. },
  141. uploadRecord(v) {
  142. if (this.recorder == null || this.recorder.duration === 0) {
  143. this.$Message.error('请先录音')
  144. return false
  145. }
  146. this.recorder.pause() // 暂停录音
  147. this.timer = null
  148. console.log('上传录音') // 上传录音
  149. var formData = new FormData()
  150. var blob = this.recorder.getWAVBlob() //获取wav格式音频数据
  151. //此处获取到blob对象后需要设置fileName满足当前项目上传需求,其它项目可直接传把blob作为file塞入formData
  152. var newbolb = new Blob([blob], {
  153. type: 'audio/wav'
  154. })
  155. var fileOfBlob = new File([newbolb], new Date().getTime() + '.wav')
  156. formData.append('file', fileOfBlob);
  157. if(v == 1){
  158. this.voice = '正在识别。。。';
  159. this.uploadExcel(formData)
  160. }else{
  161. if (window.navigator && window.navigator.msSaveOrOpenBlob) {
  162. let newbolb = new Blob([blob], {
  163. type: 'audio/wav'
  164. })
  165. window.navigator.msSaveOrOpenBlob(newbolb, new Date().getTime() + '.wav');
  166. } else {
  167. /* 火狐谷歌的文件下载方式 */
  168. let newbolb = new Blob([blob], {
  169. type: 'audio/wav'
  170. })
  171. var downloadElement = document.createElement('a')
  172. var href = window.URL.createObjectURL(newbolb);
  173. downloadElement.href = href;
  174. downloadElement.download = new Date().getTime() + '.wav';
  175. document.body.appendChild(downloadElement);
  176. downloadElement.click();
  177. document.body.removeChild(downloadElement);
  178. window.URL.revokeObjectURL(href);
  179. }
  180. }
  181. },
  182. uploadExcel(query) {
  183. let _this = this;
  184. this.$http({
  185. url: '/market/nlp/recognition',
  186. method: "post",
  187. headers: {
  188. "Content-Type": "application/json",
  189. },
  190. data: query,
  191. }).then((res) => {
  192. this.voice = '';
  193. let voice = JSON.parse(res.data.body);
  194. for (let i = 0; i < voice.length; i++) {
  195. this.voice += voice[i];
  196. }
  197. });
  198. }
  199. },
  200. mounted() {
  201. },
  202. created() {
  203. this.recorder = new Recorder()
  204. }
  205. }
  206. </script>
  207. <style scoped lang="scss">
  208. .audio-box{
  209. font-size:14px;
  210. padding-left: 20px;
  211. div{
  212. display: inline-block;
  213. width: 50%;
  214. // margin-right: 40px;
  215. }
  216. h3{
  217. margin: 10px;
  218. }
  219. }
  220. .titbox {
  221. padding-bottom: 20px;
  222. }
  223. .voice-box {
  224. margin-top: 30px;
  225. padding-right: 20px;
  226. span {
  227. width: 100px;
  228. display: inline-block;
  229. vertical-align: top;
  230. text-align: right;
  231. }
  232. .vfile {
  233. display: inline-block;
  234. width: calc(100% - 100px);
  235. }
  236. .vtxt {
  237. margin: 0 20px;
  238. padding: 20px;
  239. display: inline-block;
  240. width: calc(100% - 140px);
  241. border: 2px dotted #ddd;
  242. border-radius: 5px;
  243. }
  244. }
  245. </style>