ChatVoice.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. <template>
  2. <el-dialog class="chat-voice" title="语音录制" :visible.sync="visible" width="600px" :before-close="handleClose">
  3. <div v-show="mode=='RECORD'">
  4. <div class="chat-voice-tip">{{stateTip}}</div>
  5. <div>时长: {{state=='STOP'?0:parseInt(rc.duration)}}s</div>
  6. </div>
  7. <audio v-show="mode=='PLAY'" :src="url" controls ref="audio" @ended="handleStopAudio()"></audio>
  8. <el-divider content-position="center"></el-divider>
  9. <el-row class="chat-voice-btn-group">
  10. <el-button round type="primary" v-show="state=='STOP'" @click="handleStartRecord()">开始录音</el-button>
  11. <el-button round type="warning" v-show="state=='RUNNING'" @click="handlePauseRecord()">暂停录音</el-button>
  12. <el-button round type="primary" v-show="state=='PAUSE'" @click="handleResumeRecord()">继续录音</el-button>
  13. <el-button round type="danger" v-show="state=='RUNNING'||state=='PAUSE'" @click="handleCompleteRecord()">
  14. 结束录音</el-button>
  15. <el-button round type="success" v-show="state=='COMPLETE' && mode!='PLAY'" @click="handlePlayAudio()">播放录音
  16. </el-button>
  17. <el-button round type="warning" v-show="state=='COMPLETE' && mode=='PLAY'" @click="handleStopAudio()">停止播放
  18. </el-button>
  19. <el-button round type="primary" v-show="state=='COMPLETE'" @click="handleRestartRecord()">重新录音</el-button>
  20. <el-button round type="primary" v-show="state=='COMPLETE'" @click="handleSendRecord()">立即发送</el-button>
  21. </el-row>
  22. </el-dialog>
  23. </template>
  24. <script>
  25. import Recorder from 'js-audio-recorder';
  26. export default {
  27. name: 'chatVoice',
  28. props: {
  29. visible: {
  30. type: Boolean
  31. }
  32. },
  33. data() {
  34. return {
  35. rc: new Recorder(),
  36. audio: new Audio(),
  37. state: 'STOP', // STOP、RUNNING、PAUSE、COMPLETE
  38. stateTip: "未开始",
  39. mode: 'RECORD', // RECORD 、PLAY
  40. duration: 0,
  41. url: ""
  42. }
  43. },
  44. methods: {
  45. handleClose() {
  46. // 关闭前清除数据
  47. this.rc.destroy();
  48. this.rc = new Recorder();
  49. this.audio.pause();
  50. this.mode = 'RECORD';
  51. this.state = 'STOP';
  52. this.stateTip = '未开始';
  53. this.$emit("close");
  54. },
  55. handleStartRecord() {
  56. this.rc.start().then((stream) => {
  57. this.state = 'RUNNING';
  58. this.stateTip = "正在录音...";
  59. }).catch(error => {
  60. console.log(error);
  61. this.$message.error(error);
  62. console.log(error);
  63. });
  64. },
  65. handlePauseRecord() {
  66. this.rc.pause();
  67. this.state = 'PAUSE';
  68. this.stateTip = "已暂停录音";
  69. },
  70. handleResumeRecord() {
  71. this.rc.resume();
  72. this.state = 'RUNNING';
  73. this.stateTip = "正在录音...";
  74. },
  75. handleCompleteRecord() {
  76. this.rc.pause();
  77. this.state = 'COMPLETE';
  78. this.stateTip = "已结束录音";
  79. },
  80. handlePlayAudio() {
  81. let wav = this.rc.getWAVBlob();
  82. let url = URL.createObjectURL(wav);
  83. this.$refs.audio.src = url;
  84. this.$refs.audio.play();
  85. this.mode = 'PLAY';
  86. },
  87. handleStopAudio() {
  88. console.log(this.$refs.audio);
  89. this.$refs.audio.pause();
  90. this.mode = 'RECORD';
  91. },
  92. handleRestartRecord() {
  93. this.rc.destroy();
  94. this.rc = new Recorder()
  95. this.rc.start();
  96. this.state = 'RUNNING';
  97. this.mode = 'RECORD';
  98. this.stateTip = "正在录音...";
  99. },
  100. handleSendRecord() {
  101. let wav = this.rc.getWAVBlob();
  102. let name = new Date().getDate() + '.wav';
  103. var formData = new window.FormData()
  104. formData.append('file', wav, name);
  105. this.$http({
  106. url: '/file/upload',
  107. data: formData,
  108. method: 'post',
  109. headers: {
  110. 'Content-Type': 'multipart/form-data'
  111. }
  112. }).then((url) => {
  113. let data = {
  114. duration: parseInt(this.rc.duration),
  115. url: url
  116. }
  117. this.$emit("send", data);
  118. this.handleClose();
  119. })
  120. }
  121. }
  122. }
  123. </script>
  124. <style lang="scss">
  125. .chat-voice {
  126. .chat-voice-tip {
  127. font-size: 18px;
  128. }
  129. .chat-voice-btn-group {
  130. margin-bottom: 20px;
  131. }
  132. }
  133. </style>