如何在64位的Objective-C中获取Quicktime-Movie的开始时间码(SMPTE)? [英] How to get the Start Timecode (SMPTE) of a Quicktime-Movie in Objective-C in 64-bit?

查看:212
本文介绍了如何在64位的Objective-C中获取Quicktime-Movie的开始时间码(SMPTE)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经把头发拉过这个了。

I've been pulling my hair out over this.

我在这里找到了几件事,但没有什么似乎有效。

I've found a few things here, but nothing actually seems to work. And the documentation is really limited.

我想要弄清楚的是如何从时间码中获取Objective-C中的Quicktime电影的开始时间代码跟踪,并从中获得一个人类可读的输出。

What I'm trying to figure out here is how to get the start time code of a Quicktime movie in Objective-C from the timecode track, and getting a human-readable output from that.

我发现这个:
SMPTE TimeCode从快速时间

它在32位模式下工作得很好。但它不工作在64位模式,因为Quicktime API。我需要将它并入已经已经并必须继续运行64位的软件。

It works perfectly in 32-bit mode. But it doesn't work in 64-bit mode because of the Quicktime API. The software I need to incorporate it into already has been and must continue to run 64-bit.

我在这里失去了我的心。任何人都知道这些API?

I'm losing my mind here. Anyone out there know about these APIs?

最后,这里的目标是找出Quicktime的开始时间码,因为它需要在FCP-X XML中设置OFFSET文件。没有它,视频文件是没有音频(或者,实际上,它只是滑了很多)。

Ultimately, the goal here is to figure out the start timecode of the Quicktime because its needed to set the OFFSET in FCP-X XML files. Without it, the video files are brought in without audio (or, really, its just slipped a lot).

推荐答案

使用 AVFoundation 框架代替 QuickTime 。播放器初始化在文档中有详细解释: https://developer.apple.com/library/mac/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html#//apple_ref/doc/uid / TP40010188-CH3-SW2

Use AVFoundation framework instead of QuickTime. The player initialisation is well explained in the documentation: https://developer.apple.com/library/mac/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html#//apple_ref/doc/uid/TP40010188-CH3-SW2

一旦将 AVAsset 加载到内存中,就可以提取第一个样本帧编号em> timeStampFrame )通过读取时间码轨迹的内容(如果存在):

Once your AVAsset is loaded in memory, you can extract the first sample frame number (timeStampFrame) by reading the content of the timecode track if present:

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,并且必须对上面的代码有一些改进,但它适用于我。

This is a little more tricky than the QuickTime API and there must be some improvement to the code above but it works for me.

这篇关于如何在64位的Objective-C中获取Quicktime-Movie的开始时间码(SMPTE)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆