音频播放控制API

本文编辑: 大妖怪 大妖怪浏览 4097 版权所有,严禁转载

接口说明:

接口 说明
wx.playVoice 开始播放语音,同时只允许一个语音文件正在播放,如果前一个语音文件还没播放完,将中断前一个语音播放
wx.pauseVoice 暂停正在播放的语音。再次调用wx.playVoice播放同一个文件时,会从暂停处开始播放。如果想从头开始播放,需要先调用 wx.stopVoice

接口用法:

wxml

<view class="container">
  <view class="page-body">
    <view class="page-section">
      <block wx:if="{{recording === false && playing === false && hasRecord === false}}">
        <view class="page-body-time">
          <text class="time-big">{{formatedRecordTime}}</text>
        </view>
        <view class="page-body-buttons">
          <view class="page-body-button"></view>
          <view class="page-body-button" bindtap="startRecord">
            <image src="/imgs/record.png"></image>
          </view>
          <view class="page-body-button"></view>
        </view>
      </block>

      <block wx:if="{{recording === true}}">
        <view class="page-body-time">
          <text class="time-big">{{formatedRecordTime}}</text>
        </view>
        <view class="page-body-buttons">
          <view class="page-body-button"></view>
          <view class="page-body-button" bindtap="stopRecord">
            <view class="button-stop-record"></view>
          </view>
          <view class="page-body-button"></view>
        </view>
      </block>

      <block wx:if="{{hasRecord === true && playing === false}}">
        <view class="page-body-time">
          <text class="time-big">{{formatedPlayTime}}</text>
          <text class="time-small">{{formatedRecordTime}}</text>
        </view>
        <view class="page-body-buttons">
          <view class="page-body-button"></view>
          <view class="page-body-button" bindtap="playVoice">
            <image src="/imgs/play.png"></image>
          </view>
          <view class="page-body-button" bindtap="clear">
            <image src="/imgs/trash.png"></image>
          </view>
        </view>
      </block>

      <block wx:if="{{hasRecord === true && playing === true}}">
        <view class="page-body-time">
          <text class="time-big">{{formatedPlayTime}}</text>
          <text class="time-small">{{formatedRecordTime}}</text>
        </view>
        <view class="page-body-buttons">
          <view class="page-body-button" bindtap="stopVoice">
            <image src="/imgs/stop.png"></image>
          </view>
           <view class="page-body-button" bindtap="pauseVoice">
            <image src="/imgs/pause.png"></image>
          </view> 
          <view class="page-body-button" bindtap="clear">
            <image src="/imgs/trash.png"></image>
          </view>
        </view>
      </block>
    </view>
  </view>
</view>

js
index.js

var util = require('../../utils/util.js')
var playTimeInterval
var recordTimeInterval

Page({
  data: {
    recording: false,
    playing: false,
    hasRecord: false,
    recordTime: 0,
    playTime: 0,
    formatedRecordTime: '00:00:00',
    formatedPlayTime: '00:00:00'
  },
  onHide: function() {
    if (this.data.playing) {
      this.stopVoice()
    } else if (this.data.recording) {
      this.stopRecordUnexpectedly()
    }
  },
  startRecord: function () {
    this.setData({ recording: true })

    var that = this
    recordTimeInterval = setInterval(function () {
      var recordTime = that.data.recordTime += 1
      that.setData({
        formatedRecordTime: util.formatTime(that.data.recordTime),
        recordTime: recordTime
      })
    }, 1000)
    wx.startRecord({
      success: function (res) {
        that.setData({
          hasRecord: true,
          tempFilePath: res.tempFilePath,
          formatedPlayTime: util.formatTime(that.data.playTime)
        })
      },
      complete: function () {
        that.setData({ recording: false })
        clearInterval(recordTimeInterval)
      }
    })
  },
  stopRecord: function() {
    wx.stopRecord()
  },
  stopRecordUnexpectedly: function () {
    var that = this
    wx.stopRecord({
      success: function() {
        console.log('stop record success')
        clearInterval(recordTimeInterval)
        that.setData({
          recording: false,
          hasRecord: false,
          recordTime: 0,
          formatedRecordTime: util.formatTime(0)
        })
      }
    })
  },
  playVoice: function () {
    var that = this
    playTimeInterval = setInterval(function () {
      var playTime = that.data.playTime + 1
      console.log('update playTime', playTime)
      that.setData({
        playing: true,
        formatedPlayTime: util.formatTime(playTime),
        playTime: playTime
      })
    }, 1000)
    wx.playVoice({
      filePath: this.data.tempFilePath,
      success: function () {
        clearInterval(playTimeInterval)
        var playTime = 0
        console.log('play voice finished')
        that.setData({
          playing: false,
          formatedPlayTime: util.formatTime(playTime),
          playTime: playTime
        })
      }
    })
  },
  pauseVoice: function () {
    clearInterval(playTimeInterval)
    wx.pauseVoice()
    this.setData({
      playing: false
    })
  },
  stopVoice: function () {
    clearInterval(playTimeInterval)
    this.setData({
      playing: false,
      formatedPlayTime: util.formatTime(0),
      playTime: 0
    })
    wx.stopVoice()
  },
  clear: function () {
    clearInterval(playTimeInterval)
    wx.stopVoice()
    this.setData({
      playing: false,
      hasRecord: false,
      tempFilePath: '',
      formatedRecordTime: util.formatTime(0),
      recordTime: 0,
      playTime: 0
    })
  }
})

wxss

image {
  width: 150rpx;
  height: 150rpx;
}

.page-body-wrapper {
  justify-content: space-between;
  flex-grow: 1;
  margin-bottom: 300rpx;
}
.page-body-time {
  display: flex;
  flex-direction: column;
  align-items: center;
}
.time-big {
  font-size: 60rpx;
  margin: 20rpx;
}
.time-small {
  font-size: 30rpx;
}

.page-body-buttons {
  margin-top: 60rpx;
  display: flex;
  justify-content: space-around;
}
.page-body-button {
  width: 250rpx;
  text-align: center;
}
.button-stop-record {
  width: 110rpx;
  height: 110rpx;
  border: 20rpx solid #fff;
  background-color: #f55c23;
  border-radius: 130rpx;
  margin: 0 auto;
}

util.js

function formatTime(time) {
  if (typeof time !== 'number' || time < 0) {
    return time
  }

  var hour = parseInt(time / 3600)
  time = time % 3600
  var minute = parseInt(time / 60)
  time = time % 60
  var second = time

  return ([hour, minute, second]).map(function (n) {
    n = n.toString()
    return n[1] ? n : '0' + n
  }).join(':')
}

function formatLocation(longitude, latitude) {
  if (typeof longitude === 'string' && typeof latitude === 'string') {
    longitude = parseFloat(longitude)
    latitude = parseFloat(latitude)
  }

  longitude = longitude.toFixed(2)
  latitude = latitude.toFixed(2)

  return {
    longitude: longitude.toString().split('.'),
    latitude: latitude.toString().split('.')
  }
}

module.exports = {
  formatTime: formatTime,
  formatLocation: formatLocation
}

主要方法:

【wx.playVoice】:【开始播放语音,同时只允许一个语音文件正在播放,如果前一个语音文件还没播放完,将中断前一个语音播放】

| 参数 | 类型 | 必填 | 描述 |
| filePath | String | 是 | 需要播放的语音文件的文件路径 |
| success | Function | 否 | 接口调用成功的回调函数 |
| fail | Function | 否 | 接口调用失败的回调函数 |
| complete | Function | 否 | 接口调用结束的回调函数(调用成功、失败都会执行) |

wx.startRecord({
  success: function(res) {
    var tempFilePath = res.tempFilePath
    wx.playVoice({
      filePath: tempFilePath,
      complete: function(){
      }
    })
  }
})

【wx.pauseVoice】:【暂停正在播放的语音。再次调用wx.playVoice播放同一个文件时,会从暂停处开始播放。如果想从头开始播放,需要先调用 wx.stopVoice】

wx.startRecord({
  success: function(res) {
    var tempFilePath = res.tempFilePath
      wx.playVoice({
      filePath: tempFilePath
    })

    setTimeout(function() {
        //暂停播放
      wx.pauseVoice()
    }, 5000)
  }
})

【wx.stopVoice】:【结束播放语音】

wx.startRecord({
  success: function(res) {
    var tempFilePath = res.tempFilePath
    wx.playVoice({
      filePath:tempFilePath
    })

    setTimeout(function(){
      wx.stopVoice()
    }, 5000)
  }
})

Bug & Tip
1.tip: wx.startRecord 接口需要用户授权,请兼容用户拒绝授权的场景。
2.tip:wx.startRecord只能在真机调试,不能在编译器调试。
3.bug:暂停后继续播放,在安卓上playTimeInterval方法这块有问题,ios上没有。
4.tip:本组接口只能用来控制录音,不能播放音频

如有技术问题或对本文有反馈,请加入QQ群:
微信小程序实战5营: 微信小程序Club实战5营