index.ts 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import Taro from "@tarojs/taro"
  2. import { checkPermission, showAuthModal } from '@/utils/auth'
  3. interface H5RecordResult {
  4. arrayBuffer?: ArrayBuffer | any;
  5. }
  6. type TOnStopRes = (Taro.RecorderManager.OnStopCallbackResult & H5RecordResult) | null
  7. let audioCtx:Taro.WebAudioContext = Taro.createWebAudioContext();
  8. export const useVoiceRecord = (format: keyof Taro.RecorderManager.Format = 'mp3')=> {
  9. let recorder = Taro.getRecorderManager()
  10. let volumeChangeCallback: (volume: number, n:any)=> void
  11. let recorderStopCallback: (res: TOnStopRes)=> void
  12. //@ts-ignore
  13. const analyser = audioCtx.createAnalyser();
  14. recorder.onStop((res)=> {
  15. console.log('recorder stop')
  16. const {
  17. duration,
  18. } = res
  19. if(duration < 1000){
  20. Taro.showToast({
  21. title: '录音不能小于 1 秒',
  22. icon: 'none'
  23. })
  24. return
  25. }
  26. recorderStopCallback && recorderStopCallback(res)
  27. })
  28. recorder.onFrameRecorded(listener => {
  29. if (listener.isLastFrame) {
  30. console.log('soundIntensity',0)
  31. } else {
  32. //@ts-ignore
  33. // audioCtx.decodeAudioData(listener.frameBuffer, buffer => {
  34. // let source = audioCtx.createBufferSource()
  35. // source.buffer = buffer
  36. // source.connect(analyser)
  37. // source.start()
  38. // let n = new Uint8Array(analyser.frequencyBinCount)
  39. // analyser.getByteTimeDomainData(n)
  40. // let i = 0, r = 0, s = 0
  41. // r = Math.max.apply(null, n)
  42. // s = Math.min.apply(null, n)
  43. // i = (r - s) / 128
  44. // i = Math.round(i * 100 / 2)
  45. // i = i > 100 ? 100 : i
  46. // const volume = listener.isLastFrame ? 0 : i
  47. // console.log('soundIntensity', volume)
  48. // volumeChangeCallback && volumeChangeCallback(volume, n)
  49. // }, err => {
  50. // console.error('decodeAudioData fail', err)
  51. // })
  52. }
  53. })
  54. const start = async () => {
  55. const authed = await checkPermission('scope.record')
  56. if(!authed){
  57. showAuthModal('需要您允许录音权限')
  58. recorderStopCallback && recorderStopCallback(null)
  59. return
  60. }
  61. recorder.start({
  62. duration: 1000 * 60 * 20,
  63. sampleRate: 16000, //采样率
  64. numberOfChannels: 1, //录音通道数
  65. encodeBitRate: 96000, //编码码率
  66. format: format, //音频格式,有效值 aac/mp3
  67. frameSize: 1
  68. })
  69. }
  70. const onVolumeChange = (callback: (volume: number, n:any)=> void) => {
  71. volumeChangeCallback = callback
  72. }
  73. const onStop = (callback: (res: TOnStopRes)=> void) => {
  74. recorderStopCallback = callback
  75. }
  76. const stop = ()=> {
  77. recorder.stop()
  78. }
  79. return {
  80. start,
  81. stop,
  82. onVolumeChange,
  83. onStop,
  84. }
  85. }