5

我使用 AVAudioPlayer 在我的 iPhone 应用程序中播放 MP3;我需要在特定时间(比如第 30 秒、1 分钟)执行一些操作;有没有办法根据 mp3 播放时间调用回调函数?

4

6 回答 6

8

我相信最好的解决方案是在开始播放NSTimer时开始AVAudioPlayer播放。您可以将计时器设置为每半秒左右触发一次。然后每次定时器触发时,查看currentTime音频播放器上的属性。

为了在特定的时间间隔做某事,我建议你为上次调用计时器回调的播放时间保留一个实例变量。然后,如果您已经通过了上次回调和 this 之间的临界点,请执行您的操作。

因此,在伪代码中,计时器回调:

  1. 获取currentTime您的 AVAudioPlayer
  2. 检查是否currentTime大于criticalPoint
  3. 如果是,检查是否lastCurrentTime小于criticalPoint
  4. 如果也同意,请采取行动。
  5. 设置lastCurrentTimecurrentTime
于 2012-05-14T09:49:39.237 回答
5

如果您能够使用 AVPlayer 而不是 AVAudioPlayer,则可以设置边界或周期性时间观察器:

// File URL or URL of a media library item
AVPlayer *player = [[AVPlayer alloc] initWithURL:url];        

CMTime time = CMTimeMakeWithSeconds(30.0, 600);
NSArray *times = [NSArray arrayWithObject:[NSValue valueWithCMTime:time]];

id playerObserver = [player addBoundaryTimeObserverForTimes:times queue:NULL usingBlock:^{
    NSLog(@"Playback time is 30 seconds");            
}];

[player play];

// remove the observer when you're done with the player:
[player removeTimeObserver:playerObserver];

AVPlayer 文档:http: //developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVPlayer_Class/Reference/Reference.html

于 2012-05-21T09:53:36.327 回答
1

是的,当然你可以......这很棘手,我希望它对你有用,但它对我有用..

1- you play your mp3 file.

2-[self performSelector:@selector(Operation:) withObject:Object afterDelay:30]; 然后是功能

-(void)Operation:(id)sender;

称为;所以你在 mp3 文件 30 秒后触发了函数..你可以根据你想要的时间制作许多函数..

3-还有其他使用计时器的解决方案

[NSTimer scheduledTimerWithTimeInterval:0 target:self selector:@selector(CheckTime:) userInfo:nil repeats:YES];

它将触发名为 Check Time 的函数

-(void)CheckTime:(id)sender{
   if (avAudioPlayerObject.currentTime == 30.0)
   {
       //Do Something
       //Fire and function call such
       [self performSelector:@selector(Operation:) withObject:Object]
   }
}

然后你可以改变你想要的时间间隔,重复是为了让你控制是否每 5 秒重复一次这个动作.. 希望有帮助..

谢谢

于 2012-05-14T09:49:41.150 回答
1

使用多线程,您的目标很简单,只需这样做:

1 :  in your main thread create a variable for storing time passed 
2 :  create new thread like "checkthread" that check each 30-20 sec(as you need)
3 :  if the time passed is what you want do the callback  
于 2012-05-14T09:51:48.970 回答
1

我发现这个链接描述了一个似乎表明您可以获得当前播放时间的属性。

如果声音正在播放,currentTime 是当前播放位置的偏移量,以声音开始的秒数为单位。如果声音没有播放,currentTime 是调用 play 方法时开始播放的偏移量,以从声音开始开始的秒数为单位。

通过设置此属性,您可以寻找到声音文件中的特定点或实现音频快进和快退功能。

要检查时间并执行您的操作,您只需查询它:

if (avAudioPlayerObject.currentTime == 30.0) //You may need a more broad check. Double may not be able to exactly represent 30.0s
{
    //Do Something
}
于 2012-05-14T09:47:18.480 回答
1

我认为,您想在 30 秒后播放不同的声音文件,然后使用以下代码:

1) 所有声音文件都放在数组中,然后从文档目录中检索

2)然后试试这个:

-(IBAction)play_sound
{

    BackgroundPlayer=[[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:[Arr_tone_selected objectAtIndex:j]ofType:@"mp3"]]error:NULL];
    BackgroundPlayer.delegate=self;

    [BackgroundPlayer play];


}   


- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
    [BackgroundPlayer stop];
    j++;
    [self performSelector:@selector(play_sound) withObject:Object afterDelay:30];   
}
于 2012-05-14T10:02:20.683 回答