我开始疯狂地使用这一个。我正在录制音频,一旦我停止录制作为此过程的一部分,我也会加载音频,以便在必要时可以播放,这里我做了setOnPlaybackStatusUpdate
。我使用回放回调,以便我可以基于positionMillis
更新我的currentSeconds
状态。
问题是我得到的currentSeconds
和recordedDuration
状态值。为什么它们的值在触发音频播放的playAudio
方法和回调方法onPlaybackStatusUpdate
之间变化?
当我在控制台中输出它们在两个方法中的值时,这是我期望它们相同时得到的结果:
In playAudio - currentSeconds: 0
In playAudio - recordedDuration: 4.5
In onPlaybackStatusUpdate - currentSeconds: 115.5
In onPlaybackStatusUpdate - recordedDuration: 0
下面是代码:
const AudioRecorder = useRef(new Audio.Recording());
const AudioPlayer = useRef(new Audio.Sound());
const timerMaxDuration = 120
const [currentSeconds, setCurrentSeconds] = useState<number>(timerMaxDuration);
const [recordedDuration, setRecordedDuration] = useState<number>(0);
const stopRecording = async () => {
try {
await AudioRecorder.current.stopAndUnloadAsync();
// To hear sound through speaker and not earpiece on iOS
await Audio.setAudioModeAsync({ allowsRecordingIOS: false });
const recordedURI = AudioRecorder.current.getURI();
SetRecordingURI(recordedURI)
AudioRecorder.current = new Audio.Recording();
send('STOP')
setRecordedDuration(+(timerMaxDuration - currentSeconds).toFixed(1)) // there is subtraction because during the recording there is a countdown from timerMaxDuration
setCurrentSeconds(0)
// Load audio after recording so that it is ready to be played
loadAudio(recordedURI)
} catch (error) {
console.log(error);
}
};
const loadAudio = async (recordedUri) => {
try {
const playerStatus = await AudioPlayer.current.getStatusAsync();
if (playerStatus.isLoaded === false) {
AudioPlayer.current.setOnPlaybackStatusUpdate(onPlaybackStatusUpdate)
await AudioPlayer.current.loadAsync({ uri: recordedUri }, { progressUpdateIntervalMillis: 20 }, true)
}
} catch (error) {
console.log(error)
}
}
const playAudio = async () => {
console.log(`In playAudio - currentSeconds: ${currentSeconds}`)
console.log(`In playAudio - recordedDuration: ${recordedDuration}`)
try {
const playerStatus = await AudioPlayer.current.getStatusAsync();
if (playerStatus.isLoaded) {
if (playerStatus.isPlaying === false) {
AudioPlayer.current.playAsync();
send('PLAY')
}
}
} catch (error) {
console.log(error);
}
};
const onPlaybackStatusUpdate = playbackStatus => {
if (playbackStatus.isPlaying) {
console.log(`In onPlaybackStatusUpdate - currentSeconds: ${currentSeconds}`)
console.log(`In onPlaybackStatusUpdate - recordedDuration: ${recordedDuration}`)
if(currentSeconds >= recordedDuration){
stopAudio()
}
else{
setCurrentSeconds(+(playbackStatus.positionMillis / 1000).toFixed(1))
}
}
}
2条答案
按热度按时间oxcyiej71#
好了,回放回调函数没有任何问题。问题是回放回调函数是一个箭头函数,这意味着在回调函数中唯一会改变的属性值是参数
playbackStatus
,其他属性的值将保持与创建函数时相同。在React中的一个方法是以以下方式使用useEffect,它允许访问状态值
currentSeconds
和recordedDuration
:g52tjvyc2#
面对类似的问题,另一种解决方法是使用useRef钩子而不是状态将所需的值存储在refs中。