3

私はこれで髪を伸ばしてきました。

ここでいくつかのことを見つけましたが、実際には何も機能していないようです。そして、ドキュメントは本当に限られています。

ここで理解しようとしているのは、タイムコード トラックから Objective-C で Quicktime ムービーの開始タイム コードを取得し、そこから人間が読み取れる出力を取得する方法です。

私はこれを見つけました: Quick Time の SMPTE TimeCode

32 ビット モードで完全に動作します。ただし、Quicktime API のため、64 ビット モードでは機能しません。それを組み込む必要があるソフトウェアは、すでに 64 ビットで実行されており、引き続き実行する必要があります。

私はここで私の心を失っています。これらの API について知っている人はいますか?

最終的に、ここでの目標は、FCP-X XML ファイルで OFFSET を設定する必要があるため、Quicktime の開始タイムコードを把握することです。それがなければ、ビデオファイルはオーディオなしで取り込まれます (または、実際には、大幅にずれてしまいます)。

4

1 に答える 1

1

QuickTimeの代わりにAVFoundationフレームワークを使用します。プレーヤーの初期化については、次のドキュメントで詳しく説明されています。 -SW2

AVAssetがメモリにロードされると、タイムコード トラックのコンテンツが存在する場合はそれを読み取ることで、最初のサンプル フレーム番号 ( timeStampFrame )抽出できます

long timeStampFrame = 0;
for (AVAssetTrack * track in [_asset tracks]) {
    if ([[track mediaType] isEqualToString:AVMediaTypeTimecode]) {
        AVAssetReader *assetReader = [AVAssetReader assetReaderWithAsset:_asset error:nil];
        AVAssetReaderTrackOutput *assetReaderOutput = [AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:nil]; 
        if ([assetReader canAddOutput:assetReaderOutput]) {
            [assetReader addOutput:assetReaderOutput];
            if ([assetReader startReading] == YES) {
                int count = 0;

                while ( [assetReader status]==AVAssetReaderStatusReading ) {
                    CMSampleBufferRef sampleBuffer = [assetReaderOutput copyNextSampleBuffer];
                    if (sampleBuffer == NULL) {
                        if ([assetReader status] == AVAssetReaderStatusFailed) 
                            break;
                        else    
                            continue;
                    }
                    count++;

                    CMBlockBufferRef blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer);
                    size_t length = CMBlockBufferGetDataLength(blockBuffer);

                    if (length>0) {
                        unsigned char *buffer = malloc(length);
                        memset(buffer, 0, length);
                        CMBlockBufferCopyDataBytes(blockBuffer, 0, length, buffer);

                        for (int i=0; i<length; i++) {
                            timeStampFrame = (timeStampFrame << 8) + buffer[i];
                        }

                        free(buffer);
                    }

                    CFRelease(sampleBuffer);
                }

                if (count == 0) {
                    NSLog(@"No sample in the timecode track: %@", [assetReader error]);
                }

                NSLog(@"Processed %d sample", count);

            }

        }

        if ([assetReader status] != AVAssetReaderStatusCompleted)
            [assetReader cancelReading];
    }
}

これはQuickTime APIよりも少しトリッキーで、上記のコードを改善する必要がありますが、私にとってはうまくいきます。

于 2012-08-24T04:40:00.040 に答える