AVPlayer 类中是否有任何委托方法?我需要处理诸如电话等中断。AVAudioPlayer 支持。如果 AVPlayer 不支持,如何使用 AVAudioPlayer 流式传输音频?
5 回答
AVPlayer
没有您想要的方法,但您可以使用AVAudioSession
object 代替
1)选择AVAudioSession
对象(例如[AVAudioSession sharedInstance]
)
2)通过调用setActive:error:
方法将其设置为活动
3)设置其委托(类实现AVAudioSessionDelegate
协议)
4)实现委托的方法,例如
-(void)beginInterruption;
-(void)endInterruptionWithFlags:(NSUInteger)flags;
-(void)endInterruption;
编辑
那么如何使用 AVAudioPlayer 流式传输音频呢?因为我们不知道您需要如何流式传输它,最重要的是从哪里,提供一些灵感,
请参阅相关问题:
- 停止 AVAudioPlayer
- 重用 AVAudioPlayer 以获得不同的声音
- avaudioplayer 播放歌曲
- 使用 AVAudioplayer 进行流式传输
- http://blog.guvenergokce.com/avaudioplayer-on-iphone-simulator/57/
- http://www.iphonedevsdk.com/forum/iphone-sdk-development/15991-sample-code-avaudioplayer.html
和教程
AVAudioPlayerDelegate 协议参考 http://developer.apple.com/library/ios/#documentation/AVFoundation/Reference/AVAudioPlayerDelegateProtocolReference/Reference/Reference.html#//apple_ref/doc/uid/TP40008068
响应声音播放完成
– audioPlayerDidFinishPlaying:successfully:响应音频解码错误
– audioPlayerDecodeErrorDidOccur:error:处理音频中断
– audioPlayerBeginInterruption:
– audioPlayerEndInterruption:
– audioPlayerEndInterruption:withFlags:
我认为 AVPlayer 不会让你到达那里。看看 AVAudioPlayerDelegate,audioPlayerBeginInterruption 将是您正在寻找的委托方法。
这是我用于 AVAudioPlayer 的代码示例(我假设您已经知道如何构建您的 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];
}
即使在使用 AVAudioPlayer 时,您也可以初始化一个音频会话,在其中您可以指定您将执行的播放(或录制,就此而言)的类型,以及用于处理电话等中断的回调。
看看AudioSessionInitialize()
它的第三个参数,一个处理中断的回调函数。在您的回调中,您可以处理中断的开始和结束。
使用 AudioSession 和依赖 AVAudioPlayer 回调之间的显着区别在于前者发生在较低级别,可能在调用后者的委托方法之前。因此,使用 AudioSession 回调,我认为您可以更好地控制,但是您可能需要做更多的事情,这取决于您的应用程序音频设置的复杂性。
自问题发布以来已经有很长时间了。不过,为了完整起见,我想补充一下:AVPlayer可以通过添加TimeObserver来处理中断,如下所示:
初始化 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
}
}
如果您选择此解决方案,请注意addPeriodicTimeObserverForInterval
文档中的内容:
只要您希望播放器调用时间观察器,就必须保留返回值[即_aplayerObserver]。此方法的每次调用都应与对 removeTimeObserver: 的相应调用配对。