我试着去弄清楚如何检索通过AVPlayer一个视频帧速率。 AVPlayerItem具有率可变但它只返回(通常为1播放时)0和2之间的值。 任何人有一个想法如何获得视频的帧速率?
干杯
我试着去弄清楚如何检索通过AVPlayer一个视频帧速率。 AVPlayerItem具有率可变但它只返回(通常为1播放时)0和2之间的值。 任何人有一个想法如何获得视频的帧速率?
干杯
使用AVAssetTrack's
nominalFrameRate
property
。
下面的方法来得到FrameRate
:这里queuePlayer
是AVPlayer
-(float)getFrameRateFromAVPlayer
{
float fps=0.00;
if (self.queuePlayer.currentItem.asset) {
AVAssetTrack * videoATrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject];
if(videoATrack)
{
fps = videoATrack.nominalFrameRate;
}
}
return fps;
}
人们似乎在这个nominalFrameRate差异返回同一媒体上不同版本的iOS播放。 我有每25个帧的关键帧我的ffmpeg编码以每秒(125帧)1帧的视频和iOS上的应用程式加载时7.x中的(标称)的帧速率是1.0,而在iOS 8.X的(标称值)的帧速率是0.99。 这似乎是一个非常小的差异,但在我的情况,我需要精确地导航到影片中的一个给定的框架与此不同的螺丝了这样的导航(电影是演示幻灯片序列的编码)。 既然我已经知道了我的应用程序需要播放视频(例如1 fps)的我可以简单地依赖于这个值,而不是动态地确定(通过nominalFrameRate值)的帧速率,但是我不知道为什么会有之间的这种差异的帧速率IOS版本就因为这nominalFrameRate去。 有任何想法吗?
我不知道在什么AVPlayer
,可以帮助你计算帧速率。
AVPlayerItem
rate
属性是播放速率,无关的帧速率。
越容易选择是获得AVAssetTrack
并阅读其nominalFrameRate
属性。 只需创建一个AVAsset
,你会得到轨道的数组。
或者使用AVAssetReader
逐帧读取视频帧,获得其呈现时间和计数多少帧是在同一秒钟,然后平均几秒钟或整个视频。
上AVPlayer率值是相对于实时的速度与它的演奏,例如0.5是慢动作,2是双速。
作为帕雷什Navadiya指出的轨道也有。然而nominalFrameRate变量这似乎有时会给奇怪的结果。 到目前为止,我已经找到了最好的解决方案是使用以下命令:
CMTime frameDuration = [myAsset tracksWithMediaType:AVMediaTypeVideo][0].minFrameDuration;
float fps = frameDuration.timescale/(float)frameDuration.value;
以上给出的可变帧速率,但可变帧速率略微意外的结果具有稍微异常行为反正。 除此之外,它在我的测试中的ffmpeg -i匹配。
编辑----
我有时发现上面给出的时间kCMTimeZero。 我用这个解决方法是创建一个声道输出的AVAssetReader,获得第一帧和第二帧的PTS然后做两个减法。
雨燕4.0版本的答案:
let asset = avplayer.currentItem.asset
let tracks = asset.tracks(withMediaType: .video)
let fps = tracks?.first?.nominalFrameRate
记住要处理零检查。
这是不是要去工作了,API已经改变了,和这个职位是旧的。 :(雨燕4回答也很酷,这是答案是相似的。
你从一开始视频轨道AVPlayerItem
,你检查FPS那里。 :)
private var numberOfRenderingFailures = 0
func isVideoRendering() -> Bool {
guard let currentItem = player.currentItem else { return false }
// Check if we are playing video tracks
let isRendering = currentItem.tracks.contains { ($0.assetTrack?.mediaType == .video) && ($0.currentVideoFrameRate > 5) }
if isRendering {
numberOfRenderingFailures = 0
return true
}
numberOfRenderingFailures += 1
if numberOfRenderingFailures < 5 {
return true
}
return false
}