ios 加载资源后立即在 AVPlayer 中寻找某个位置

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12134109/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 19:53:23  来源:igfitidea点击:

Seek to a certain position in AVPlayer right after the asset was loaded

objective-cioscocoa-touchvideoavplayer

提问by Besi

This works:I have an AVPlayerwhich plays a video right after it was loaded. And this works fine.

这有效:我有一个AVPlayer在加载后立即播放视频。这工作正常。

This doesn't:

这不会

Instead of starting the video at the beginning, I want to play it at a given position. So I wait until the asset is ready for Play using KVO:

我不想从头开始播放视频,而是想在给定位置播放它。所以我等到资产准备好使用 KVO 播放:

BOOL isReadyToSeek = (self.playerItem.status == AVPlayerStatusReadyToPlay)

And then seek to the given time

然后寻找给定的时间

[playerItem seekToTime:timeInTheMiddleOfTheVideo completionHandler:myHandler];

But the player will always start at the beginning of the video on the initial seek.

但是播放器将始终在初始搜索时从视频的开头开始。

UpdateI tried a dispatch_after with a few seconds but that does not work either. It works after playback but never initially.

更新我在几秒钟内尝试了 dispatch_after ,但这也不起作用。它在播放后起作用,但最初从不起作用。

When I observe self.player.currentItem.durationI keep getting 0as the valueand timescale.

当我观察时,self.player.currentItem.duration我一直0valuetimescale

回答by

Couple of things which may help you:

一些可能对您有帮助的事情:

  1. When checking if the player is ready to play, I check both the player itself and also the player's current item.

    if(self.player.status == AVPlayerStatusReadyToPlay &&
       self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
        [self.player play];
    }
    
  2. It's possible that if you seek to e.g. 15 seconds, it may start from the beginning of the video instead if that is the location of the nearest keyframe. To force the player to seek to the exact location (note: this will take several seconds to do), do this:

    Float64 seconds = 500.0f;
    CMTime targetTime = CMTimeMakeWithSeconds(seconds, NSEC_PER_SEC);
    [self.player seekToTime:targetTime
     toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
    

    Or you can seek to the keyframe explicitly before/after the specified point by specifying one of the arguments as infinity:

    [self.player seekToTime:targetTime
     toleranceBefore:kCMTimePositiveInfinity toleranceAfter:kCMTimeZero];
    
  1. 在检查播放器是否准备好播放时,我会检查播放器本身和播放器的当前项目。

    if(self.player.status == AVPlayerStatusReadyToPlay &&
       self.player.currentItem.status == AVPlayerItemStatusReadyToPlay) {
        [self.player play];
    }
    
  2. 如果您寻求例如 15 秒,它可能会从视频的开头开始,如果那是最近关键帧的位置。要强制玩家寻找确切位置(注意:这需要几秒钟才能完成),请执行以下操作:

    Float64 seconds = 500.0f;
    CMTime targetTime = CMTimeMakeWithSeconds(seconds, NSEC_PER_SEC);
    [self.player seekToTime:targetTime
     toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];
    

    或者,您可以通过将参数之一指定为无穷大来明确地在指定点之前/之后寻找关键帧:

    [self.player seekToTime:targetTime
     toleranceBefore:kCMTimePositiveInfinity toleranceAfter:kCMTimeZero];