美文网首页程序员
react-native 发录音效果

react-native 发录音效果

作者: 一天清晨 | 来源:发表于2021-02-01 17:55 被阅读0次

    效果

    屏幕录制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 = (<Image source={icCancel} style={{ width: 100, height: 100 }} />)
        } else {
          showIcon = (
            <Image source={icMic} style={{ width: 100, height: 100 }} />
          );
        }
    
        RecordView.key = Toast.show({
          text: (
            <Text style={{ fontSize: 13, color: 'white' }}>
              {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方法中,初始化手势识别代码,复制给触发事件的组件,
    用来展示录音图片和取消图片

     <View
            {...this.Gesture}
    </View>
    

    最后

    进行录音,引入头文件

    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 发录音效果

        本文链接:https://www.haomeiwen.com/subject/kihstltx.html