移动端,录音之前判断是否已经获取录音权限

项目背景:项目是用 vue 写的,最终打包为 apk ,其中涉及到录音的功能,利用 h5+ 实现的。

(在vue中集成 html5 plus, 参考 https://www.cnblogs.com/luobiao/p/10552030.html)

需求:长按录音,录音之前判断是否已经获取录音权限,如果没有权限,则需要获取权限;如果有权限,则开始录音。

 

录音功能,使用了触摸事件,触摸开始,则录音开始,触摸结束,则录音结束。并且限制录音时长最长为一分钟

<div class="record" @touchstart="startRecord" @touchend="stopRecord"></div>

因为要使用录音,所以在 mounted 钩子函数中需要先获取设备的录音对象

使用 plus.audio.getRecorder() 可以获取设备的录音对象。

  mounted () {
    let vm = this
    this.onPlusReady(() => {
      console.log('plus ready')
      // eslint-disable-next-line
        vm.recorderPlus = plus.audio.getRecorder()
    })
  },

 

录音时,首先要先判断是否已经获取录音的权限。 plus.navigator.checkPermission() 方法可以检查运行环境的权限。

plus.navigator.checkPermission(permission)

向系统检查当前程序的权限状态,不触发权限相对应的功能API的调用。

permission : 要检查的权限名称。

返回值:"authorized"表示程序已被用户授权使用此权限; "denied"表示程序已被用户拒绝使用此权限; "undetermined"表示程序未确定是否可使用此权限,此时调用对应的API时系统会弹出提示框让用户确认; "notdeny"表示程序未被用户拒绝使用此权限(与denied相反,可能是"authorized"或者"undetermined"); "unknown"表示程序未知此权限状态(系统存在权限管理但无法查询); "unsupported"表示程序不支持此权限。

    startRecord () {
      if (this.recorderPlus === null) {
        this.$toast('Device not ready!')
        return
      }
      // 判断权限
      // eslint-disable-next-line
      let permission = plus.navigator.checkPermission('RECORD')
      console.log(permission)
      switch (permission) {
        case 'authorized':   // 允许
          this.record()
          break
        case 'denied':    // 拒绝
          this.requestPermission()
          break
        case 'undetermined':    // 询问
          this.requestPermission()
          break
        case 'unknown':    // 未知
          this.record()
          break
        default:
          this.$toast('设备不支持录音')
          break
      }
    },

 

获取权限时,安卓 和 ios 的处理方式不同。

对于安卓手机,plus.android 提供了获取权限的方法。

plus.android.requestPermissions(permissions, successCb, errorCb)

permissions: Array[String]   申请的权限列表(要申请的权限需在应用manifest.json的“模块权限配置”中勾选)

succesCb: 申请权限成功回调函数

返回申请权限的结果,可能被用户允许 回调函数的参数event包含以下属性:

  • granted - Array[String]字符串数组,已获取权限列表;
  • deniedPresent - Array[String]字符串数据,已拒绝(临时)的权限列表;
  • deniedAlways - Array[String]字符串数据,永久拒绝的权限列表。

errorCb: 申请权限失败回调函数

          // eslint-disable-next-line
          plus.android.requestPermissions(['android.permission.RECORD_AUDIO'], function (e) {
          if (e.deniedAlways.length > 0) { // 权限被永久拒绝
            vm.$dialog.alert({
              message: '录音权限被永久拒绝,请到设置权限里找到应用手动开启权限,否则将不能使用此功能。'
            })
          }
          if (e.deniedPresent.length > 0) { // 权限被临时拒绝
            vm.$dialog.confirm({
              message: '拒绝开启录音权限,将不能使用此功能!确定拒绝开启吗?',
              confirmButtonText: '确定',
              cancelButtonText: '取消'
            }).then(() => {})
              .catch(() => {
                vm.requestPermission()
              })
          }
          if (e.granted.length > 0) { // 权限被允许
          }
        }, function (e) {
          vm.$dialog.alert({
            message: '请求录音权限失败,请到设置权限里找到应用手动开启权限,否则将不能使用此功能。'
          })
        })

但是对于 ios , 并没有直接的方法获取权限。最后采取的解决办法是,在没有录音权限的时候,先主动调用一次录音的api,此时 ios 回去请求一次录音的权限。如果没有选择不允许使用权限,则触发录音失败的回调函数。

        vm.recorderPlus.record({}, function () {
        }, function (e) {
          if (e.code === 2) {
            vm.$dialog.alert({
              message: '录音权限未允许,请到设置手动开启权限,否则将不能使用此功能。'
            })
          }
          console.log(JSON.stringify(e))
        })
        vm.recorderPlus.stop()

因为两个平台需要区别对待,plus 提供了判断平台的方法,plus.os.name

获取录音权限的  requestPermission() 方法的完整代码为

requestPermission () {
      let vm = this
      // eslint-disable-next-line
        let platform = plus.os.name
      if (platform === 'Android') {
        // 动态申请权限
        // eslint-disable-next-line
          plus.android.requestPermissions(['android.permission.RECORD_AUDIO'], function (e) {
          if (e.deniedAlways.length > 0) { // 权限被永久拒绝
            vm.$dialog.alert({
              message: '录音权限被永久拒绝,请到设置权限里找到应用手动开启权限,否则将不能使用此功能。'
            })
          }
          if (e.deniedPresent.length > 0) { // 权限被临时拒绝
            vm.$dialog.confirm({
              message: '拒绝开启录音权限,将不能使用此功能!确定拒绝开启吗?',
              confirmButtonText: '确定',
              cancelButtonText: '取消'
            }).then(() => {})
              .catch(() => {
                vm.requestPermission()
              })
          }
          if (e.granted.length > 0) { // 权限被允许
          }
        }, function (e) {
          vm.$dialog.alert({
            message: '请求录音权限失败,请到设置权限里找到应用手动开启权限,否则将不能使用此功能。'
          })
        })
      } else if (platform === 'iOS') {
        vm.recorderPlus.record({}, function () {
        }, function (e) {
          if (e.code === 2) {
            vm.$dialog.alert({
              message: '录音权限未允许,请到设置手动开启权限,否则将不能使用此功能。'
            })
          }
          console.log(JSON.stringify(e))
        })
        vm.recorderPlus.stop()
      } else {
        this.record()
      }
    },

 

录音 record()方法的完整代码

    data () {
      return {
        recording: false,  // 是否有录音在进行中
        timeLimit: 60, // 时间限制(s)
        remainTime: 60, // 剩余时间(s)
        timeOut: 10, // 剩余时间提示(s)
     }
    },   

    record () {
      let vm = this
      if (vm.recording) {
        return false
      }
      vm.recording = true
      if (vm.timer) {
        clearInterval(vm.timer)
      }
      vm.remainTime = vm.timeLimit
      let duration = 0
      vm.timer = setInterval(function () {
        duration++
        vm.remainTime = vm.timeLimit - duration
        if (duration === vm.timeLimit) {
          vm.stopRecord()
        }
      }, 1000)
      let rates = vm.recorderPlus.supportedSamplerates
      vm.recorderPlus.record({filename: '_doc/audio/', format: 'wav', samplerate: rates[0]}, function (path) {
        console.log('录音文件的路径为:' + path)
      }, function (e) {
        let error = JSON.stringify(e)
        vm.$toast('Audio record failed: ' + error)
        if (vm.timer) {
          clearInterval(vm.timer)
        }
        if (vm.recording) {
          vm.recording = false
        }
      })
    },

 

结束录音的方法

    stopRecord () {
      let vm = this
      if (vm.timer) {
        clearInterval(vm.timer)
      }
      if (vm.recording) {
        vm.recording = false
        vm.recorderPlus.stop()
      }
    },

 

写在最后:此解决方案,在开发时,我只用 iPhone X 和 OPPO R11 进行了测试,没有发现问题。公司资源有限,后来测试也没有测试到所有机型。现在 app 已经发布到应用市场,随着用户的增加,目前为止,还没有收到录音获取权限不起作用的反馈。如有问题,欢迎大家分享反馈。

 

  • 5
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
在Vue移动端,你可以使用HTML5的MediaRecorder API来录制音频。下面是一个示例: 1. 创建一个录音组件,例如Record.vue: ```html <template> <div> <button v-on:touchstart="startRecording" v-on:touchend="stopRecording">开始录音</button> </div> </template> <script> export default { data() { return { chunks: [], mediaRecorder: null, isRecording: false }; }, methods: { startRecording() { navigator.mediaDevices.getUserMedia({ audio: true }) .then(stream => { this.mediaRecorder = new MediaRecorder(stream); this.mediaRecorder.start(); this.isRecording = true; this.mediaRecorder.addEventListener('dataavailable', event => { if (typeof event.data === 'undefined') return; if (event.data.size === 0) return; this.chunks.push(event.data); }); }) .catch(err => console.log(err)); }, stopRecording() { this.mediaRecorder.stop(); this.mediaRecorder.addEventListener('stop', () => { const audioBlob = new Blob(this.chunks, { 'type': 'audio/mp3' }); const audioURL = URL.createObjectURL(audioBlob); const audio = new Audio(audioURL); audio.play(); this.chunks = []; this.isRecording = false; }); } } } </script> ``` 2. 在需要使用录音功能的页面中引入Record组件,并使用: ```html <template> <div> <Record></Record> </div> </template> <script> import Record from './Record.vue'; export default { components: { Record } } </script> ``` 在上面的示例中,我们在Record组件中请求用户许可使用麦克风。一旦用户授权,我们就创建一个MediaRecorder实例并开始录制音频。在录制期间,我们将音频数据存储在一个数组中。当停止录制时,我们使用Blob对象将音频数据转换为Blob对象,这样我们就可以将其上传到服务器或将其保存到本地文件中。最后,我们创建一个Audio实例并将其播放,以便用户可以听到自己的录音

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值