当使用AVPlayer播放来自网址的音频时,它会 例如,在断开wifi连接时停止播放。
[player play];
不恢复AVPlayer
player.rate // Value is 1.0
player.currentItem.isPlaybackLikelyToKeepUp // Value is YES
player.status // Value is AVPlayerStatusReadyToPlay
player.error // Value is nil
但播放器没有播放任何音频。
如何处理与AVPlayer的断开连接,以重新连接AVPlayer 并重新开始玩?
答案 0 :(得分:12)
为了处理网络更改,您必须为AVPlayerItemFailedToPlayToEndTimeNotification
添加观察者。
- (void) playURL:(NSURL *)url
{
AVPlayerItem *playerItem = [AVPlayerItem playerItemWithURL:url];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playerItemFailedToPlayToEndTime:) name:AVPlayerItemFailedToPlayToEndTimeNotification object:playerItem];
self.player = [AVPlayer playerWithPlayerItem:playerItem];
[self.player play];
}
- (void) playerItemFailedToPlayToEndTime:(NSNotification *)notification
{
NSError *error = notification.userInfo[AVPlayerItemFailedToPlayToEndTimeErrorKey];
// Handle error ...
}
答案 1 :(得分:2)
您应该为AVPlayerItemPlaybackStalledNotification添加观察者。
AVPlayerItemFailedToPlayToEndTimeNotification在这个问题上对我没有价值。
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(playbackStalled:) name:AVPlayerItemPlaybackStalledNotification object:trackItem];
正如医生所说,如果没有及时通过网络传送必要的流媒体,基于文件的播放将不会继续。
通知的对象是AVPlayerItem实例,其播放 无法继续,因为没有必要的流媒体 通过网络及时交付。播放流 一旦传递了足够数量的数据,媒体就会继续。 基于文件的播放不会继续。
这说明了为什么AVPlayer可以在网络切换后恢复HLS流,但是如果我使用AVPlayer播放基于文件的TuneIn资源则不能这样做。
然后答案变得简单。
- (void)playbackStalled:(NSNotification *)notification {
if ([self isFileBased:streamUri]) {
// Restart playback
NSURL *url = [NSURL URLWithString:streamUri];
AVPlayerItem *trackItem = [AVPlayerItem playerItemWithURL:url];
AVPlayer *mediaPlayer = [AVPlayer playerWithPlayerItem:trackItem];
[self registerObservers:trackItem player:mediaPlayer];
[mediaPlayer play];
}
}
答案 2 :(得分:1)
0xced对 Swift 3/4 :
的回答var playerItem: AVPlayerItem?
var player: AVPlayer?
func instantiatePlayer(_ url: URL) {
self.playerItem = AVPlayerItem(url: url)
self.player = AVPlayer(playerItem: self.playerItem)
NotificationCenter.default.addObserver(self, selector: #selector(playerItemFailedToPlay(_:)), name: NSNotification.Name.AVPlayerItemFailedToPlayToEndTime, object: nil)
}
func playerItemFailedToPlay(_ notification: Notification) {
let error = notification.userInfo?[AVPlayerItemFailedToPlayToEndTimeErrorKey] as? Error
}