AVPlayer seekToTime并不在正确的位置上发挥(AVPlayer seekToTime

2019-07-30 10:18发布

我有正在播放的HLS视频流的AVPlayer。 我的用户界面提供一排按钮中的,一个用于在视频的每个“章节”(按钮标记为“1”,“2”,“3”)。 该应用程序从包含章切入以秒记点列表中的服务器下载一些元数据。 例如,一个视频的长度是12分钟 - 的章切入点是0,58,71,230,530,等等等等列表

当用户点击“一章按钮”按钮处理程序代码执行此操作之一:

            [self.avPlayer pause];

    [self.avPlayer seekToTime: CMTimeMakeWithSeconds(seekTime, 600) 
              toleranceBefore: kCMTimeZero 
               toleranceAfter: kCMTimeZero 
            completionHandler: ^(BOOL finished) 
            {
                [self.avPlayer play];
            }];

其中“seekTime”是一个局部变量含有切入点(如上所述)。

问题是,视频并不总是开始在正确的点。 有时它。 但有时是从十分之一秒,到2秒所请求seekTime之前的任何地方。 请求seekTime后,它永远不会发生。

下面是对视频编码的一些统计数据:

编码器:handbrakeCLI编解码器:H.264帧速率:24(实际上,23.976 - 同样,因为它是怎么出手的)视频比特率:多种比特率(64/150/300/500/800/1200)音频比特率:128K关键帧:23.976(每秒1次)

我使用的是苹果mediafilesegmenter工具,当然,和variantplaylistcreator生成播放列表。

该文件被从亚马逊云/ S3存储服务。

我仍然不清楚有关的一个领域是CMTimeMakeWithSeconds - 我曾尝试根据不同的文章/文档我已看过一些变化。 例如,在上面摘录我使用:

CMTimeMakeWithSeconds(seekTime,600)

我也曾尝试:

CMTimeMakeWithSeconds(seekTime,1)

我不能告诉哪个是正确的,但似乎都产生相同的结果不一致!

我也曾尝试:

CMTimeMakeWithSeconds(seekTime,23.967)

有些文章声称这就像一个分子/ denomenator,因此n / 1应该是正确的,其中“n”为秒数(如在CMTimeMakeWithseconds(N,1))。 但是,代码最初是由不同的程序员创建(现在谁走了),他用于preferredTimeScale 600号(即CMTimeMakeWithseconds(N,600))。

任何人都可以提供任何线索,以什么我做错了,或者即使准确性我想达到那种甚至有可能?

而且万一有人不禁要提供“另类”的解决方案,我们已经在考虑打破了视频到独立的流,每章一个,但我们不认为这将使我们在这个意义上,不断变化的章节将需要更长的时间相同的性能作为一个新的AVPlayerItem将必须创建并加载,等等,等等,等等。所以,如果你认为这是将工作的唯一解决方案(和我们预计这将实现我们想要的结果 - 也就是说,每个章节将我们希望它)随意说出这样的话正好开始。

提前致谢!

Answer 1:

int32_t timeScale = self.player.currentItem.asset.duration.timescale;
CMTime time = CMTimeMakeWithSeconds(77.000000, timeScale);
[self.player seekToTime:time toleranceBefore:kCMTimeZero toleranceAfter:kCMTimeZero];

我曾与“seekToTime”的问题。 我解决我的问题与此代码。 “时间表”是这个问题的把戏。

斯威夫特版本:

let playerTimescale = self.player.currentItem?.asset.duration.timescale ?? 1
let time =  CMTime(seconds: 77.000000, preferredTimescale: playerTimescale)
self.player.seek(to: time, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero) { (finished) in /* Add your completion code here */
}


Answer 2:

我的建议:1)不要使用[avplayer seekToTime:toleranceBefore:toleranceAfter:],这会耽误你的寻道时间4-5秒。

2)HLS视频切割成每段为10秒。 你的章节起始现在的位置应该适合这是10 multipes由于段开始于I帧,在这样的价值,你可以得到快速的寻道时间和准确的时间。



Answer 3:

请使用像函数[player seekToTime:CMTimeMakeWithSeconds(seekTime,1)]
因为你的宽容值kCMTimeZero将需要更多的时间来使用seek.Instead的kCMTimeZero公差值,你可以使用kCMTimeIndefinite这相当于我先前指定的功能。



Answer 4:

将这个代码,它可能解决您的问题。

let targetTime = CMTimeMakeWithSeconds(videoLastDuration, 1) // videoLastDuration hold the previous video state.
self.playerController.player?.currentItem?.seekToTime(targetTime, toleranceBefore: kCMTimeZero, toleranceAfter: kCMTimeZero)


文章来源: AVPlayer seekToTime does not play at correct position