2017-07-12 7 views
0

タイムコードトラックの時間値を読みたいと思います。そこ (Technical Note 2310を参照)、アップルから 優れたドキュメントがありますが、私はそれはからそのCMSampleBufferを意味 にObjCバージョン、として正確に動作スウィフト3.コア・ロジックを翻訳したAVAssetとSwift 3でタイムコードトラックを読み取る方法は?

のObjective Cで書かれていますタイムコード トラックが読み取られ、CMBlockBufferに変換されます。 CMBlockBufferGetDataPointertimecodeFrame() func)のデータポインタを作成すると、生データは常に で0フレームになります。だから、質問には、どうすれば私は 生データを正しく処理するのですか?

import Foundation 
import AVFoundation 
import CoreMedia 

let movie = URL(fileURLWithPath: "videoWithTimecodeTrack.mov") 
let asset = AVAsset(url: movie) 

asset.loadValuesAsynchronously(forKeys: ["tracks"]) { 

    var error: NSError? 
    guard asset.statusOfValue(forKey: "tracks", error: &error) == AVKeyValueStatus.loaded 
     else { if let error = error { return print(error) } } 

    readStartTimecode(asset: asset) 
} 


func readStartTimecode(ofAsset asset: AVAsset) { 

    let timecodeTracks = asset.tracks(withMediaType: AVMediaTypeTimecode) 
    guard let timecodeTrack = timecodeTracks.first, 
     let assetReader = try? AVAssetReader(asset: asset) else { return } 

    let readerOutput = AVAssetReaderTrackOutput(track: timecodeTrack, outputSettings: nil) 
    assetReader.add(readerOutput) 
    guard assetReader.startReading() else { return } 

    while let sampleBuffer = readerOutput.copyNextSampleBuffer() { 
     if let frame = timecodeFrame(sampleBuffer: sampleBuffer) { 
      print("timecodeFrame: \(frame)") 
     } 
    } 
} 

func timecodeFrame(sampleBuffer: CMSampleBuffer) -> UInt32? { 

    guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer), 
     let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer) 
     else { return nil } 

    var rawData: UnsafeMutablePointer<Int8>? = nil 
    var length: Int = 0 
    var totalLength: Int = 0 

    let status = CMBlockBufferGetDataPointer(blockBuffer, 0, &length, &totalLength, &rawData) 
    guard status == kCMBlockBufferNoErr, 
     let frameRead = rawData?.pointee 
     else { return nil } 

    let type = CMFormatDescriptionGetMediaSubType(formatDescription) 

    if type == kCMTimeCodeFormatType_TimeCode32 { 
     let frame = UInt32(frameRead) 
     let bigFrame = CFSwapInt32BigToHost(frame) 
     print("kCMTimeCodeFormatType_TimeCode32: \(bigFrame)") 
    } 
    if type == kCMTimeCodeFormatType_TimeCode64 { 
     print("kCMTimeCodeFormatType_TimeCode64") 
     // todo 
    } 
    return nil 
}  

編集:データポインタ検索のObjective Cのバージョンは次のようになります。

size_t length = 0; 
size_t totalLength = 0; 
char *rawData = NULL; 

CMBlockBufferGetDataPointer(blockBuffer, 0, &length, &totalLength, &rawData); 
if (status == kCMBlockBufferNoErr) { 
    int32_t *frameNumberRead = (int32_t *)rawData; 
    (int)Endian32_Swap(*frameNumberRead)] 
} 

答えて

1

ソリューションはUInt32(rawData.pointee)のようなInt8データを変換しないためにはなくてUnsafeMutablePointer<Int8>ポインタのメモリにアクセスすることです別の種類(一時的)。これは、次のようになります。

if let frames = rawData?.withMemoryRebound(to: UInt32.self, capacity: 1, { CFSwapInt32BigToHost($0.pointee) }) { 
    return frames 
} 

完全な機能は次のようになります。

func timecodeFrame(sampleBuffer: CMSampleBuffer) -> UInt32? { 

    guard let blockBuffer = CMSampleBufferGetDataBuffer(sampleBuffer), 
     let formatDescription = CMSampleBufferGetFormatDescription(sampleBuffer) 
     else { return nil } 

    var rawData: UnsafeMutablePointer<Int8>? = nil 
    var length: Int = 0 
    var totalLength: Int = 0 

    let status = CMBlockBufferGetDataPointer(blockBuffer, 0, &length, &totalLength, &rawData) 
    guard status == kCMBlockBufferNoErr else { return nil } 

    let type = CMFormatDescriptionGetMediaSubType(formatDescription) 

    if type == kCMTimeCodeFormatType_TimeCode32 { 
     if let frames = rawData?.withMemoryRebound(to: UInt32.self, capacity: 1, { CFSwapInt32BigToHost($0.pointee) }) { 
      return frames 
     } 
    } 
    if type == kCMTimeCodeFormatType_TimeCode64 { 
     if let frames = rawData?.withMemoryRebound(to: UInt64.self, capacity: 1, { CFSwapInt64BigToHost($0.pointee) }) { 
      return UInt32(frames) 
     } 
    } 
    return nil 
} 

私は、これはビデオのタイムコードトラックのスタートタイムコードを読みたい人に便利であると思います。

関連する問題