【问题标题】:Getting the exact number of frames from movie clip从影片剪辑中获取确切的帧数
【发布时间】:2011-11-08 11:05:55
【问题描述】:

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

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

如何获得准确的帧数?

【问题讨论】:

    标签: iphone c ios video video-processing


    【解决方案1】:

    这取决于视频格式。

    如果是原始视频,则 PAL 和 SECAM 规定每秒 25 帧 (fps),NTSC 29.97 实际电影为 24fps。是隔行扫描还是逐行扫描?

    它是否已经压缩并因此使用了帧数的近似值?

    编辑

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

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

    【讨论】:

    • 视频标准和隔行与逐行与捕获的帧数完全无关。
    • 特别是 H.264,由 iPad 拍摄的 AAC
    • natko - 如果 Or.Ron 正在处理原始视频(YUV、RGB 等),它确实如此。因为他正在处理压缩格式。
    • Ha 可以打开那个 H264 并从元数据中读取帧数。它不仅在极少数情况下出现。颜色格式、视频标准和扫描类型与捕获的帧数没有任何关系。
    • 正如我所说 - 只是因为他处理的是压缩格式而不是原始视频格式。
    【解决方案2】:

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

    【讨论】:

    • 在文件中找不到总帧数,帧率为29.3。关键是在我开始阅读所有帧之前我需要知道帧号
    • 首先你写“我知道影片剪辑实际上有 2840”,现在你说“我找不到文件中的总帧数”。你是怎么得到2840的?尝试逐帧解码并显示每个解码帧的时间戳。附:我假设您正在阅读该视频剪辑中的一个视频流。
    • 视频没有说 2840 我数着它是逐帧播放的。是的,我只阅读电影的视频轨道!所以基本上你是说没有办法知道确切的总帧数?
    • 是的,有可能。例如,ffmpeg 会告诉您任何有效 H.264 视频剪辑的帧数。
    • 那么你认为这个工具是如何实现它的呢?只是(持续时间)*(fps)?
    【解决方案3】:

    这里是 节奏拳手 的另一个好答案iOS Determine Number of Frames in Video。它在 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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-08-23
        • 2015-07-07
        • 2013-04-22
        • 1970-01-01
        • 2012-06-01
        • 2011-08-10
        • 1970-01-01
        • 2012-05-24
        相关资源
        最近更新 更多