AVPlayer seekToTime 导致播放器停止播放

Posted

技术标签:

【中文标题】AVPlayer seekToTime 导致播放器停止播放【英文标题】:AVPlayer seekToTime causes the player to stop playing 【发布时间】:2015-05-27 18:57:04 【问题描述】:

我有一个播放广播电台的 AVPlayer,并有一个我构建的快退按钮。当你倒带时,该方法被调用并且 WORKS 大约 80% 的时间,成功地将 AVPLayer 的当前时间设置回 X-many seconds。但是,另外 20% 的时间,AVPlayer 会停止播放音频,并且在应用程序被杀死并重新打开之前不会再次播放。方法如下:

- (IBAction)rewind:(id)sender

    CMTime cmTime = CMTimeMake(CMTimeGetSeconds(self.player.currentTime) - 1.0, 1);
    CMTime almostZero = CMTimeMake(1, 2);
    if (CMTimeGetSeconds(cmTime) > CMTimeGetSeconds(almostZero)) 
    [self.player.currentItem seekToTime:cmTime];
    

就上下文而言,它是一个实时流。

这是我的 15 秒倒带方法:

 if((self.currentPlaybackTime - 15.0f) > CMTimeGetSeconds(kCMTimeZero)) 
        [self.player pause];
        [self.player seekToTime:CMTimeMakeWithSeconds((self.currentPlaybackTime - 15.0f), self.player.currentTime.timescale)];
        [self.player play];
         else if((self.currentPlaybackTime - 10.0f) > CMTimeGetSeconds(kCMTimeZero)) 
       [self.player pause];
       [self.player seekToTime:CMTimeMakeWithSeconds((self.currentPlaybackTime - 10.0f), self.player.currentTime.timescale)];
            [self.player play];
     else if((self.currentPlaybackTime - 5.0f) > CMTimeGetSeconds(kCMTimeZero)) 
        [self.player pause];
        [self.player seekToTime:CMTimeMakeWithSeconds((self.currentPlaybackTime - 5.0f), self.player.currentTime.timescale)];
        [self.player play];

     else if((self.currentPlaybackTime - 3.0f) > CMTimeGetSeconds(kCMTimeZero)) 
        [self.player pause];
        [self.player seekToTime:CMTimeMakeWithSeconds((self.currentPlaybackTime - 3.0f), self.player.currentTime.timescale)];
        [self.player play];
     else if((self.currentPlaybackTime - 2.0f) > CMTimeGetSeconds(kCMTimeZero)) 
       [self.player pause];
       [self.player seekToTime:CMTimeMakeWithSeconds((self.currentPlaybackTime - 2.0f), self.player.currentTime.timescale)];
        [self.player play];
     else if((self.currentPlaybackTime - 1.0f) > CMTimeGetSeconds(kCMTimeZero)) 
        [self.player pause];
        [self.player seekToTime:CMTimeMakeWithSeconds((self.currentPlaybackTime - 1.0f), self.player.currentTime.timescale)];
        [self.player play];
    

- (NSTimeInterval)currentPlaybackTime

    return CMTimeGetSeconds(self.player.currentTime);

当我记录方法和秒数时,您可以看到在第三次倒带(音频始终停止并且不会重新启动)时,播放器实际上并没有返回 15 秒,尽管 seekToTime 似乎是当前时间减去 15 秒。

2015-05-28 09:34:57.383 Lancers[78554:11732524] sec: 45
2015-05-28 09:34:58.382 Lancers[78554:11732524] sec: 46
2015-05-28 09:34:59.383 Lancers[78554:11732524] sec: 47
2015-05-28 09:35:00.383 Lancers[78554:11732524] sec: 48
2015-05-28 09:35:01.382 Lancers[78554:11732524] sec: 49
2015-05-28 09:35:02.237 Lancers[78554:11732524] CURRENT PLAYING TIME: 49.855237
2015-05-28 09:35:02.237 Lancers[78554:11732524] REWIND 15 SECONDS!
2015-05-28 09:35:02.293 Lancers[78554:11732524] sec: 35
2015-05-28 09:35:02.293 Lancers[78554:11732524] sec: 35
2015-05-28 09:35:02.305 Lancers[78554:11732524] sec: 35
2015-05-28 09:35:02.305 Lancers[78554:11732524] sec: 35
2015-05-28 09:35:02.305 Lancers[78554:11732524] sec: 35
2015-05-28 09:35:02.472 Lancers[78554:11732524] sec: 35
2015-05-28 09:35:03.472 Lancers[78554:11732524] sec: 36
2015-05-28 09:35:04.473 Lancers[78554:11732524] sec: 37
2015-05-28 09:35:05.473 Lancers[78554:11732524] sec: 38
2015-05-28 09:35:06.473 Lancers[78554:11732524] sec: 39
2015-05-28 09:35:07.472 Lancers[78554:11732524] sec: 40
2015-05-28 09:35:08.473 Lancers[78554:11732524] sec: 41
2015-05-28 09:35:09.473 Lancers[78554:11732524] sec: 42
2015-05-28 09:35:10.473 Lancers[78554:11732524] sec: 43
2015-05-28 09:35:11.472 Lancers[78554:11732524] sec: 44
2015-05-28 09:35:12.472 Lancers[78554:11732524] sec: 45
2015-05-28 09:35:13.472 Lancers[78554:11732524] sec: 46
2015-05-28 09:35:13.771 Lancers[78554:11732524] CURRENT PLAYING TIME: 46.299634
2015-05-28 09:35:13.771 Lancers[78554:11732524] REWIND 15 SECONDS!
2015-05-28 09:35:13.821 Lancers[78554:11732524] sec: 31
2015-05-28 09:35:13.821 Lancers[78554:11732524] sec: 31
2015-05-28 09:35:13.833 Lancers[78554:11732524] sec: 31
2015-05-28 09:35:13.833 Lancers[78554:11732524] sec: 31
2015-05-28 09:35:13.833 Lancers[78554:11732524] sec: 31
2015-05-28 09:35:14.557 Lancers[78554:11732524] sec: 32
2015-05-28 09:35:15.557 Lancers[78554:11732524] sec: 33
2015-05-28 09:35:16.556 Lancers[78554:11732524] sec: 34
2015-05-28 09:35:16.870 Lancers[78554:11732524] CURRENT PLAYING TIME: 34.314164
2015-05-28 09:35:16.870 Lancers[78554:11732524] REWIND 15 SECONDS!
2015-05-28 09:35:16.898 Lancers[78554:11732524] sec: 34
2015-05-28 09:35:16.899 Lancers[78554:11732524] sec: 34

【问题讨论】:

如果您有一种可行的方法,那么问题是什么? 它没有。快退按钮工作两次,然后冻结音频。您只能倒带 30 秒,然后播放器冻结。如果我告诉 rewind2 方法简单地调用 rewind1 方法 15 次,播放器仍然会在第三次调用时冻结。 我不清楚“冻结”是什么意思。如果你想在搜索后继续玩,你打电话给seekToTime:toleranceBefore:toleranceAfter:completionHandler:有帮助吗? completionHandler: 的全部意义在于,您可以在寻找之后进行游戏。 谢谢。我应该将公差设置为什么?当我使用 rewind1 方法搜索时,它会继续播放,所以我认为它总是在你搜索后继续播放。 我不知道,但文档说这是最准确的。我并不是说这会起作用,但如果它确实会很好!试一试,让我们看看会发生什么...... 【参考方案1】:

我在猜测您的应用,但我认为问题可能出在您的流式音频的缓冲上。我在本地媒体上使用过很多次 AVPlayer,并且从未遇到过 seekToTime 的任何问题。

跳到一个无效的时间会搞砸你,但从我在你的代码中可以看到你应该没问题。您的倒带代码试图向后移动 1 秒(不是 15 秒?),除非您在开始的 1/2 秒内,在这种情况下您不会寻找并继续播放。

我会在 rewind 方法中检查 AVPlayer 对象(player.status、player.error)的状态,并查看调用 seekToTime 时发生的情况。还要使用调试器或 NSLog 检查您的 cmTime 变量的值和状态标志,以确保您在那里也很好。

【讨论】:

我有两种不同的倒带方法,一种是 15 秒,另一种是 1 秒。我以前没有使用过 AVPlayer,所以我不完全确定如何实施您的建议,但我仍然很感激,并会尽力而为。像这样简单的东西应该可以工作,不是吗? NSLog(@"ERROR: %@", self.player.error); NSLog(@"STATUS: %d", self.player.status); 好的。消除可能出现的问题。是的,您正在正确记录。 @matt 建议在方法中查看 cmTime 的值怎么样?在第二次计算 cmTime 之后,它可能会变得古怪。您能否发布 -15 秒调整的代码,以便我们可以看到给您带来问题的执行代码? thx - dcl 好的。这就是我认为正在发生的事情。不幸的是,如果我是对的,您的代码将永远无法工作。它有时可能只是 AVPlayer 内部工作的时机。 AVPlayer.currentTime 仅在您正在播放时返回当前时间。如果停止,则 currentTime 返回媒体的开始时间。所以在你调用 [self.player pause] 之​​后,你从 currentPlaybackTime 得到的值并不是你想的那样。在暂停之前保存 currentTime 并使用该值进行 seekToTime 计算。 我相信你一定能做到。只要您将流数据保存在 AVPlayer 某处的缓冲区中,它就不是真正的流。 听起来你已经有数据进入你的应用程序并开始播放——这是一大步。考虑这些数据是什么以及它在您的应用程序中流动的位置。有了它,您可以找出缓存它的最佳位置,您想要保留多少以及保留多长时间。这应该决定您是否将其保存到本地文件、核心数据等。

以上是关于AVPlayer seekToTime 导致播放器停止播放的主要内容,如果未能解决你的问题,请参考以下文章

AVPlayer SeekToTime 不工作。每次从头开始

AVPlayer seekToTime:循环播放短视频时性能不佳

AVPlayer seekToTime 永远不会完成

iOS AVPlayer 在快退/快进后无法暂停

使用avplayer时如何提高seek的性能

AVPlayer seektotime with Pangesturerecognizer