从影片剪辑中获取确切的帧数

时间:2011-11-08 11:05:55

标签: iphone c ios video video-processing

我正在构建一个用于视频分析的iphone应用程序,我需要知道影片剪辑中的确切帧数。

我得到了帧率和持续时间,出于某种原因我得到了2880帧,但我知道影片片段实际上是2840帧。

我怎样才能获得确切数量的帧?

4 个答案:

答案 0 :(得分:1)

确切的帧数通常写在文件内的某处,可以检索。但是,视频文件可能包含更多或更少的帧。 例如,你得到2880帧,你知道你应该得到2840帧。我的猜测是一些时间戳是相同的。应跳过/忽略具有与前一个相同时间戳的解码帧。你检查过了吗? 您还可以获得报告的帧数更少。这意味着某些帧的持续时间比预期的要长。例如,如果您以25 fps记录影片剪辑,则一帧的持续时间为40毫秒。但是,在解压缩后你可能会得到一个持续时间为80的帧。这样的帧应该有这个持续时间,或者它可以重复两次......

答案 1 :(得分:1)

这取决于视频格式。

如果它是原始视频,那么PAL和SECAM指示每个secon(fps)25帧,NTSC 29.97实际电影是24fps。它是隔行扫描还是逐行扫描?

它是否已被压缩,因此使用近似的帧数?

修改

啊,所以你的视频是带有AAC音频的H.264 / MPEG4标准?索引数据保存在文件的“moov”部分中,该部分包含组成文件的所有索引和数据值。有关MPEG4标准的更多信息,请查看here

如果您可以提取此数据,它将告诉您每个帧的数据大小等。

答案 2 :(得分:0)

这是iOS Determine Number of Frames in Video Rhythmic Fistman 的另一个好答案。它在SWIFT中,但我尝试过如下(Objective-C):

- (void)getTotalFramesFromVideo{
    AVURLAsset* asset = [AVURLAsset assetWithURL:URL1];
    NSError* errReader=nil;
    AVAssetReader* reader = [AVAssetReader assetReaderWithAsset:asset error:&errReader];
    if(!errReader){
        AVAssetTrack* track = [asset tracksWithMediaType:AVMediaTypeVideo].firstObject;
        AVAssetReaderOutput* readerOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:nil];
        [reader addOutput:readerOutput];
        [reader startReading];
        long long count = 0;
        BOOL isAvailable = NO;
        do {
            CMSampleBufferRef ref = [readerOutput copyNextSampleBuffer];
            if(ref){
                isAvailable = YES;
                count++;
            }else{
                isAvailable = NO;
            }
        } while (isAvailable == YES);
        NSLog(@"Total Frames in your Video is %@",@(count));
    }else{
        NSLog(@"\nAVAssetReaderError:\n%@",errReader.localizedDescription);
    }
}

对于像我这样想要获取视频帧数的人来说,这可能会有所帮助 注意:您也可以在此方法中获得CMSampleBufferRef

答案 3 :(得分:0)

计算帧数的真正方法是查询帧持续时间,然后将总电影持续时间(以秒为单位)除以帧持续时间。读取所有帧的建议太慢,实际上不能用于短视频。 H.264流中还存在delta帧的问题。您可以通过AVAssetTrack.timeRange查询轨道长度,然后可以通过AVAssetTrack.minFrameDuration查询帧持续时间。可以找到执行此计算的工作源代码示例here。请注意,这些CMTime值需要通过传递给CMTimeGetSeconds()来转换为浮点时间值。