我正在尝试播放一个MP3
文件,该文件是从先前的UIView
(存储在NSURL *fileURL
变量中)传递给UIView
的。
我正在使用以下参数初始化AVPlayer
:
player = [AVPlayer playerWithURL:fileURL];
NSLog(@"Player created:%d",player.status);
NSLog
打印Player created:0,
,我认为这意味着它还没有准备好播放。
当我点击play UIButton
时,我运行的代码是:
-(IBAction)playButtonClicked
{
NSLog(@"Clicked Play. MP3:%@",[fileURL absoluteString]);
if(([player status] == AVPlayerStatusReadyToPlay) && !isPlaying)
// if(!isPlaying)
{
[player play];
NSLog(@"Playing:%@ with %d",[fileURL absoluteString], player.status);
isPlaying = YES;
}
else if(isPlaying)
{
[player pause];
NSLog(@"Pausing:%@",[fileURL absoluteString]);
isPlaying = NO;
}
else {
NSLog(@"Error in player??");
}
}
当我运行此命令时,我总是在控制台中获得Error in player??
。但是,如果我将检查AVPlayer
是否准备好播放的if
条件替换为一个简单的if(!isPlaying)
...,那么音乐将在我第二次单击play UIButton
时播放。
控制台日志为:
Clicked Play. MP3:http://www.nimh.nih.gov/audio/neurogenesis.mp3
Playing:http://www.nimh.nih.gov/audio/neurogenesis.mp3 **with 0**
Clicked Play. MP3:http://www.nimh.nih.gov/audio/neurogenesis.mp3
Pausing:http://www.nimh.nih.gov/audio/neurogenesis.mp3
Clicked Play. MP3:http://www.nimh.nih.gov/audio/neurogenesis.mp3
2011-03-23 11:06:43.674 Podcasts[2050:207] Playing:http://www.nimh.nih.gov/audio/neurogenesis.mp3 **with 1**
我看到第二次,player.status
看起来是1,我猜是AVPlayerReadyToPlay
。
当我第一次单击play UIButton
时,如何才能使播放正常工作?(例如,我如何确保AVPlayer
不是刚刚创建的,而且是可以播放的?)
发布于 2011-03-23 17:33:19
您正在播放远程文件。AVPlayer
可能需要一段时间来缓冲足够的数据并准备好播放文件(请参阅AV Foundation Programming Guide)
但你似乎并没有等到玩家准备好了才点击播放按钮。我想要的是禁用这个按钮,并只在玩家准备好的时候启用它。
使用KVO,可以在播放器状态更改时收到通知:
playButton.enabled = NO;
player = [AVPlayer playerWithURL:fileURL];
[player addObserver:self forKeyPath:@"status" options:0 context:nil];
此方法将在状态更改时调用:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context {
if (object == player && [keyPath isEqualToString:@"status"]) {
if (player.status == AVPlayerStatusReadyToPlay) {
playButton.enabled = YES;
} else if (player.status == AVPlayerStatusFailed) {
// something went wrong. player.error should contain some information
}
}
}
发布于 2012-03-17 11:19:27
我在尝试弄清楚AVPlayer
的状态时遇到了很多麻烦。status
属性似乎并不总是非常有帮助,当我试图处理音频会话中断时,这导致了无尽的挫折。有时AVPlayer
告诉我它已经准备好(用AVPlayerStatusReadyToPlay
)玩了,但实际上并不是这样。我使用了Jilouc的KVO方法,但它并不是在所有情况下都有效。
作为补充,当status属性没有用处时,我通过查看AVPlayer的currentItem
(它是一个AVPlayerItem
)的loadedTimeRanges
属性来查询AVPlayer
加载的流的数量。
这一切都有点令人困惑,但它看起来是这样的:
NSValue *val = [[[audioPlayer currentItem] loadedTimeRanges] objectAtIndex:0];
CMTimeRange timeRange;
[val getValue:&timeRange];
CMTime duration = timeRange.duration;
float timeLoaded = (float) duration.value / (float) duration.timescale;
if (0 == timeLoaded) {
// AVPlayer not actually ready to play
} else {
// AVPlayer is ready to play
}
发布于 2017-06-16 21:18:42
private var playbackLikelyToKeepUpContext = 0
对于寄存器观察者
avPlayer.addObserver(self, forKeyPath: "currentItem.playbackLikelyToKeepUp",
options: .new, context: &playbackLikelyToKeepUpContext)
倾听观察者的声音
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change: [NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &playbackLikelyToKeepUpContext {
if avPlayer.currentItem!.isPlaybackLikelyToKeepUp {
// loadingIndicatorView.stopAnimating() or something else
} else {
// loadingIndicatorView.startAnimating() or something else
}
}
}
对于删除观察者
deinit {
avPlayer.removeObserver(self, forKeyPath: "currentItem.playbackLikelyToKeepUp")
}
代码中的关键点是实例属性isPlaybackLikelyToKeepUp。
https://stackoverflow.com/questions/5401437
复制相似问题