小程序录音功能

1,443 阅读4分钟

小程序录音功能

效果:

相关代码

JS代码

const app = getApp()

const recorderManager = wx.getRecorderManager()
const innerAudioContext = wx.createInnerAudioContext()

var interval;
var tempFilePath = '';
var donghuaStop = '';
var donghuaStops = '';
var number = 1;

Page({

  /**
   * 页面的初始数据
   */
  data: {
    //录音
    imageShows: false,
    random: '',
    viconPlay: true,
    imageShow: '/images/yunyinShow.png',
    recordingDuration: 0, //录音时长
    count: 0, // 设置 计数器 初始为0
    hiddenmodalput: true,
    show: false,
  },
  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function(options) {},

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function() {},
  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function() {
    if (this.data.show == true) {
      recorderManager.stop();
    }
    clearInterval(donghuaStops);
    clearInterval(donghuaStop);
    if (!this.data.viconPlay) {
      innerAudioContext.stop();
      this.setData({
        imageShow: '/images/yunyinShow.png',
        viconPlay: true
      });
    }
  },
   /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function() {
    if (this.data.show == true) {
      recorderManager.stop();
    }
    clearInterval(donghuaStops);
    clearInterval(donghuaStop);
    if (!this.data.viconPlay) {
      innerAudioContext.stop();
      this.setData({
        imageShow: '/images/yunyinShow.png',
        viconPlay: true
      });
    }
  },
  
  //录音
  //打开录音模态框
  modalinput: function() {
    //关闭录音播放
    if (!this.data.viconPlay) {
      innerAudioContext.stop();
      this.setData({
        imageShow: '/images/yunyinShow.png',
        viconPlay: true
      });
    }
    if (this.data.show == false) {}
    hiddenmodalput: !this.data.hiddenmodalput,
      this.setData({
        show: !this.data.show
      })
    this.start();
  },

  //开始录音
  start: function() {
    var that = this;
    const options = {
      duration: 60000, //指定录音的时长,单位 ms
      sampleRate: 16000, //采样率
      numberOfChannels: 1, //录音通道数
      encodeBitRate: 96000, //编码码率
      format: 'mp3', //音频格式,有效值 aac/mp3
      frameSize: 50 //指定帧大小,单位 KB
    }

    //开始录音
    recorderManager.start(options);
    recorderManager.onStart(() => {
      //设置gif图片重新加载
      clearInterval(donghuaStops);
      that.setData({
        imageShows: true,
      })
      if (that.data.imageShows == true) {
        donghuaStop = setInterval(() => {
          that.setData({
            random: "?t=" + new Date().getTime()
          })
          number = number + 1;
          //当60秒执行完了 自动上传
          if (number == 2) {
            that.confirm();
          }
        }, 60000)
      }
    });
    //错误回调
    recorderManager.onError((res) => {
      console.log("错误回调")
      console.log(res);
    })
  },

  //取消按钮 不返回录音  
  cancel: function() {
    donghuaStops = setInterval(() => {
      this.setData({
        random: "?t=" + new Date().getTime()
      })
    }, 500)
    this.setData({
      show: !this.data.show
    })
    if (this.data.show == false) {
      this.setData({
        imageShow: '/images/yunyinShow.png'
      })
    }
    this.data.count = 0;
    this.shutRecording(false);
    //关闭gif动画定时器
    clearInterval(donghuaStop);
  },

  // 只有确认事件才返回录音
  confirm: function() {
    //关闭gif动画定时器
    clearInterval(donghuaStop);

    number = 1;
    donghuaStops = setInterval(() => {
      this.setData({
        random: "?t=" + new Date().getTime()
      })
    }, 500)
    this.shutRecording(true);
    this.setData({
      show: !this.data.show
    })
  },

  //播放\暂停 声音
  play: function() {
    innerAudioContext.obeyMuteSwitch = false;
    innerAudioContext.autoplay = true
    innerAudioContext.src = tempFilePath
    if (this.data.viconPlay == true) {
      innerAudioContext.play()
      this.setData({
        imageShow: '/images/yuyinSshow.gif',
        viconPlay: false
      });
    }
    //暂停事件
    else {
      innerAudioContext.stop();
      this.setData({
        imageShow: '/images/yunyinShow.png',
        viconPlay: true
      });
    };
    innerAudioContext.onEnded(() => {
      console.log("结束播放")
      this.setData({
        imageShow: '/images/yunyinShow.png',
        viconPlay: true
      });
    });
  },

  //结束录音
  shutRecording: function(booble) {

    //关闭模态框
    this.setData({
      hiddenmodalput: true
    });
    var that = this;
    recorderManager.stop();
    recorderManager.onStop((res) => {
      //用户点击说完了但是时间很短
      if (res.duration < 1000 && booble == true) {
        app.commonTip("录音时间太短")
      }
      //用户点击说完了 时间在1秒以上
      else if (res.duration > 1000 && booble == true) {
        app.loadingTip('上传中', true)
        res.duration = res.duration * 0.001;
        // 上传录音
        wx.uploadFile({
          url: `${app.globalData.apiHost}/qiniu/upload-image${app.globalData.t}`, //这是你自己后台的连接
          filePath: res.tempFilePath,
          name: "file", //后台要绑定的名称
          header: {
            'X-Auth-Token': app.getToken()
          },
          //参数绑定
          formData: {
            recordingtime: res.duration.toFixed(0),
            topicid: that.data.topicid,
            userid: 1,
            praisepoints: 0
          },
          success: (ress) => {
            var ress = JSON.parse(ress.data);
            if (ress.e == 200) {
              that.setData({
                recordingDuration: res.duration.toFixed(0), //录音的本地地址
              });
              tempFilePath = ress.d.filepath
            }
            app.loadingTip('上传中', false)
            wx.showToast({
              title: '保存完成',
              icon: 'success',
              duration: 2000,
              mask: true,
            })
            number = 1;
          },
          fail: function(ress) {
            console.log("。。录音保存失败。。");
          }
        })
      }
    })
  },

  

WXML代码

<!-- 弹出层 -->
  <view class='popup-view' wx:if="{{show}}">
    <view class='popup'>
      <icon class='icondialogclose iconfont popup-icon' bindtap='cancel'></icon>
      <view class="circle-box">

        <image wx:if="{{imageShows==false}}" style='width:220rpx;height:220rpx' src="/images/yuyinOne.png"></image>

        <image wx:if="{{imageShows==true}}" style='width:240rpx;height:240rpx' src="https://file.baimipay.cn/voicePlayback.gif{{random}}"></image>

      </view>
      <view bindtap="confirm" class='modal-button'>

        <text class="modal-button-text">说完了</text>
      </view>
    </view>
  </view>

<!-- 语音图标 -->
<view style='width:44rpx;height:44rpx;' bindtap='voice'>
   <image bindtap='modalinput' mode='aspectFill' src='/images/yuyinbs(2).png'></image>
</view>
<!-- 语音内容 -->
<view class='yuyinbg' bindtap='play' wx:if='{{recordingDuration>0}}'>
  <text>{{recordingDuration}}"</text>
  <image src='{{imageShow}}'></image>
</view>


WXSS代码

/* //弹出框样式 */

.popup {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translateY(-50%) translateX(-50%);
  width: 500rpx;
  height: 400rpx;
  border-radius: 8rpx;
  background: #fff;
  z-index: 99;
}

.popup-view {
  position: fixed;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  z-index: 9999;
}

.popup-icon {
  position: absolute;
  right: 0;
  top: -60rpx;
  z-index: 999;
  font-size: 45rpx;
  color: #fff;
}

.popup .text {
  padding-top: 84rpx;
  text-align: center;
  font-size: 30rpx;
  font-family: PingFangSC-Regular;
  font-weight: 400;
}

.popup .btn, .bind-btn {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  width: 340rpx;
  height: 80rpx;
  margin-top: 58rpx;
  line-height: 80rpx;
  background-size: cover;
  text-align: center;
  background-image: url("https://imgs.xqphh.pandabg.cn/miniappindex-btn.png");
}

.topicRecording {
  float: left;
  width: 40%;
  height: 100%;
  position: relative;
}


.modal-button {
  position: absolute;
  width: 100%;
  height: 20%;
  border-top: 1px solid rgba(232, 233, 234, 1);
  text-align: center;
  padding-top: 15rpx;
}

.modal-button-text {
  display: block;
  padding-top: 6rpx;
}

.circle-box {
  height: 80%;
  display: -webkit-flex;
  display: flex;
  -webkit-justify-content: center;
  justify-content: center;
  -webkit-align-items: center;
  align-items: center;
}


.yuyinbg {
  width: 193rpx;
  height: 56rpx;
  z-index: 100;
  background-image: url("https://file.baimipay.cn/yuyinbg@3x.png");
  background-repeat: no-repeat;
  background-size: 100% 100%;
  display: flex;
  align-items: center;
  margin-bottom: 30rpx;
}

.yuyinbg text {
  font-size: 32rpx;
  color: #2e3038;
  margin-left: 40rpx;
}

.yuyinbg image {
  margin-left: 13rpx;
  width: 30rpx;
  height: 34rpx;
}