通过AVAssetReader读取样本

13

如何通过AVAssetReader读取样本?我找到了使用AVAssetReader复制或混合的示例,但这些循环始终由AVAssetWriter循环控制。是否可能只创建一个AVAssetReader并通过它进行阅读,获取每个样本?

谢谢。

2个回答

27

从您的问题中不清楚您是在谈论视频样本还是音频样本。要读取视频样本,您需要执行以下操作:

  1. 构建AVAssetReader:

    asset_reader = [[AVAssetReader alloc] initWithAsset:asset error:&error]; (这里进行错误检查)

  2. 从您的资源中获取视频轨道:

    NSArray* video_tracks = [asset tracksWithMediaType:AVMediaTypeVideo]; AVAssetTrack* video_track = [video_tracks objectAtIndex:0];

  3. 设置所需的视频帧格式:

    NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init];
    [dictionary setObject:[NSNumber numberWithInt:<来自CVPixelBuffer.h的格式代码>] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey];

    请注意,某些视频格式可能无法正常工作,如果您正在进行实时处理,则某些视频格式的性能比其他格式更好(例如,BGRA比ARGB快)。

  4. 构建实际的轨道输出并将其添加到资源阅读器中:

    AVAssetReaderTrackOutput* asset_reader_output = [[AVAssetReaderTrackOutput alloc] initWithTrack:video_track outputSettings:dictionary];
    [asset_reader addOutput:asset_reader_output];
  5. 启动资产阅读器:

    [asset_reader startReading];

  6. 读取样本:

    CMSampleBufferRef buffer;
    while ( [asset_reader status]==AVAssetReaderStatusReading )
          buffer = [asset_reader_output copyNextSampleBuffer];
    

谢谢Damian。我实际上是在问关于音频的问题。我可以将音频放入缓冲区,但不知道如何访问缓冲区内的样本。 - Eric Christensen
我已经实现了视频样本读取,但是有时会出现空白视频帧(对于某些视频则一直如此)。没有错误,只有空白帧。有什么想法吗? - Dave Branton
不确定,抱歉。也许可以在示例中检查演示时间戳?你能想出一种始终创建空白视频的方法吗 - 也许这会有所帮助? - damian
@damian,我能否从“缓冲区”中获取帧捕获的时间戳? - Mr.G
@Mr.G 是的,请尝试使用CMSampleBufferGetPresentationTimeStamp()。文档在这里:https://developer.apple.com/library/ios/documentation/CoreMedia/Reference/CMSampleBuffer/index.html#//apple_ref/c/func/CMSampleBufferGetPresentationTimeStamp - damian

2

damian的回答对我有用,只需进行一点小修改即可:在第3步中,我认为需要将字典设置为可变的:

NSMutableDictionary* dictionary = [[NSMutableDictionary alloc] init];

2
只需使用现代Objective-C的@{(NSString*)kCVPixelBufferPixelFormatTypeKey : @(<CVPixelBuffer.h中的格式代码>)}或经典的[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:<CVPixelBuffer.h中的格式代码>] forKey:(NSString*)kCVPixelBufferPixelFormatTypeKey]即可,无需使其可变。在初始化时传递键/对象不需要可变性。 - Regexident
感谢您的澄清,Regexidnet。 - Matt Wallis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接