【问题标题】:React Native - SetTimeout() is not working. t.apply is not a functionReact Native - SetTimeout() 不起作用。 t.apply 不是函数
【发布时间】:2019-10-07 01:41:34
【问题描述】:

我正在尝试在延迟一段时间后播放音频

_onPlayPausePressed = () => {
    if (this.sound != null) {
      if (this.state.isPlaying) {
        this.sound.pauseAsync();
      } else {
        setTimeout(this.sound.playAsync(), 2000);
      }
    }
  };

但是它返回错误:t.apply 不是一个函数。 (in't.apply(void 0,o)','t.apply' 未定义) 我尝试了 Oleg 的更新方法。它第一次工作,但之后不会再次运行。以下是我的代码的更多见解:

//import the array with sound details:{id, name desc, sound}
import { soundArray } from "./CreateRecord";
...
export default class CurrentRecord extends React.Component {
  constructor(props) {
    super(props);
    this.currentSound = [];
    this.recording = null;
    this.sound = null;
    this.isSeeking = false;
    this.shouldPlayAtEndOfSeek = false;
    this.state = {
      haveRecordingPermissions: false,
      isLoading: false,
      isPlaybackAllowed: false,
      muted: false,
      soundPosition: null,
      soundDuration: null,
      recordingDuration: null,
      shouldPlay: false,
      isPlaying: false,
      isRecording: false,
      fontLoaded: false,
      shouldCorrectPitch: true,
      volume: 1.0,
      rate: 1.0,
      isModalVisible: false
    };
    this.recordingSettings = JSON.parse(
      JSON.stringify(Audio.RECORDING_OPTIONS_PRESET_LOW_QUALITY)
    );
  }

//load the audio when the component mount
  componentDidMount() {
    this.loadAudio();

    (async () => {
      await Font.loadAsync({
        "cutive-mono-regular": require("../../assets/fonts/CutiveMono-Regular.ttf")
      });
      this.setState({ fontLoaded: true });
    })();
    this._askForPermissions();
  }

//load the sound
  async loadAudio() {
    const { navigation } = this.props;
    const id = navigation.getParam("id");
    this.sound = new Audio.Sound();
    for (let i = 0; i < soundArray.length; i++) {
      if (soundArray[i].id === id) {
        this.currentSound = soundArray[i];
        console.log(this.currentSound);

        break;
      }
    }
    try {
      await this.sound.loadAsync({
        uri: this.currentSound.sound /* url for your audio file */
      });
      await this.sound.setOnPlaybackStatusUpdate(
        this._updateScreenForSoundStatus
      );
    } catch (e) {
      console.log("ERROR Loading Audio", e);
    }
  }

//change screen based on the status
  _updateScreenForSoundStatus = status => {
    if (status.isLoaded) {
      this.setState({
        soundDuration: status.durationMillis,
        soundPosition: status.positionMillis,
        shouldPlay: status.shouldPlay,
        isPlaying: status.isPlaying,
        rate: status.rate,
        muted: status.isMuted,
        volume: status.volume,
        shouldCorrectPitch: status.shouldCorrectPitch,
        isPlaybackAllowed: true
      });
    } else {
      this.setState({
        soundDuration: null,
        soundPosition: null,
        isPlaybackAllowed: false
      });
      if (status.error) {
        console.log(`FATAL PLAYER ERROR: ${status.error}`);
      }
    }
  };

  _askForPermissions = async () => {
    const response = await Permissions.askAsync(Permissions.AUDIO_RECORDING);
    this.setState({
      haveRecordingPermissions: response.status === "granted"
    });
  };

//here's where i want to delay the audio file. 
  _onPlayPausePressed = () => {
    if (this.sound != null) {
      if (this.state.isPlaying) {
        this.sound.pauseAsync();
      } else {
        setTimeout(() => this.sound.playAsync(), 2000);
      }
    }
  };

  _onStopPressed = () => {
    if (this.sound != null) {
      this.sound.stopAsync();
    }
  };

  _onMutePressed = () => {
    if (this.sound != null) {
      this.sound.setIsMutedAsync(!this.state.muted);
    }
  };

  _onVolumeSliderValueChange = value => {
    if (this.sound != null) {
      this.sound.setVolumeAsync(value);
    }
  };

  _trySetRate = async (rate, shouldCorrectPitch) => {
    if (this.sound != null) {
      try {
        await this.sound.setRateAsync(rate, shouldCorrectPitch);
      } catch (error) {
        // Rate changing could not be performed, possibly because the client's Android API is too old.
      }
    }
  };

  _onRateSliderSlidingComplete = async value => {
    this._trySetRate(value * RATE_SCALE, this.state.shouldCorrectPitch);
  };

  _onPitchCorrectionPressed = async value => {
    this._trySetRate(this.state.rate, !this.state.shouldCorrectPitch);
  };

  _onSeekSliderValueChange = value => {
    if (this.sound != null && !this.isSeeking) {
      this.isSeeking = true;
      this.shouldPlayAtEndOfSeek = this.state.shouldPlay;
      this.sound.pauseAsync();
    }
  };

  _onSeekSliderSlidingComplete = async value => {
    if (this.sound != null) {
      this.isSeeking = false;
      const seekPosition = value * this.state.soundDuration;
      if (this.shouldPlayAtEndOfSeek) {
        this.sound.playFromPositionAsync(seekPosition);
      } else {
        this.sound.setPositionAsync(seekPosition);
      }
    }
  };

  _getSeekSliderPosition() {
    if (
      this.sound != null &&
      this.state.soundPosition != null &&
      this.state.soundDuration != null
    ) {
      return this.state.soundPosition / this.state.soundDuration;
    }
    return 0;
  }

  _getMMSSFromMillis(millis) {
    const totalSeconds = millis / 1000;
    const seconds = Math.floor(totalSeconds % 60);
    const minutes = Math.floor(totalSeconds / 60);

    const padWithZero = number => {
      const string = number.toString();
      if (number < 10) {
        return "0" + string;
      }
      return string;
    };
    return padWithZero(minutes) + ":" + padWithZero(seconds);
  }

  _getPlaybackTimestamp() {
    if (
      this.sound != null &&
      this.state.soundPosition != null &&
      this.state.soundDuration != null
    ) {
      return `${this._getMMSSFromMillis(
        this.state.soundPosition
      )} / ${this._getMMSSFromMillis(this.state.soundDuration)}`;
    }
    return "";
  }

  _getRecordingTimestamp() {
    if (this.state.recordingDuration != null) {
      return `${this._getMMSSFromMillis(this.state.recordingDuration)}`;
    }
    return `${this._getMMSSFromMillis(0)}`;
  }

【问题讨论】:

    标签: reactjs react-native expo


    【解决方案1】:

    改成

    _onPlayPausePressed = () => {
        if (this.sound != null) {
          if (this.state.isPlaying) {
           this.sound.pauseAsync();
              } else {
             setTimeout(()=>this.sound.playAsync(), 2000);
          }
        }
      };
    

    【讨论】:

    • 嗨,我试过了。但是声音将无法再播放。
    • 已更新答案,请再试一次,如果不起作用,请发布更多代码。
    • 它只运行第一次,之后不再运行。我只是在下面发布了一些额外的代码
    • 你在哪里更新了 this.state.isPlaying 的状态?在您的代码中添加一些日志或发布博览会小吃。
    • 我认为那是我错的地方。当我在另一个选项卡中创建声音文件时。我做了同样的事情,但效果很好。我不知道为什么会这样。您对我应该在哪里更新它有什么建议吗?
    【解决方案2】:

    删除函数的执行。在 playAsync 中也使用箭头函数(()=> {})

    _onPlayPausePressed = async () => {
      if (this.sound != null) {
        if (this.state.isPlaying) {
          await this.sound.pauseAsync();
        } else {
          setTimeout(() => {
            await this.sound.playAsync()
          }, 2000);
        }
      }
    };
    

    【讨论】:

    • 嗨,如果我这样做,播放按钮将不再运行
    • playAsync() 是用于播放音频的 expo 函数
    • docs.expo.io/versions/latest/sdk/audio 你可以在这里查看更多内容
    • @minhphạm 请尝试修复
    猜你喜欢
    • 1970-01-01
    • 2022-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多