【发布时间】:2020-01-06 19:39:01
【问题描述】:
我有一个从数据库中获取的语音 URL,并想使用 react-native-sound 播放它,
所以我制作了一个可重用的组件,它“现在没有动画”呈现播放图标和持续时间
所以在声音播放之后,我先更改播放图标,然后运行setInterval 以每秒增加计数+1
但一开始更改图标和实际持续时间太慢了,以秒为单位:11但计时器在9停止
那么我怎样才能让它更快...
代码
this.state = {
playingNow: false,
spinValue: new Animated.Value(0),
timer: 0,
};
// get URL sound from DB then play it :)
play = async () => {
const {VoiceURL} = this.props;
console.log('Play Func Object:', VoiceURL);
const sound = new Sound(VoiceURL, '', error => {
if (error) {
console.log('failed to load the sound', error);
return;
} else {
// Animated.timing(this.state.spinValue, {
// toValue: 1,
// duration: sound. _duration * 1100 || 1000,
// easing: Easing.linear,
// useNativeDriver: true,
// }).start(() => {
// this.state.spinValue.setValue(0);
// });
this.interval = setInterval(
() =>
this.setState({
playingNow: true,
timer: this.state.timer + 1,
}),
1000,
);
sound.play(success => {
if (success) {
// That's mean sound is finish
console.log('success?', success);
this.setState(
{playingNow: false, timer: 0},
() => sound.stop(),
clearInterval(this.interval),
);
console.log('successfully finished playing');
} else {
console.log('playback failed due to audio decoding errors');
}
});
console.log(
'duration in seconds: ' +
sound.getDuration() +
'number of channels: ' +
sound.getNumberOfChannels(),
);
sound.getCurrentTime(seconds => console.log('at: ' + seconds));
}
sound.setNumberOfLoops(0);
});
console.log('in_play??', sound);
return sound;
};
这就是渲染一个 UI
_renderPlayButton = onPress => {
const {timer} = this.state;
let icon = this.state.playingNow ? 'pause' : 'play-arrow';
// const spin = this.state.spinValue.interpolate({
// inputRange: [0, 1],
// outputRange: [0, -120],
// });
return (
<View
style={{
opacity: this.props.opacity,
alignItems: 'center',
flexDirection: 'row',
}}>
<TouchableOpacity
style={{backgroundColor: '#1E558E', borderRadius: 100}}
onPress={onPress}>
<Icon name={icon} color="#fff" size={25} style={{padding: 2}} />
</TouchableOpacity>
<View
style={{flexDirection: 'row', marginLeft: 5, alignItems: 'center'}}>
{/* <Animated.View
style={{
backgroundColor: '#f00',
borderRadius: 10,
width: 15,
height: 15,
zIndex: 10,
transform: [{translateX: spin}],
}}
/> */}
<View
style={{
width: 120,
backgroundColor: '#a7a7a7',
height: 2,
}}
/>
<Text style={{color: '#777', marginBottom: 5, marginLeft: 10}}>
00:
{('0' + (timer || 0)).slice(-2)}
{console.log('timer-state:', timer)}
</Text>
</View>
</View>
);
};
JSX
<View>
{this._renderPlayButton(() => {
this.play();
})}
</View>
【问题讨论】:
-
不知道这是否是问题的原因,但您不应在传递给
setState的对象中直接使用this.state。请改用function form。 -
@RobinZigmond U 的意思是
setState计时器? -
是的。将其更改为
this.setState(oldState => ({playingNow: true, timer: oldState.timer + 1}))。我不能肯定地说这会解决问题(如果我确定我会给出答案),但在我看来这当然是可能的。我链接到的文章应该解释为什么这是必要的。 -
@RobinZigmond 遗憾地没有解决问题:\
-
@RobinZigmond 当我使用这种方式并在
_renderPlayButton()中记录timer时,它记录了 125 次,虽然声音只有 3 秒:O
标签: javascript reactjs react-native audio