How to get the Start Timecode (SMPTE) of a Quicktime-Movie in Objective-C in 64-bit?

后端 未结 1 1727
情歌与酒
情歌与酒 2021-01-03 10:16

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.

What I

相关标签:
1条回答
  • 2021-01-03 10:51

    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

    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];
        }
    }
    

    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.

    0 讨论(0)
提交回复
热议问题