SoundRecord.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. <template>
  2. <div class="sound-record-wrapper">
  3. <div class="sound-microphone" @click="microphone">
  4. <img v-if="microphoneStatus" :src="require('@/assets/fill/record-ing.png')" class="voice-play" />
  5. <SvgIcon v-else icon-class="mic-line" class="record" />
  6. <span class="auto-btn">录制音频</span>
  7. <span>{{ secondFormatConversion(recordTimes) }}</span>
  8. </div>
  9. </div>
  10. </template>
  11. <script>
  12. import Recorder from 'js-audio-recorder'; // 录音插件
  13. import { secondFormatConversion } from '@/utils/transform';
  14. import { GetStaticResources, GetFileStoreInfo } from '@/api/app';
  15. export default {
  16. name: 'SoundRecord',
  17. props: {},
  18. data() {
  19. return {
  20. secondFormatConversion,
  21. recorder: new Recorder({
  22. sampleBits: 16, // 采样位数,支持 8 或 16,默认是16
  23. sampleRate: 16000, // 采样率,支持 11025、16000、22050、24000、44100、48000,根据浏览器默认值,我的chrome是48000
  24. numChannels: 1, // 声道,支持 1 或 2, 默认是1
  25. }),
  26. timer: null, // 计时器
  27. microphoneStatus: false, // 是否录音
  28. hasMicro: '', // 录音后的样式class
  29. audio: {
  30. paused: true,
  31. },
  32. playtime: 0, // 播放时间
  33. recordTimes: 0,
  34. file_url: '',
  35. recordTime: 0,
  36. };
  37. },
  38. computed: {},
  39. watch: {},
  40. mounted() {
  41. this.$refs.audio.addEventListener('ended', () => {
  42. this.audio.paused = true;
  43. });
  44. this.$refs.audio.addEventListener('pause', () => {
  45. this.audio.paused = true;
  46. });
  47. this.$refs.audio.addEventListener('play', () => {
  48. this.audio.paused = false;
  49. });
  50. },
  51. methods: {
  52. // 开始录音
  53. microphone() {
  54. let _this = this;
  55. if (this.microphoneStatus) {
  56. this.handleStop();
  57. } else {
  58. this.hasMicro = '';
  59. // 开始录音
  60. this.recorder.start();
  61. this.microphoneStatus = true;
  62. this.recordTimes = 0;
  63. clearInterval(this.timer);
  64. this.timer = setInterval(() => {
  65. // 每条录音不能超过10分钟
  66. if (_this.recordTimes < 600) {
  67. _this.recordTimes += 1;
  68. } else {
  69. _this.handleStop();
  70. }
  71. }, 1000);
  72. }
  73. },
  74. handleStop() {
  75. this.hasMicro = 'normal';
  76. this.recorder.stop();
  77. clearInterval(this.timer);
  78. // 录音结束,获取取录音数据
  79. let wav = this.recorder.getWAVBlob(); // 获取 WAV 数据
  80. this.microphoneStatus = false;
  81. let reader = new window.FileReader();
  82. reader.readAsDataURL(wav);
  83. reader.onloadend = () => {
  84. let MethodName = 'file_store_manager-SaveFileByteBase64Text';
  85. let data = {
  86. base64_text: reader.result.replace('data:audio/wav;base64,', ''),
  87. file_suffix_name: 'mp3',
  88. };
  89. GetStaticResources(MethodName, data).then((res) => {
  90. if (res.status === 1) {
  91. this.$emit('updateFileList', res.file_id);
  92. }
  93. });
  94. };
  95. },
  96. },
  97. };
  98. </script>
  99. <style lang="scss" scoped>
  100. .sound-record-wrapper {
  101. display: flex;
  102. column-gap: 12px;
  103. align-items: center;
  104. width: 200px;
  105. padding: 5px 12px;
  106. background: $fill-color;
  107. border-radius: 2px;
  108. .audio-play-btn {
  109. cursor: pointer;
  110. &.not-url {
  111. color: #a1a1a1;
  112. cursor: not-allowed;
  113. }
  114. }
  115. .record-time {
  116. flex: 1;
  117. min-width: 52px;
  118. font-size: 14px;
  119. font-weight: 400;
  120. line-height: 22px;
  121. color: #a1a1a1;
  122. &.record-ing {
  123. color: #000;
  124. }
  125. }
  126. .record {
  127. cursor: pointer;
  128. }
  129. .voice-play {
  130. width: 16px;
  131. height: 16px;
  132. }
  133. .delete-btn {
  134. margin-left: 12px;
  135. color: #4e4e4e;
  136. cursor: pointer;
  137. &.not-url {
  138. color: #a1a1a1;
  139. cursor: not-allowed;
  140. }
  141. }
  142. .auto-btn {
  143. font-size: 16px;
  144. font-weight: 400;
  145. line-height: 22px;
  146. color: #1d2129;
  147. cursor: pointer;
  148. }
  149. .sound-microphone {
  150. display: flex;
  151. column-gap: 12px;
  152. align-items: center;
  153. justify-content: space-between;
  154. width: 100%;
  155. }
  156. }
  157. </style>