繁体   English   中英

IOS AVPlayer获得fps

[英]IOS AVPlayer get fps

我试图弄清楚如何通过AVPlayer检索视频帧率。 AVPlayerItem有一个速率变量,但它只返回0到2之间的值(播放时通常为1)。 有人知道如何获得视频帧率吗?

干杯

使用AVAssetTrack's nominalFrameRate property

获取FrameRate方法FrameRate :这里的queuePlayerAVPlayer

-(float)getFrameRateFromAVPlayer
{
  float fps=0.00;
  if (self.queuePlayer.currentItem.asset) {
    AVAssetTrack * videoATrack = [[videoAsset tracksWithMediaType:AVMediaTypeVideo] lastObject];
    if(videoATrack)
    {
        fps = videoATrack.nominalFrameRate;
    }
  }
  return fps;
}

对于在不同版本的iOS上播放的相同媒体,返回的这个nominalFrameRate似乎存在差异。 我有一个用ffmpeg以1帧/秒(125帧)编码的视频,每25帧有一个关键帧,当在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是双速。

正如Paresh Navadiya所指出的那样,一个轨道也有一个名义上的帧变量,但这似乎有时会产生奇怪的结果。 我到目前为止找到的最佳解决方案是使用以下内容:

CMTime frameDuration = [myAsset tracksWithMediaType:AVMediaTypeVideo][0].minFrameDuration;
float fps = frameDuration.timescale/(float)frameDuration.value;

上面给出了可变帧速率的略微意外的结果,但是可变帧速率无论如何都有轻微的奇怪行为。 除此之外,它在我的测试中匹配ffmpeg -i。

编辑----

我发现有时上面给出时间kCMTimeZero。 我用于此的解决方法是创建一个带有轨道输出的AVAssetReader,获取第一帧和第二帧的pts,然后减去两者。

Swift 4版的答案:

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM