2012-04-27 49 views
0

声明:我是比较新的的iOS编程,我试图教我的基础知识,因为我一起只是为了好玩去......所以,请温柔:-)AVAudioPlayer延迟setImage的发生


我正在构建一款应用程序,播放一系列使用AVAudioplayer排列在一起的.mp3文件。到目前为止,这部分工作很好。 IBActions和IBOutlets联系在一起。点击按钮,音频播放。

我的问题是这样的: 我的播放按钮已直接添加到main.storyboard中,通过在Interface Builder中定义的初始状态进行设置和自定义。当我点击播放时,我想更改按钮的图像以指示正在播放。然而,一旦音频开始,它几乎看起来像是......暂停了,或者什么。按钮图像保持不变,直到音频完成播放。只有这样,按钮图像才会更新 - 几乎没有用。

我也试图设置另一个随机的UIImageView的图像没有附加到这个特定的按钮。同样的经验。只要我注释掉我的playAudioArray方法,该按钮就会立即工作。


    -(IBAction)start_playing:(UIButton*)pressed_button { 
    [_btn_start setImage:[UIImage imageNamed:@"btn_on-active"] forState:UIControlStateNormal]; 

    [self playAudioArray]; 
    } 

我希望我已经留下了足够的下去......任何想法/意见/建议?

万分感谢 - 德鲁

更新:

我发现,更新的观点发生故障时我有一个LOPP我的音频播放器。此代码工作正常...


    if (audioPlayer.playing == YES) {

[audioPlayer pause]; 
[sender setImage:[UIImage imageNamed:@"btn_on.png"] forState:UIControlStateNormal]; 
[_btn_stop setImage:[UIImage imageNamed:@"btn_off.png"] forState:UIControlStateNormal]; 

} else { 

NSString *path = [[NSBundle mainBundle] pathForResource:@"audio_file1" ofType:@"mp3"]; 
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; 
audioPlayer.volume = 1.0; 
audioPlayer.numberOfLoops = 0; 
[audioPlayer setMeteringEnabled: YES]; 
[audioPlayer play]; 


//changes the image when the button is pressed 
[sender setImage:[UIImage imageNamed:@"btn_on.png"] forState:UIControlStateNormal]; 
[_btn_stop setImage:[UIImage imageNamed:@"btn_off.png"] forState:UIControlStateNormal]; 

} 

但是这个代码不低于没有。


    } else {

//changes the image when the button is pressed 
[sender setImage:[UIImage imageNamed:@"btn_on.png"] forState:UIControlStateNormal]; 
[_btn_stop setImage:[UIImage imageNamed:@"btn_off.png"] forState:UIControlStateNormal]; 

NSArray *theSoundArray = [NSArray arrayWithObjects:@"audio1",@"audio2",@"audio3",nil]; 

for (int i = 0; i < totalSoundsInQueue;) { 

NSString *sound = [theSoundArray objectAtIndex:i]; 

// Wait until the audio player is not playing anything 
while(![audioPlayer isPlaying]){ 

NSString *path = [[NSBundle mainBundle] pathForResource:@"mom" ofType:@"mp3"]; 
audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path] error:NULL]; 
audioPlayer.volume = 1.0; 
audioPlayer.numberOfLoops = 0; 
[audioPlayer setMeteringEnabled: YES]; 
[audioPlayer play]; 

i++; 

}   

} 

} 

音频正常播放,循环遍历所有我的声音,并没有发生任何错误。只有在按下循环播放完成后,我的按钮的“开启状态”才会被设置。我已经尝试了许多不同类型的循环方法。对于每一个,每当我开始循环播放声音时,音频播放效果很好,但是显示器失去了所有的焦点。

这提醒了我。一旦我在循环中,我的“停止”按钮就失去了可点击(可点击)的性质。直到循环完成运行。如果我不在循环中,停止按钮工作正常,没有问题。

对不起,如果我在这里做一个全新的错误...想法/评论任何人?

+0

您的'playAudioArray'方法设置了_btn_start的状态吗? – 2012-04-27 16:27:41

+0

不是,它设置在start_playing方法的顶部 - 第1行。 – Drew 2012-04-27 17:21:37

回答

0

您的for loop正在捆绑主线程,使您的UI无响应。不要连续运行for循环,而要将自己设置为AVAudioPlayer的代理。一旦音频播放器完成播放,它将向代表发送消息- (void) audioPlayerDidReachEnd;(您必须执行该操作)。然后,您可以播放该实现中队列中的下一个音频文件。无论如何,你真的想成为代表。AVAudioPlayer将发送您的委托消息以进行中断(如来电)并解码错误。你想优雅地处理这些事件。

我认为音频播放良好的原因是它具有更高的优先级,并在单独的线程上运行。 UI变为无响应的原因是即使动画/ UI更改发生在单独的线程上,它们也是从主线程启动的。但是所有UI更改都排队到运行循环的末尾(因此可以进行优化)。但是,该运行循环永不结束,因为您的for loop永远不会结束,直到播放所有音频文件。音频文件可以按顺序播放,因为它们是在for loop中启动的,并在单独的线程上运行。说得通?一般来说,你真的不想捆绑主线程。

+0

谢谢,你的建议帮了大忙。 最后,我完全移除了for循环和while循环,并且最终逐个遍历每个声音,并在每个之前的声音完成后敲击新的播放方法。 谢谢! – Drew 2012-05-10 18:20:40