11

我开发了一个 iOS 应用程序,它将捕获的相机数据保存到一个文件中,我使用了

(void) captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection

捕获 CMSampleBufferRef 并将其编码为 H264 格式,并且帧将使用AVAssetWriter.

我按照示例源代码创建了这个应用程序:

现在我想获取保存的视频帧的时间戳来创建一个新的电影文件。为此,我做了以下事情

  1. 找到文件并创建AVAssestReader以读取文件

    CMSampleBufferRef sample = [asset_reader_output copyNextSampleBuffer];   
    CMSampleBufferRef buffer;
    
    while ([assestReader status] == AVAssetReaderStatusReading) {
        buffer = [asset_reader_output copyNextSampleBuffer];
    
        // CMSampleBufferGetPresentationTimeStamp(buffer);
    
        CMTime presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(buffer);
        UInt32 timeStamp = (1000 * presentationTimeStamp.value) / presentationTimeStamp.timescale;
    
        NSLog(@"timestamp %u", (unsigned int) timeStamp);
        NSLog(@"reading");
    
        // CFRelease(buffer);
    }
    

打印的值给了我一个错误的时间戳,我需要获取帧的捕获时间。

有什么方法可以获取帧捕获时间戳?

我已经阅读了一个答案以使其具有时间戳,但它没有正确阐述我上面的问题。

更新:

我在写入文件之前读取了示例时间戳,它给了我xxxxx价值(33333.23232)。在我尝试读取文件后,它给了我不同的价值。这有什么具体原因吗??

4

1 回答 1

2

文件时间戳与捕获时间戳不同,因为它们是相对于文件开头的。这意味着它们是您想要的捕获时间戳,减去捕获的第一帧的时间戳:

 presentationTimeStamp = fileFramePresentationTime + firstFrameCaptureTime

所以从文件中读取时,这应该计算你想要的捕获时间戳:

 CMTime firstCaptureFrameTimeStamp = // the first capture timestamp you see
 CMTime presentationTimeStamp = CMTimeAdd(CMSampleBufferGetPresentationTimeStamp(buffer), firstCaptureFrameTimeStamp);

如果您在应用程序启动之间进行此计算,则需要序列化和反序列化第一帧捕获时间,您可以使用CMTimeCopyAsDictionary和来执行此操作CMTimeMakeFromDictionary

AVAssetWriter您可以通过的metadata属性将其存储在输出文件中。

于 2015-03-31T05:10:04.607 回答