recordingApp.vue 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. <template>
  2. <view class="app">
  3. <view class="sub-recording fx-h fx-bc fx-ac" v-if="isPopup">
  4. <view class="title">按住说话</view>
  5. <image @longpress="recStart" @touchend="recStop" class="icon" src="/img/hold_talk.png"></image>
  6. </view>
  7. <view class="app-win fx-h fx-bc fx-ac" v-if="isRecorder">
  8. <view class="recording-wav">
  9. <view class="hr f-h">
  10. <view class="top" v-if="powerLevel >= 100">
  11. <view class="vc"></view>
  12. </view>
  13. <view class="v" :style="'height:' + (22 * (powerLevel / 100)) + 'px'"></view>
  14. <view class="foot" v-if="powerLevel > 0">
  15. <view class="vc"></view>
  16. </view>
  17. </view>
  18. <image src="/static/chat/zeffect_recordbutton__recordview_bottom.png"></image>
  19. </view>
  20. <view class="time">{{getTime()}}</view>
  21. </view>
  22. </view>
  23. </template>
  24. <style>
  25. .sub-recording{padding: 20px 0;}
  26. .sub-recording .title{color: #787878;padding: 10px 0;font-size: 14px;}
  27. .sub-recording .icon{width: 60px;height: 60px;}
  28. .app-win{background: rgba(0, 0, 0, 0.8);width: 40vw;height: 40vw;position: fixed;top: calc(50% - 30vw);left: calc(50% - 20vw);border-radius: 6px;}
  29. .app-win .recording-wav{width: 60px;height: 60px;position: relative;}
  30. .app-win .recording-wav image{width: 60px;height: 60px;}
  31. .app-win .recording-wav .hr{width: 25px;left:17px;bottom: 20px;position: absolute;z-index: 9;}
  32. .app-win .recording-wav .hr .v{background: #2fbec0;}
  33. .app-win .recording-wav .hr .foot{height: 6px;overflow: hidden;position: relative}
  34. .app-win .recording-wav .hr .foot .vc{width:26px;height: 26px; border-radius:0px 0px 26px 26px;background: #2fbec0;position: absolute;bottom: 0;}
  35. .app-win .recording-wav .hr .top{height: 6px;overflow: hidden;position: relative;}
  36. .app-win .recording-wav .hr .top .vc{width:26px;height: 26px; border-radius:26px 26px 0px 0px;background: #2fbec0;position: absolute;top: 0;}
  37. .app-win .time{margin:10px 0;color: #fff;}
  38. </style>
  39. <script>
  40. import { pathToBase64, base64ToPath } from 'image-tools';
  41. export default{
  42. props:{
  43. },
  44. computed:{},
  45. data(){
  46. return{
  47. isRecorder:false,
  48. rec: null,
  49. powerLevel:0,
  50. time : 0,
  51. isPopup : false,
  52. recorder:uni.getRecorderManager(),
  53. recordTimer:0
  54. }
  55. },
  56. created () {
  57. this.recOpen();
  58. },
  59. methods:{
  60. recOpen(){
  61. //开始录音
  62. this.recorder.onStart(()=>{
  63. this.time = 0;
  64. this.powerLevel = 0;
  65. this.isRecorder = true;
  66. this.recordTimer = setInterval(()=>{
  67. this.time = this.time + 100;
  68. this.powerLevel = Math.floor(Math.random() * 100 );
  69. },100)
  70. });
  71. //录音结束
  72. this.recorder.onStop( (res)=> {
  73. if(this.recordTimer > 0){
  74. clearInterval(this.recordTimer);
  75. }
  76. this.isRecorder = false;
  77. if(this.time < 1000) {
  78. this.utils.Tip("说话时间太短了");
  79. return;
  80. }
  81. this.imgToBase64(res.tempFilePath).then(base64=>{
  82. //console.log(base64);
  83. this.$emit('end',{data:(/.+;\s*base64\s*,\s*(.+)$/i.exec(base64)||[])[1],duration:this.time});
  84. });
  85. //this.$emit('end',{data:(/.+;\s*base64\s*,\s*(.+)$/i.exec(reader.result)||[])[1],duration:duration});
  86. //console.log('recorder stop' + JSON.stringify(res));
  87. //this.voicePath = res.tempFilePath;
  88. });
  89. //
  90. this.recorder.onError(()=>{
  91. this.utils.Tip("录音失败");
  92. });
  93. },
  94. open(){
  95. // #ifdef APP-PLUS
  96. this.$store.dispatch('permission/requestPermissions', 'RECORD_AUDIO').then(res => {
  97. if(res !== 1) return;
  98. this.isPopup = true;
  99. });
  100. // #endif
  101. },
  102. hide(){
  103. this.isPopup = false;
  104. },
  105. //打开录音
  106. recStart(){
  107. this.recorder.start({ sampleRate:16000,format:"mp3"});
  108. },
  109. /**
  110. * 停止录音
  111. */
  112. recStop(){
  113. this.recorder.stop();
  114. },
  115. //关闭录音
  116. recClose(){
  117. },
  118. getTime:function(){
  119. let seconds = parseInt(this.time / 1000);
  120. if(seconds <= 60) {
  121. return "00:" + (seconds < 10 ? ("0" + seconds) : seconds );
  122. }
  123. let seconds1 = parseInt(seconds / 60);
  124. let seconds2 = parseInt(seconds % 60);
  125. return (seconds1 < 10 ? ("0" + seconds1) : seconds1 ) + ":" + (seconds2 < 10 ? ("0" + seconds2) : seconds2 );
  126. },
  127. imgToBase64:function(data){
  128. return new Promise((resolve,reject)=>{
  129. pathToBase64(data).then(base64 => {
  130. resolve(base64)
  131. }).catch(error => {
  132. console.error(error)
  133. reject(error)
  134. })
  135. });
  136. }
  137. }
  138. }
  139. </script>