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

AVAssetWritermetadataプロパティを介して、これを出力ファイルに保存できます。

于 2015-03-31T05:10:04.607 に答える