React Native syncing sound with Animated



我正在制作一个有节拍器的应用程序。我使用的是react原生声音和Animated。我需要节拍器的声音以非常高的精度触发,并与动画同步。我没有太多经验,所以我使用了一个破解的解决方案(用Animated.listener触发样本(,但效率非常低:

<Button
icon={this.state.paused ? <Icon name="play" size={25} color='white'/> : <Icon name="pause" size={25} color='white'/>}
onPress={() => {
if (this.state.paused)
{this.setState({paused: false});
this.animateTiming();
let loopCount = 0;
this.animatedValue.addListener(({value}) => {
loopCount++;
if(value==1) loopCount=0;
// metronome playback
if ([0,60,120,180].includes(loopCount)) playSound(audioList[0], 0);
});

}

有人对如何更好地处理它有什么建议吗?非常感谢。

更新#2

this.animateTiming((看起来像这样:

animateTiming(){
this.animatedValue.setValue(START_POINT);
Animated.loop(
Animated.timing(this.animatedValue, {
toValue: STOP_POINT,
easing: Easing.linear,
duration: 4000, //these are milliseconds
useNativeDriver: true
})
).start(); 

}

循环长度为4000ms,因此在60fps时,loopCount会上升到240。因此,[0,60120180]表示";每秒钟播放一次声音";。延迟发生在每个循环的开始,即调用渲染函数时。我已经确定延迟(约80ms(的来源是使用VexFlow渲染乐谱(请参阅此链接中"入门"中的示例(。

问题是,VexFlow渲染和动画是否有可能以某种方式并行运行(音频需要完全及时,渲染符号时稍有延迟不是问题(。预渲染表示法是不可行的,因为显示的内容取决于用户在上一个循环周期中的操作。

[…],因此在60fps时,loopCount会上升到240。因此,[0,60120180]表示";每秒钟播放一次声音";

这是一个假设,它将是60帧/秒。实际帧速率将取决于设备的功能,以及每帧要进行多少计算。它随时间变化。FPS的任何波动都会导致声音在错误的时间播放。

我已经确定延迟(约80ms(的来源是渲染乐谱[…]

看起来你的帧速率有所下降。

解决方案

节拍器应该以恒定的间隔点击,因此正确的方法是计算帧之间的时间差,并检查是否经过了指定的时间量;如果是,则播放";点击";声音

这些来源可能派上用场:

  • 增量计时
  • requestAnimationFrame API

最新更新