从 React Native Expo AV 保存的 Uri 不起作用?

问题描述

我创建了一个包含音频数据的字典数组。用户必须录制这些音频,然后才能收听。问题是这些音频用一个平面列表表示,当我在它们之间传递时,它找不到 uri。例如:

const [data,setData] = useState(
    {uri: null,duration: 0},{uri: null,duration: 0}
)

const [index,setIndex] = useState()
const [step,setStep] = useState(0)
const [recording,setRecoding] = useState()
const [sound,setSound] = useState()
const [curDuration,setCurduration] = useState(0)
const [isBuffering,setIsBuferring] = useState(false)

const leftArrow = async () => {
    if (index >= 1) {
        flatlist.current.scrollToIndex({ animated: true,index: index - 1 })
        if (newAudio[index - 1].grabacion != null) {
            await sound.unloadAsync()
            loadAudio(index - 1)
        }
        setIndex(index - 1)
    };
}

const rightArrow = async () => {
    if (index < newAudio.length - 1) {
        flatlist.current.scrollToIndex({ animated: true,index: index + 1 })
        if (newAudio[index + 1].grabacion != null) {
            await sound.unloadAsync()
            loadAudio(index + 1)
        }
        setIndex(index + 1)
    }
}

const loadAudio = async (idx) => {
    const playbackInstance = new Audio.sound()
    const source = { uri: newAudio[idx].grabacion }
    const status = { shouldplay: isPlaying }

    playbackInstance.setonPlaybackStatusUpdate((status) => { setIsBuffering(status.isBuffering) })
    await playbackInstance.loadAsync(source,status,false)
    setSound(playbackInstance)
}

const startRecording = async () => {
    try {
        setStep(1)
        console.log('Requesting permissions..');
        await Audio.requestPermissionsAsync();
        await Audio.setAudioModeAsync({
            allowsRecordingIOS: false,playsInSilentModeIOS: true,playThroughEarpieceAndroid: false,staysActiveInBackground: true,interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DUCK_OTHERS,shouldDuckAndroid: true,interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DUCK_OTHERS,});
        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);
    }
}

const stopRecording = async () => {
    console.log('Stopping recording..');
    setRecording(undefined);
    await recording.stopAndUnloadAsync();
    const uri = recording.getURI();
    // set the sound
    console.log('Loading Sound');
    const { sound } = await Audio.sound.createAsync({ uri: uri });
    setSound(sound);
    //check the status
    let status = await sound.getStatusAsync()
    //save uri and duration
    updateValues( status.durationMillis,status.uri);
}

const updateValues = (dur,uri) => {
    data[index] = {
        duration: dur,grabacion: uri
    }
    setNewAudio(newAudio)
}

return (
    
    <View>
        <Flatlist
            data={data}
            horizontal={true}
            initialScrollIndex={index}
            pagingEnabled={true}
            scrollEnabled={false}
            initialScrollIndex={index}
            showsHorizontalScrollIndicator={false}
            keyExtractor={(item,index) => index.toString()}
            renderItem={(itemData) => {
                <View>

                    <View style={{flexDirection: 'row',justifyContent: 'space-between',alignItems: 'center'}}>
                        <TouchableOpacity onPress={leftArrow}>
                            <AntDesign name='arrowleft'  />
                        </TouchableOpacity>
                        <TouchableOpacity onPress={rightArrow}>
                            <AntDesign name='arrowright' />
                        </TouchableOpacity>
                    </View>

                    {step == 0 ?
                        <TouchableOpacity onPress={startRecording()}>
                            <Fontisto name='mic' />
                        </TouchableOpacity >
                            : step == 1 ?
                            <TouchableOpacity onPress={stopRecording()}>
                                <MaterialIcons name='stop' />
                            </TouchableOpacity >
                                : <TouchableOpacity onPress={HanddlePlayStop()} >
                                    {isPlaying ?
                                        <Fontisto name='pause' />
                                        :
                                        <Fontisto name='play' />
                                    }
                                </TouchableOpacity >
                        }

                    <Slider
                        disabled={isPlaying ? true : false}
                        value={curDuration}
                        minimumValue={0}
                        maximumValue={itemData.item.duration}
                        onSlidingComplete={async (value) => {
                            await sound.setPositionAsync(value)
                        }}
                    />
                </View>

            }
        />
    </View>
    )

我遇到的问题是,当我按 arrowRight() 或 arrowLeft() 时,如果我们要去那里的索引已经有录音,则它无法识别 uri。有人可以帮我吗

解决方法

我能够通过将 uri 保存在 UseState 上来解决它,并且在 updateValues 函数中,我将使用 uri 的 useState 变量而不是 status.uri 来更改值抓取。由于某种原因 status.uri 没有正确保存 uri

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...