首页 > 解决方案 > Toggle 播放和暂停音乐 React Native

问题描述

我尝试只使用一个按钮来播放和暂停音乐。当按下按钮时音乐开始播放,但当尝试暂停音乐时出现问题。我在做什么错?

我收到以下错误:

可能未处理的 Promise Rejection (id:0): TypeError: Sound.pauseAsync is not a function。

这是我的音频功能

    const { sound } = await Audio.Sound.createAsync(
      { uri: props.songURL }
    );
      await Audio.setIsEnabledAsync(true);
      setSound(songs);
      setSongs(userSongPosts)
    if (isPlaying === true) {
        try {
            await sound.pauseAsync();
            setIsPlaying(false);
          } catch (error) {
            console.error(error);
          }
    } else {
        try {
            await sound.playAsync(); 
            setIsPlaying(true);
          } catch (error) {
            console.error(error);
          }
    }
  }

这是我的按钮

        <TouchableOpacity
              style={styles.profilContainer}
              onPress={() => playSound() }>
            <Text>{isPlaying ? 'Pause' : 'Play'}</Text>
            <View style={styles.buttonView}>
            <Text style={styles.textButton}>{props.submitText}</Text>
            <MatetrialCommunityIcons
              style={styles.iconStyles}
              name={props.icon}
            />

标签: react-nativeexpomedia-player

解决方案


我建议您创建一个 ref 并将声音变量存储在其中

工作示例

像这样

const sound = React.useRef(new Audio.Sound());
const [Status, SetStatus] = React.useState(false);

React.useEffect(() => {
  LoadAudio();
  return () => sound.current.unloadAsync();
}, []);

const LoadAudio = async () => {
  const checkLoading = await sound.current.getStatusAsync();
  try {
    const result = await sound.current.loadAsync({ uri: Song }, {}, true);
    // Here Song is the uri of the Audio file
    if (result.isLoaded === false) {
      console.log('Error in Loading Audio');
    } else {
      PlayAudio();
    }
  } catch (error) {
    console.log('Error in Loading Audio');
  }
};

  const LoadAudio = async () => {
    const checkLoading = await sound.current.getStatusAsync();
    try {
      const result = await sound.current.loadAsync({ uri: Song }, {}, true);
      if (result.isLoaded === false) {
        console.log('Error in Loading Audio');
      } else {
        PlayAudio();
      }
    } catch (error) {
      console.log('Error in Loading Audio');
    }
  };

  const PlayAudio = async () => {
    try {
      const result = await sound.current.getStatusAsync();
      if (result.isLoaded) {
        if (result.isPlaying === false) {
          sound.current.playAsync();
          SetStatus(true);
        }
      } else {
        LoadAudio();
      }
    } catch (error) {
      SetStatus(false);
    }
  };

  const PauseAudio = async () => {
    try {
      const result = await sound.current.getStatusAsync();
      if (result.isLoaded) {
        if (result.isPlaying === true) {
          sound.current.pauseAsync();
          SetStatus(false);
        }
      }
    } catch (error) {
      SetStatus(false);
    }
  };

  return (
    <View style={styles.container}>
      <Text>{Status === false  ? 'Stopped' : 'Playing now'}</Text>
      <View style={{ width: '100%' }}>
        <Button title="Play Sound" onPress={() => PlayAudio()} />
        <Button title="Pause Sound" onPress={() => PauseAudio()} />
      </View>
    </View>
  );

Pause在这个实现中,和有两个单独的按钮Play。因此,如果您想要一个single按钮,toggle pause and play那么return语句应该如下所示

return (
  <View style={styles.container}>
    <Text>{Status === false ? 'Stopped' : 'Playing now'}</Text>
    <View style={{ width: '100%' }}>
      <Button
        title={Status === false ? 'Play' : 'Pause'}
        onPress={Status === false ? () => PlayAudio() : () => PauseAudio()}
      />
    </View>
  </View>
);

不要忘记顶部的导入是这样的

import * as React from "react";

推荐阅读