2012-08-23 4 views
2

나는 이것으로 내 머리카락을 꺼내왔다.Objective-C에서 Quicktime-Movie의 SMPTE (Start Timecode)를 64 비트로 얻는 방법은 무엇입니까?

여기에 몇 가지 사실을 발견했지만 실제로 작동하는 것은 없습니다. 그리고 문서는 실제로 제한되어 있습니다.

내가 여기서 알아 내려고하는 것은 목표 -C에서 타임 코드 트랙의 퀵타임 무비의 시작 시간 코드를 얻는 방법과 그것을 인간이 읽을 수있는 출력으로 만드는 것입니다.

이걸 발견했습니다 : 그것은 32 비트 모드에서 완벽하게 작동 SMPTE TimeCode from Quick Time

. 그러나 Quicktime API 때문에 64 비트 모드에서는 작동하지 않습니다. 이미 그것을 통합해야하는 소프트웨어는 64 비트를 계속 실행 해 왔으며 계속 실행해야합니다.

나는 여기서 내 마음을 잃고있다. 누구든지이 API에 대해 알고 있습니까?

궁극적으로 목표는 FCP-X XML 파일에 OFFSET을 설정해야하기 때문에 Quicktime의 시작 타임 코드를 파악하는 것입니다. 그것 없이는, 비디오 파일은 오디오없이 (또는, 정말로, 그냥 많이 미끄러 져서) 가져 왔습니다.

답변

1

QuickTime 대신 AVFoundation 프레임 워크를 사용하십시오. 플레이어 초기화 잘 문서에 설명 : 당신의 AVAsset이 메모리에로드되면 https://developer.apple.com/library/mac/#documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/02_Playback.html#//apple_ref/doc/uid/TP40010188-CH3-SW2

, 당신은 타임 코드 트랙의 내용 존재하는 경우를 읽어 첫 번째 샘플 프레임 번호 (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]; 
    } 
} 

이 조금 더 까다 롭습 퀵타임 API보다 위의 코드에 약간의 개선이 있어야하지만 나를 위해 작동합니다.

+0

unsigned char * buffer = malloc (length); 몇 가지 오류를 던지고 그것을 풀려고하고 있지만 문제가 있습니다. – mxisaac

+0

나를 위해 일한 서명되지 않은 문자로 캐스팅하는 것처럼 보입니다. 그냥 달아서 작동하는 것처럼 보입니다! @ tinmaru, 당신은 내 영웅입니다. – mxisaac

+0

다른 질문 하나, 별거 없다면. 파일이 드롭 및 논 드롭 타임 코드인지 확인하는 방법이 있습니까? 나는 네가 나에게 준 점을 점프 포인트로 사용하려고 노력하고 있지만 정보를 찾는 데 어려움을 겪고있다. – mxisaac