【发布时间】:2012-07-12 20:28:27
【问题描述】:
我有一个正在播放 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”是一个包含切入点的本地变量(如上所述)。
问题在于视频并不总是从正确的位置开始。有时确实如此。但有时它在请求的 seekTime 之前的十分之一秒到 2 秒之间。它永远不会在请求的 seekTime 之后开始。
以下是视频编码的一些统计数据:
编码器:handbrakeCLI 编解码器:h.264 帧速率:24(实际上是 23.976 - 与拍摄方式相同) 视频比特率:多种比特率(64/150/300/500/800/1200) 音频比特率:128k 关键帧:23.976(每秒 1 个)
当然,我正在使用 Apple mediafilesegmenter 工具和 variantplaylistcreator 来生成播放列表。
文件是从 Amazon Cloud/S3 存储桶提供的。
我仍然不清楚的一个领域是 CMTimeMakeWithSeconds - 我已经根据我阅读的不同文章/文档尝试了几种变体。例如,在上面的摘录中我使用的是:
CMTimeMakeWithSeconds(seekTime, 600)
我也试过了:
CMTimeMakeWithSeconds(seekTime, 1)
我不知道哪个是正确的,尽管两者似乎产生了相同的不一致结果!
我也试过了:
CMTimeMakeWithSeconds(seekTime, 23.967)
一些文章声称这就像一个分子/分母,所以 n/1 应该是正确的,其中“n”是秒数(如 CMTimeMakeWithseconds(n, 1))。但是,该代码最初是由另一个程序员(现在已经离开)创建的,他使用 600 数字作为首选时间刻度(即 CMTimeMakeWithseconds(n, 600))。
任何人都可以提供任何线索来说明我做错了什么,或者即使我试图达到的准确度是可能的吗?
如果有人想提供“替代”解决方案,我们已经在考虑将视频分成单独的流,每章一个,但我们不认为这会给我们带来与更改章节相同的性能将需要更长的时间,因为必须创建和加载一个新的 AVPlayerItem 等等等等。所以如果你认为这是唯一可行的解决方案(我们确实希望这会达到我们想要的结果 - 即。每一章都会从我们想要的地方开始)随意说出来。
提前致谢!
【问题讨论】:
标签: ios video-streaming avplayer