开发者

AVPlayer class events

Are there any delegate methods in AVPlayer class? I need to handle interruptions such as phone call etc. AVAudioPlayer supports. If AVPlayer doesn't s开发者_如何学Cupport it, how to stream audio with AVAudioPlayer?


AVPlayer doesn't have the methods you want but you can use AVAudioSession object instead

1) Select AVAudioSession object (for example [AVAudioSession sharedInstance])
2) Set it active by calling setActive:error: method
3) Set its delegate (class implementing AVAudioSessionDelegate protocol)
4) Implement delegate's methods such as

-(void)beginInterruption;
-(void)endInterruptionWithFlags:(NSUInteger)flags;
-(void)endInterruption;


EDIT

I don't see any delegates available in AVPlayer class

So how to stream audio with AVAudioPlayer? Because we don't know how you need to stream it, and most important from where, providind some inspiration
see related questions:

  • stopping an AVAudioPlayer
  • Reusing an AVAudioPlayer for a different sound
  • avaudioplayer playingsong
  • Streaming with an AVAudioplayer
  • http://blog.guvenergokce.com/avaudioplayer-on-iphone-simulator/57/
  • http://www.iphonedevsdk.com/forum/iphone-sdk-development/15991-sample-code-avaudioplayer.html

and tutorial

  • http://mobileorchard.com/easy-audio-playback-with-avaudioplayer/

AVAudioPlayerDelegate Protocol Reference http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioPlayerDelegateProtocolReference/Reference/Reference.html#//apple_ref/doc/uid/TP40008068

  • Responding to Sound Playback Completion
    – audioPlayerDidFinishPlaying:successfully:

  • Responding to an Audio Decoding Error
    – audioPlayerDecodeErrorDidOccur:error:

  • Handling Audio Interruptions
    – audioPlayerBeginInterruption:
    – audioPlayerEndInterruption:
    – audioPlayerEndInterruption:withFlags:


I don't think AVPlayer will get you there. Take a look at AVAudioPlayerDelegate, The audioPlayerBeginInterruption would be the delegate method you are looking for.

Here's a sample of code I use for AVAudioPlayer (I'm assuming you already know how to build your url):

// Instantiates the AVAudioPlayer object, initializing it with the sound
NSError * errAV = nil;
AVAudioPlayer *newPlayer = [[AVAudioPlayer alloc] initWithContentsOfUrl: mUrl error: &errAV];
if (newPlayer == nil) {

    NSString * msg = [[NSString alloc] initWithFormat:@"An internal error has occured:  %@", [errAV localizedDescription]];
    UIAlertView *uiav = [[UIAlertView alloc] initWithTitle:@"Play Sound" 
                                                   message:msg delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil];
    [uiav show];
    [uiav release];
    [msg release];
} else {

    self.appSoundPlayer = newPlayer;
    [newPlayer release];
    // "Preparing to play" attaches to the audio hardware and ensures that playback
    //      starts quickly when the user taps Play
    [appSoundPlayer prepareToPlay];
    [appSoundPlayer setVolume: 1.0];
    [appSoundPlayer setDelegate: self];
    [appSoundPlayer play];
}


Even when using AVAudioPlayer, you can initialize an Audio Session, where in you can specify the kind of playback (or recording, for that matter) you will be doing, and a callback for handling interruptions like phone calls.

Have a look at AudioSessionInitialize() and it's third parameter, a callback function for handling interruptions. In your callback, you can handle both the start and end of an interruption.

The salient different here, between using an AudioSession and relying on the AVAudioPlayer callbacks, is that the former occurs at a lower level, perhaps before the latter's delegate methods are called. So with the AudioSession callback, you have finer control, I think, but then you have to do more, perhaps, depending on the complexity of your app's audio setup.


It has been a long while since the question was posted. However, for the sake of completion, I would like to add: AVPlayer can be used to handle interruptions by adding a TimeObserver as follows:

When initialising the AVPlayer:

AVPlayer *_aplayer;
id _aplayerObserver;

_aplayer = [[AVPlayer alloc] initWithURL:mediaURL];
_aplayerObserver = [_aplayer addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:NULL usingBlock:^(CMTime time)
{
    if (((time.value/time.timescale) >= (_aplayer.currentItem.asset.duration.value/_aplayer.currentItem.asset.duration.timescale))
    {
        // media file played to its end
        // you can add here code that should run after the media file is completed, 
        // thus mimicing AVAudioPlayer's audioPlayerDidFinishPlaying event
    }
    else
    {
        if (_aplayer.rate == 0)
            // audio player was interrupted
    }
}

If you choose this solution, please take note of what addPeriodicTimeObserverForInterval's documentation says:

You must retain the returned value [i.e. _aplayerObserver] as long as you want the time observer to be invoked by the player. Each invocation of this method should be paired with a corresponding call to removeTimeObserver:.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜