【问题标题】:How can I play a sound after recording in React Native Expo?在 React Native Expo 中录制后如何播放声音?
【发布时间】:2021-07-16 08:00:03
【问题描述】:

我正在使用 Expo 构建一个录音应用程序。 这是我开始录音的功能,可以正常使用。

  const [recording, setRecording] = React.useState();

  async function startRecording() {
    try {
      console.log('Requesting permissions..');
      await Audio.requestPermissionsAsync();
      await Audio.setAudioModeAsync({
        allowsRecordingIOS: true,
        playsInSilentModeIOS: true,
      }); 
      console.log('Starting recording..');
      const recording = new Audio.Recording();
      await recording.prepareToRecordAsync(Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY);
      await recording.startAsync(); 
      setRecording(recording);
      console.log('Recording started');
    } catch (err) {
      console.error('Failed to start recording', err);
    }
  }

这是我的“停止”功能,记录停止并存储...

  async function stopRecording() {
    console.log('Stopping recording..');
    setRecording(undefined);
    await recording.stopAndUnloadAsync();
    const uri = recording.getURI(); 
    console.log('Recording stopped and stored at', uri);
  }

现在我想用播放按钮播放这个保存的声音。我怎样才能获得这个保存的声音?

  return (
    <View style={styles.container}>
      <Button
        title={recording ? 'Stop Recording' : 'Start Recording'}
        onPress={recording ? stopRecording : startRecording}
      />
    </View>
  );

我想将此存储的 uri 作为文件位置传递。这种方式可以吗?

async function playSound() {
    console.log('Loading Sound');
    const { sound } = await Audio.Sound.createAsync(
       require(RecordedURI)
    );
    setSound(sound);
    console.log('Playing Sound');
    await sound.playAsync();
}

这是小吃链接:https://snack.expo.io/ZN9MBtpLd

【问题讨论】:

    标签: react-native audio expo voice-recording


    【解决方案1】:

    首先,您在获得录音后将您的状态分配给undefined

    我建议你做这样的事情

    RecordingPlaying 音频创建两个引用。

    const AudioRecorder = useRef(new Audio.Recording());
    const AudioPlayer = useRef(new Audio.Sound());
    

    还有recordingStatuspermission 等的一些状态。

    const [RecordedURI, SetRecordedURI] = useState<string>("");
    const [AudioPermission, SetAudioPermission] = useState<boolean>(false);
    const [IsRecording, SetIsRecording] = useState<boolean>(false);
    const [IsPLaying, SetIsPLaying] = useState<boolean>(false);
    

    录制实现的小吃是here

    这是一个GitHub Repo,它有实现。

    Screenshot 的结果

    我在其余的实现下面添加了

    import React, { useState, useRef, useEffect } from "react";
    import { View, StyleSheet, Button, Text } from "react-native";
    import { Audio } from "expo-av";
    
    export default function App() {
      // Refs for the audio
      const AudioRecorder = useRef(new Audio.Recording());
      const AudioPlayer = useRef(new Audio.Sound());
    
      // States for UI
      const [RecordedURI, SetRecordedURI] = useState<string>("");
      const [AudioPermission, SetAudioPermission] = useState<boolean>(false);
      const [IsRecording, SetIsRecording] = useState<boolean>(false);
      const [IsPLaying, SetIsPLaying] = useState<boolean>(false);
    
      // Initial Load to get the audio permission
      useEffect(() => {
        GetPermission();
      }, []);
    
      // Function to get the audio permission
      const GetPermission = async () => {
        const getAudioPerm = await Audio.requestPermissionsAsync();
        SetAudioPermission(getAudioPerm.granted);
      };
    
      // Function to start recording
      const StartRecording = async () => {
        try {
          // Check if user has given the permission to record
          if (AudioPermission === true) {
            try {
              // Prepare the Audio Recorder
              await AudioRecorder.current.prepareToRecordAsync(
                Audio.RECORDING_OPTIONS_PRESET_HIGH_QUALITY
              );
    
              // Start recording
              await AudioRecorder.current.startAsync();
              SetIsRecording(true);
            } catch (error) {
              console.log(error);
            }
          } else {
            // If user has not given the permission to record, then ask for permission
            GetPermission();
          }
        } catch (error) {}
      };
    
      // Function to stop recording
      const StopRecording = async () => {
        try {
          // Stop recording
          await AudioRecorder.current.stopAndUnloadAsync();
    
          // Get the recorded URI here
          const result = AudioRecorder.current.getURI();
          if (result) SetRecordedURI(result);
    
          // Reset the Audio Recorder
          AudioRecorder.current = new Audio.Recording();
          SetIsRecording(false);
        } catch (error) {}
      };
    
      // Function to play the recorded audio
      const PlayRecordedAudio = async () => {
        try {
          // Load the Recorded URI
          await AudioPlayer.current.loadAsync({ uri: RecordedURI }, {}, true);
    
          // Get Player Status
          const playerStatus = await AudioPlayer.current.getStatusAsync();
    
          // Play if song is loaded successfully
          if (playerStatus.isLoaded) {
            if (playerStatus.isPlaying === false) {
              AudioPlayer.current.playAsync();
              SetIsPLaying(true);
            }
          }
        } catch (error) {}
      };
    
      // Function to stop the playing audio
      const StopPlaying = async () => {
        try {
          //Get Player Status
          const playerStatus = await AudioPlayer.current.getStatusAsync();
    
          // If song is playing then stop it
          if (playerStatus.isLoaded === true)
            await AudioPlayer.current.unloadAsync();
    
          SetIsPLaying(false);
        } catch (error) {}
      };
    
      return (
        <View style={styles.container}>
          <Button
            title={IsRecording ? "Stop Recording" : "Start Recording"}
            color={IsRecording ? "red" : "green"}
            onPress={IsRecording ? StopRecording : StartRecording}
          />
          <Button
            title={IsPLaying ? "Stop Sound" : "Play Sound"}
            color={IsPLaying ? "red" : "orange"}
            onPress={IsPLaying ? StopPlaying : PlayRecordedAudio}
          />
          <Text>{RecordedURI}</Text>
        </View>
      );
    }
    
    const styles = StyleSheet.create({
      container: {
        flex: 1,
        justifyContent: "center",
        backgroundColor: "#ecf0f1",
        padding: 8,
      },
    });
    

    【讨论】:

    • 当我尝试将“RecordedURI”传递到任何地方时,它返回空。我应该将此“RecordedURI”数据设置为声音位置。我正在尝试,但我还没有找到解决方案。我在帖子中添加了零食链接。
    • 我在上面的答案中添加了一个更正。检查一下
    • 我们必须用result替换result.uri
    • 非常感谢您的宝贵时间。但它仍然不起作用。我无法传递“RecordedURI”数据。 {RecordedURI} 返回空。
    • 我还添加了零食实现和截图。请检查
    【解决方案2】:

    这是一个有趣的问题,我也遇到了同样的问题。我无法从录制的 URI 播放。

    此外,我已经通过官方文档,但是他们只提供了有限的例子。

    但我想出了有趣的解决方案,它对我很有效。 Audio.Sound.createAsync() 也支持 URI 支持。

    您只需传递{uri: recording. getURI() || URIFROMFileSystem} 即可完美运行。

    我的例子

      const { sound } = await Audio.Sound.createAsync({
      uri: "file:///Users/xyz/Library/Developer/CoreSimulator/Devices/1BBRFGFCBC414-6685-4818-B625-01038771B105/data/Containers/Data/Application/18E8D28E-EA03-4733-A0CF-F3E21A23427D/Library/Caches/ExponentExperienceData/%2540anonymous%252Fchat-app-c88a6b2e-ad36-45b8-9e5e-1fb6001826eb/AV/recording-87738E73-A38E-49E8-89D1-9689DC5F316B.caf",
    });
    setSound(sound);
    
    console.log("Playing Sound");
    await sound.playAsync();
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-13
      • 2019-04-07
      • 1970-01-01
      • 2020-10-18
      • 1970-01-01
      • 2022-08-10
      • 2020-06-19
      • 2020-03-30
      相关资源
      最近更新 更多