uni-app小程序錄音上傳解決方案(後續更新Taro版)

能力依賴

RecorderManager 全局惟一的錄音管理器

錄音功能的要求與限制

  • 與當前頁面其餘音頻播放/錄音功能互斥
  • 是否在錄音中狀態顯示
  • 結束/不須要錄音時,回收RecorderManager對象

材料

能夠/結束 錄音
錄音中javascript

Codeing(結果代碼直接看最後)

構造一個簡單的DOM結構

<image @click="recordAction" :src="recordImg" class="record"/>

先實現小程序的錄音功能

import iconRecord from '../../static/images/icon_record.png'
import iconRecording from '../../static/images/icon_recording.png'
// ...
data() {
  recordImg: iconRecord, // 錄音按鈕的圖標
  rm: null, // 錄音管理器
},
// ...
mounted() {
  if (this.rm === null) { // 錄音管理器若是沒有初始化就先初始化
    this.rm = uni.getRecorderManager()
  }
  // 綁定回調方法
  this.rm.onStart((e) => this.onStart(e))
  this.rm.onPause((e) => this.onPause(e))
  this.rm.onResume((e) => this.onResume(e))
  this.rm.onInterruptionBegin((e) => this.onInterruptionBegin(e))
  this.rm.onInterruptionEnd((e) => this.onInterruptionEnd(e))
  this.rm.onError((e) => this.onError(e))
},
// ...
methods: {
  // ...
  recordAction() {
    if (this.recordImg === iconRecord) {
      // 設置格式爲MP3,最長60S,採樣率22050
      this.rm.start({
        duration: 600000,
        format: 'mp3',
        sampleRate: 22050,
      })
      // 開始錄音後綁定中止錄音的回調方法
      this.rm.onStop((e) => this.onStop(e))
    } else if (this.recordImg === iconRecording) {
      this.rm.stop()
    },
  },
  onStart(e) {
    console.log('開始錄音', this.question, this.subQuesIndex)
    this.recordImg = iconRecording
    console.log(e)
  },
  onPause(e) {
    console.log(e)
    afterAudioRecord()
  },
  onResume(e) {
    console.log(e)
  },
  onStop(e) {
    console.log(e)
    this.recordImg = iconRecord
    // 結束錄音以後上傳錄音
    this.uploadMp3Action(e)
  },
  onInterruptionBegin(e) {
    console.log(e)
  },
  onInterruptionEnd(e) {
    console.log(e)
  },
  onError(e) {
    console.log(e)
  },
  uploadMp3Action(e) {
      // TODO uploadMp3
  },
},

只能同時有一個錄音,與音頻播放互斥

  • globalData中增長兩個屬性audioPlayingaudioRecording
// src/App.vue
export default {
  globalData: {  
    // 保證全局只有一個音頻處於播放狀態且錄音與播放操做互斥
    audioPlaying: false,
    audioRecording: false,
  },
  // ...
},
  • Util中增長判斷方法
// src/lib/Util.js
// 結束錄音以後釋放錄音能力
export function afterAudioRecord() {
  getApp().globalData.audioRecording = false
}
// 結束音頻播放以後釋放音頻播放能力
export function afterAudioPlay() {
  getApp().globalData.audioPlaying = false
}

/**
 * 判斷是否能夠錄音或者播放
 * @param {string} type play | record
 */
export function beforeAudioRecordOrPlay(type) {
  const audioPlaying = getApp().globalData.audioPlaying
  const audioRecording = getApp().globalData.audioRecording
  if (audioPlaying ||audioRecording) {
    uni.showToast({
      title: audioPlaying ? '請先暫停其餘音頻播放' : '請先結束其餘錄音',
      icon: 'none'
    })
    return false
  } else {
    if (type === 'play') {
      getApp().globalData.audioPlaying = true
    } else if (type === 'record') {
      getApp().globalData.audioRecording = true
    } else {
      throw new Error('type Error', type)
    }
    return true
  }
}
  • 改造原有recordAction方法
import { beforeAudioRecordOrPlay, afterAudioRecord} from '../../lib/Utils';
// ...
recordAction() {
-  if (this.recordImg === iconRecord) {
+  if (this.recordImg === iconRecord && beforeAudioRecordOrPlay('record')) {
    // 設置格式爲MP3,最長60S,採樣率22050
    this.rm.start({
      duration: 600000,
      format: 'mp3',
      sampleRate: 22050,
    })
    // 開始錄音後綁定中止錄音的回調方法
    this.rm.onStop((e) => this.onStop(e))
  } else if (this.recordImg === iconRecording) {
    this.rm.stop()
+   afterAudioRecord()
  },
},
這樣就避免了屢次錄音

小程序錄音上傳

補全咱們的uploadMp3Action方法,咱們使用uni-appuni.uploadFile()方法來上傳錄音文件html

uploadMp3Action(e) {
  const filePath = e.tempFilePath
  const option = {
    url: 'xxx',
    filePath,
    header,
    formData: {
      filePath
    },
    name: 'audio',
  }
  uni.showLoading({
    title: '錄音上傳中...'
  })
  return await uni.uploadFile(option)
  uni.hideloading()
}

最後在頁面卸載的時候回收RecorderManager對象

beforeDestroy() {
  this.rm = null
}

打完收工~

相關文章
相關標籤/搜索