如何获取64位Objective-C中Quicktime电影的开始时间码(SMPTE)?

如何获取64位Objective-C中Quicktime电影的开始时间码(SMPTE)?,objective-c,cocoa,quicktime,Objective C,Cocoa,Quicktime,我一直在为此发愁 我在这里发现了一些东西,但实际上似乎什么都不起作用。而且文档也非常有限 我想弄明白的是,如何从时间码轨道中获取Objective-C中Quicktime电影的开始时间码,并从中获得人类可读的输出 我发现: 它可以在32位模式下完美工作。但由于Quicktime API,它在64位模式下无法工作。我需要将其合并到的软件已经并且必须继续运行64位 我在这里发疯了。有人知道这些API吗 最终,这里的目标是找出Quicktime的开始时间代码,因为需要在FCP-XXML文件中设置偏移

我一直在为此发愁

我在这里发现了一些东西,但实际上似乎什么都不起作用。而且文档也非常有限

我想弄明白的是,如何从时间码轨道中获取Objective-C中Quicktime电影的开始时间码,并从中获得人类可读的输出

我发现:

它可以在32位模式下完美工作。但由于Quicktime API,它在64位模式下无法工作。我需要将其合并到的软件已经并且必须继续运行64位

我在这里发疯了。有人知道这些API吗

最终,这里的目标是找出Quicktime的开始时间代码,因为需要在FCP-XXML文件中设置偏移量。如果没有它,视频文件就没有音频(或者,实际上,它只是滑倒了很多)

使用AVFoundation framework而不是QuickTime。文件中对播放器初始化进行了详细说明:

一旦将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];
    }
}
long timeStampFrame=0;
对于(AvassettTrack*在[\u资产轨道]中轨道){
if([[track mediaType]IsequalString:AVMediaTypeTimecode]){
Avassetrader*assetReader=[Avassetrader assetReaderWithAsset:_AssetError:nil];
AVAssetReaderTrackOutput*assetReaderOutput=[AVAssetReaderTrackOutput assetReaderTrackOutputWithTrack:track outputSettings:nil];
如果([AssetTreader CanadOutput:AssetTreaderOutput]){
[AssetTreaderAddOutput:AssetTreaderOutput];
如果([AssetTreader startReading]==是){
整数计数=0;
while([AssetTreader状态]==AvAssetTreader状态读取){
CMSampleBufferRef sampleBuffer=[assetReaderOutput copyNextSampleBuffer];
if(sampleBuffer==NULL){
如果([AssetTreader状态]==AvAssetTreaderStatus失败)
打破
其他的
继续;
}
计数++;
CMBlockBufferRef blockBuffer=CMSampleBufferGetDataBuffer(sampleBuffer);
size\u t length=CMBlockBufferGetDataLength(块缓冲区);
如果(长度>0){

无符号字符*缓冲区=malloc(长度); memset(缓冲区,0,长度); CMBlockBufferCopyDataBytes(块缓冲区,0,长度,缓冲区);
对于(int i=0;iunsigned char*buffer=malloc(长度);正在抛出一些错误,试图解决它…但遇到了一些麻烦。看起来将其作为未签名字符进行转换对我有效。刚刚运行它,它似乎有效!@tinmaru,你是我的英雄。如果你不介意的话,还有一个问题。有没有办法确定文件是否为删除和非删除时间码?我正在尝试使用你给我的作为起点,但我在查找信息时遇到了一些问题。是的,有一些元信息,但生成文件的软件并不总是填写这些信息。我最后计算了样本长度。@mxisaac DF或NDF状态可以使用此答案读取[尽管非常奇怪的是,似乎无法使用相同的方法读取开始时间代码偏移量。