react-native 发录音效果

效果

屏幕录制2021-02-01 下午5.gif

库文件

使用到的库有react-native-audio,teaset两第三方库,react-native-audio用来录音,teaset中使用Toast展示录音效果图。

首先

主要说明一下这个效果,录音功能最后说,向上代码

export default class RecordView extends React.Component {
  static key = null;
  static show(text) {
    let showIcon;
    if (RecordView.key) RecordView.hide()
    if (text == '松开手指取消发送') {
      showIcon = ()
    } else {
      showIcon = (
        
      );
    }

    RecordView.key = Toast.show({
      text: (
        
          {text}
        
      ),
      icon: showIcon,
      position: 'center',
      duration: 1000000,
    });
  }
  static hide() {
    if (!RecordView.key) return;
    Toast.hide(RecordView.key);
    RecordView.key = null;
  }
}

清晰明了,2个方法,一个显示一个隐藏。里面包含两张图片icCancel和icMic, 用来展示。

其次

接下来就是如何调用这个方法来, 包括什么时机调用

this.Gesture = {
      onStartShouldSetResponder: (evt) => true,
      onMoveShouldSetResponder: (evt) => true,
      onResponderGrant: (evt) => {
        // console.log(evt);
        this.setState(
          {
            isRecord: true,
            recordTitle: '手指上滑动,取消发送',
            isCancel: false,
            currentPageY: evt.nativeEvent.pageY,
          },
          () => {
            RecordToast.show(this.state.recordTitle);
            this._record();
            this.props.onScroll(false);
          },
        );
      },
      onResponderMove: (evt) => {
        // console.log(evt);
        if (evt.nativeEvent.pageY - this.state.currentPageY < -5) {
          if (
            this.state.isRecord &&
            this.state.recordTitle == '手指上滑动,取消发送'
          ) {
            this.setState(
              {
                recordTitle: '松开手指取消发送',
                isCancel: true,
              },
              () => {
                RecordToast.show(this.state.recordTitle);
              },
            );
          }
        } else if (evt.nativeEvent.pageY - this.state.currentPageY > 5) {
          if (
            this.state.isRecord &&
            this.state.recordTitle == '松开手指取消发送'
          ) {
            this.setState(
              {
                recordTitle: '手指上滑动,取消发送',
                isCancel: false,
              },
              () => {
                RecordToast.show(this.state.recordTitle);
              },
            );
          }
        } else {
          if (!this.state.isRecord) {
            this.setState(
              {
                isRecord: true,
                recordTitle: '手指上滑动,取消发送',
                isCancel: false,
              },
              () => {
                RecordToast.show(this.state.recordTitle);
                this._record();
                this.props.onScroll(false);
              },
            );
          }
        }
      },
      onResponderRelease: (evt) => {
        console.log('3333');
        this.setState(
          {
            isRecord: false,
          },
          () => {
            RecordToast.hide();
            this._cancel(this.state.isCancel);
            this.props.onScroll(true);
          },
        );
      },
      onResponderTerminationRequest: (evt) => false,
    };

在componentDidMount方法中,初始化手势识别代码,复制给触发事件的组件,
用来展示录音图片和取消图片

 

最后

进行录音,引入头文件

import {AudioRecorder, AudioUtils} from 'react-native-audio';

紧接着在componentDidMount方法中

AudioRecorder.onProgress = (data) => {
    let temp = Math.floor(data.currentTime);
    if (temp >= 60) {
      this.setState(
        {
          isRecord: false,
          recordTitle: '手指上滑动,取消发送',
        },
        () => {
          RecordToast.hide();
          Alert.alert('录制时间不能超过60秒');
          this._cancel(false);
          this.props.onScroll(true);
        },
      );
    } else {
      this.setState({
        currentTime: temp,
      });
    }
  };
  AudioRecorder.onFinished = (data) => {
  };

进行坚挺录音和结束的方法
录音开始录音

_record = async () => {
    if(CommonUtils.ios) {
      this.audioPath =
      AudioUtils.CachesDirectoryPath + `${new Date().getTime()}.aac`;
    } else {
      this.audioPath = AudioUtils.DocumentDirectoryPath + `${new Date().getTime()}.aac`;
    }
    this.prepareRecordingPath(this.audioPath);
    try {
      const filePath = await AudioRecorder.startRecording();
      return filePath;
    } catch (error) {
      console.log(error);
    }
  };
 prepareRecordingPath = (audioPath) => {
    AudioRecorder.prepareRecordingAtPath(audioPath, {
      SampleRate: 22050,
      Channels: 1,
      AudioQuality: 'Low',
      AudioEncoding: 'aac',
      OutputFormat: 'aac_adts',
    });
  };

这个地方需要注意一下,因为存在路径的问题, AudioUtils.CachesDirectoryPath是iOS的缓存路径,在真机和模拟器上都可以找到,如果遇到无法录音的情况,看下log大部分都是无法创建datafile之类的,说明路径不对。
如果遇到android上传不了文件的问题,注意看下log和路径。一般都是类似这类问题
停止录音和取消录音

_cancel = (canceled) => {
    this._stop();
    if (canceled) return;
    if (this.state.currentTime < 1) {
      Alert.alert('录制时间太短了');
      setTimeout(() => {
        RecordToast.hide();
      }, 300);
      return;
    }
    this.setState({currentTime: null});
    setTimeout(() => {
      // 上传音频文件,操作
    }, 500);
  };
  _stop = async () => {
    try {
      const filePath = await AudioRecorder.stopRecording();
      return filePath;
    } catch (error) {}
  };

到此大功告成。

你可能感兴趣的:(react-native 发录音效果)