Swift AVPlayer可以';t暂停后继续+;一些等待
在.pause()之后,如果我调用.play(),它会继续,但如果我在.pause()之后等待30-60秒,然后尝试.play(),它有时会无法播放Swift AVPlayer可以';t暂停后继续+;一些等待,swift,swift2,avplayer,Swift,Swift2,Avplayer,在.pause()之后,如果我调用.play(),它会继续,但如果我在.pause()之后等待30-60秒,然后尝试.play(),它有时会无法播放 AVPlayerStatus.Failed返回false AVPlayerStatus.ReadyToPlay返回true 我应该用url重新初始化播放器以使其工作。 现在我想这样做,如果播放器可以播放,我只想调用.play(),但如果不能,我想重新初始化它,我的问题是如何检测播放器是否可以播放?顺便说一句,它是一个带有.pls扩展名的无线电链
- AVPlayerStatus.Failed返回false
- AVPlayerStatus.ReadyToPlay返回true
现在我想这样做,如果播放器可以播放,我只想调用.play(),但如果不能,我想重新初始化它,我的问题是如何检测播放器是否可以播放?顺便说一句,它是一个带有.pls扩展名的无线电链接,确实没有迹象表明,当在一段长时间后恢复时,玩家处于不稳定状态。 (除了在我的测试中,我看到在这种情况下,从AVPlayerItem接收的元为空) 无论如何。。根据我从互联网上收集的信息(没有相关的文档),当你暂停时,播放器会在后台继续缓冲,然后。。如果你试图在50-60秒后恢复,它就是不能。这里有一个停止功能就好了 我的解决方案: 一个简单的计时器,用来检查50秒是否过去了,如果是,则更新一个标志,以知道当调用resume方法时,我想在一个新的播放器上启动
func pausePlayer() {
..
player.pause()
..
// Will count to default 50 seconds or the indicated interval and only then set the bufferedInExcess flag to true
startCountingPlayerBufferingSeconds()
bufferedInExcess = false
}
func startCountingPlayerBufferingSeconds(interval: Double = 50) {
timer = NSTimer.scheduledTimerWithTimeInterval(interval, target: self, selector: Selector("setExcessiveBufferedFlag"), userInfo: nil, repeats: false)
}
func setExcessiveBufferedFlag() {
if DEBUG_LOG {
print("Maximum player buffering interval reached.")
}
bufferedInExcess = true
}
func stopCountingPlayerBufferingSeconds() {
timer.invalidate()
}
func resumePlayer() {
if haveConnectivity() {
if (.. || bufferedInExcess) {
startPlaying(true)
} else {
..
player.play
}
..
}
}
func startPlaying(withNewPlayer: Bool = false) {
if (withNewPlayer) {
if DEBUG_LOG {
print("Starting to play on a fresh new player")
}
// If we need another player is very important to fist remove any observers for
// the current AVPlayer/AVPlayerItem before reinitializing them and add again the needed observers
initPlayer()
player.play()
...
}
...
}
-(void)play{
if (self.player){
if (self.bufferingExpired){
self.bufferingExpired = NO;
[self initializePlayerWithStation:self.currentStation];
}else{
[self.player play];
}
[self.resumeTimer invalidate];
self.resumeTimer = nil;
}
}
-(void)pause{
if (self.player){
[self.player pause];
[[NSNotificationCenter defaultCenter]postNotificationName:kNotificationAudioPaused object:nil];
self.resumeTimer = [NSTimer scheduledTimerWithTimeInterval:kResumeStreamingTimer target:self selector:@selector(addNewPlayerItemWhenResuming) userInfo:nil repeats:NO];
}
}
-(void)addNewPlayerItemWhenResuming{
self.bufferingExpired = YES;
}
-(void)initializePlayerWithStation:(RadioStation*)station{
_currentStation = station;
_stream_url = station.url;
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:_stream_url];
if (self.player != nil){
[[self.player currentItem] removeObserver:self forKeyPath:@"status"];
}
[item addObserver:self forKeyPath:@"status" options:0 context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemFailedToPlayToEndTime:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:item];
self.player = [AVPlayer playerWithPlayerItem:item];
}
我在目标c上发布我的解决方案。因此,我在按下暂停按钮时添加了一个计时器,如果该计时器在85秒后触发(在这些秒后缓冲停止),则我将布尔值设置为是,当恢复音频时,如果布尔值为是,则我创建一个新播放器
func pausePlayer() {
..
player.pause()
..
// Will count to default 50 seconds or the indicated interval and only then set the bufferedInExcess flag to true
startCountingPlayerBufferingSeconds()
bufferedInExcess = false
}
func startCountingPlayerBufferingSeconds(interval: Double = 50) {
timer = NSTimer.scheduledTimerWithTimeInterval(interval, target: self, selector: Selector("setExcessiveBufferedFlag"), userInfo: nil, repeats: false)
}
func setExcessiveBufferedFlag() {
if DEBUG_LOG {
print("Maximum player buffering interval reached.")
}
bufferedInExcess = true
}
func stopCountingPlayerBufferingSeconds() {
timer.invalidate()
}
func resumePlayer() {
if haveConnectivity() {
if (.. || bufferedInExcess) {
startPlaying(true)
} else {
..
player.play
}
..
}
}
func startPlaying(withNewPlayer: Bool = false) {
if (withNewPlayer) {
if DEBUG_LOG {
print("Starting to play on a fresh new player")
}
// If we need another player is very important to fist remove any observers for
// the current AVPlayer/AVPlayerItem before reinitializing them and add again the needed observers
initPlayer()
player.play()
...
}
...
}
-(void)play{
if (self.player){
if (self.bufferingExpired){
self.bufferingExpired = NO;
[self initializePlayerWithStation:self.currentStation];
}else{
[self.player play];
}
[self.resumeTimer invalidate];
self.resumeTimer = nil;
}
}
-(void)pause{
if (self.player){
[self.player pause];
[[NSNotificationCenter defaultCenter]postNotificationName:kNotificationAudioPaused object:nil];
self.resumeTimer = [NSTimer scheduledTimerWithTimeInterval:kResumeStreamingTimer target:self selector:@selector(addNewPlayerItemWhenResuming) userInfo:nil repeats:NO];
}
}
-(void)addNewPlayerItemWhenResuming{
self.bufferingExpired = YES;
}
-(void)initializePlayerWithStation:(RadioStation*)station{
_currentStation = station;
_stream_url = station.url;
AVPlayerItem *item = [[AVPlayerItem alloc] initWithURL:_stream_url];
if (self.player != nil){
[[self.player currentItem] removeObserver:self forKeyPath:@"status"];
}
[item addObserver:self forKeyPath:@"status" options:0 context:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(playerItemFailedToPlayToEndTime:)
name:AVPlayerItemDidPlayToEndTimeNotification
object:item];
self.player = [AVPlayer playerWithPlayerItem:item];
}
假设您在发出.play()之前已检查了AVPlayerItem.status==.playable 然后使用AVPlayer实例的timeControlStatus,该实例“指示播放当前是否正在进行、是否无限期暂停,或是在等待适当的网络条件时暂停。” 在我的例子中,它被困在WaitingToplayatsSpecifiedRate.evaluatingBufferingRate模式。 此时,AVPlayerItem.status实例为readToPlay
在写这篇文章的时候,无论何时收到startCommand,我都会重置AVplayer以确保安全。但这看起来很笨重。正在寻找更平滑的解决方案。我相信状态检查是在60秒延迟后完成的,对吗?是的,我确实在60秒暂停后进行了这两项检查。我不知道为什么会发生这种情况:我想我面临的是同一个问题:您没有重新初始化,而是尝试查找currentTime?