【发布时间】:2011-11-08 11:05:55
【问题描述】:
我正在构建一个用于视频分析的 iphone 应用程序,我需要知道影片剪辑中的确切帧数。
我得到了帧速率和持续时间,出于某种原因,我得到了 2880 帧,但我知道影片剪辑实际上有 2840。
如何获得准确的帧数?
【问题讨论】:
标签: iphone c ios video video-processing
我正在构建一个用于视频分析的 iphone 应用程序,我需要知道影片剪辑中的确切帧数。
我得到了帧速率和持续时间,出于某种原因,我得到了 2880 帧,但我知道影片剪辑实际上有 2840。
如何获得准确的帧数?
【问题讨论】:
标签: iphone c ios video video-processing
这取决于视频格式。
如果是原始视频,则 PAL 和 SECAM 规定每秒 25 帧 (fps),NTSC 29.97 实际电影为 24fps。是隔行扫描还是逐行扫描?
它是否已经压缩并因此使用了帧数的近似值?
编辑
啊,所以你的视频是 H.264/MPEG4 标准和 AAC 音频?索引数据保存在文件的“moov”部分中,该部分包含构成文件的所有索引和数据值。有关 MPEG4 标准的更多信息,请查看here
如果您可以提取此数据,它将告诉您每帧的数据大小等。
【讨论】:
确切的帧数通常写在文件中的某处,并且可以检索。但是,视频文件可能包含更多或更少的帧。 例如,您获得 2880 帧,并且您知道应该获得 2840。我的猜测是某些时间戳是相等的。应跳过/忽略与前一个具有相同时间戳的解码帧。你检查了吗? 您还可以获得更少的报告帧。这意味着某些帧的持续时间比预期的要长。例如,如果您以 25 fps 录制影片剪辑,则一帧的持续时间为 40 毫秒。但是,解压后你可能会得到一个持续时间为 80 的帧。这样的帧应该真的有这个持续时间,或者它可以重复两次......
【讨论】:
这里是 节奏拳手 的另一个好答案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。
【讨论】:
真正计算帧数的方法是查询帧时长,然后将总影片时长(以秒为单位)除以帧时长。读取所有帧的建议太慢,实际上无法用于短视频以外的任何内容。 H.264 流中还存在增量帧的问题。您可以通过 AVAssetTrack.timeRange 查询轨道长度,然后可以通过 AVAssetTrack.minFrameDuration 查询帧时长。可以在here 找到执行此计算的工作源代码示例。请注意,这些 CMTime 值需要通过 CMTimeGetSeconds() 传递来转换为浮点时间值。
【讨论】: