2016-12-16 16 views
1

我正在使用AVAssetWriterVideoInput將緩衝區追加到文件。我有這樣的代碼:未能使用AVAssetWriterVideoInput向視頻文件添加幀。失敗,未記錄在最後的錯誤-12738

if (_assetWriter.status == AVAssetWriterStatusWriting) { 
    // If the asset writer status is writing, append sample buffer to its corresponding asset writer input 
    if (mediaType == AVMediaTypeVideo) { 
     if (_assetWriterVideoInput.readyForMoreMediaData) { 
     if (![_assetWriterVideoInput appendSampleBuffer:sampleBuffer]) { 
      NSLog(@"error: %@", [_assetWriter.error localizedFailureReason]); 
      NSLog(@"error: %@", [_assetWriter.error localizedRecoveryOptions]); 
      NSLog(@"error: %@", [_assetWriter.error localizedDescription]); 
      NSLog(@"error: %@", [_assetWriter.error domain]); 
      NSLog(@"error: %@", [_assetWriter.error userInfo]); 
     } else 
      NSLog(@"frame saved"); 
     } 
    } 

此行

if (![_assetWriterVideoInput appendSampleBuffer:sampleBuffer]) { 

失敗,unknown error和代碼-12738,很顯然未在任何documentation發現,與所有蘋果文檔的預期。

另外,我懷疑這是一個未知的錯誤,原因很簡單,AVFoundation中存在大量未知錯誤的代碼,並且系統正在挑選代碼-12738它顯然知道的不僅僅是說它是未知的。

看着正在保存的文件,它保持0兆字節,因爲沒有保存緩衝區/幀。

AVAssetWriterVideoInput創建這樣的:

CMVideoDimensions dimensions = CMVideoFormatDescriptionGetDimensions(currentFormatDescription); 
    NSUInteger numPixels = dimensions.width * dimensions.height; 
    NSUInteger bitsPerSecond; 

    // Assume that lower-than-SD resolutions are intended for streaming, and use a lower bitrate 
    NSUInteger bitsPerPixel = 11.4; // This bitrate matches the quality produced by AVCaptureSessionPresetHigh. 

    bitsPerSecond = numPixels * bitsPerPixel; 

    NSDictionary *videoCompressionSettings = @{AVVideoCodecKey     : AVVideoCodecH264, 
              AVVideoWidthKey     : @(dimensions.width), 
              AVVideoHeightKey     : @(dimensions.height), 
              AVVideoCompressionPropertiesKey : @{ AVVideoAverageBitRateKey  : @(bitsPerSecond), 
                        AVVideoMaxKeyFrameIntervalKey : @(30)} }; 

    if ([_assetWriter canApplyOutputSettings:videoCompressionSettings forMediaType:AVMediaTypeVideo]) 
    { 
    // Intialize asset writer video input with the above created settings dictionary 
    _assetWriterVideoInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoCompressionSettings]; 
    _assetWriterVideoInput.expectsMediaDataInRealTime = YES; 

和緩衝,當它被附加有以下特點:

CMSampleBuffer 0x1009e12a0 retainCount: 1 allocator: 0x1b762cbb8 
    invalid = NO 
    dataReady = YES 
    makeDataReadyCallback = 0x0 
    makeDataReadyRefcon = 0x0 
    formatDescription = <CMVideoFormatDescription 0x[0x1b762cbb8]> { 
    mediaType:'vide' 
    mediaSubType:'BGRA' 
    mediaSpecific: { 
     codecType: 'BGRA'  dimensions: 1920 x 1080 
    } 
    extensions: {<CFBasicHash 0x17087c2c0 [0x1b762cbb8]>{type = immutable dict, count = 2, 
entries => 
    0 : <CFString 0x1b1c6d460 [0x1b762cbb8]>{contents = "Version"} = <CFNumber 0xb000000000000022 [0x1b762cbb8]>{value = +2, type = kCFNumberSInt32Type} 
    2 : <CFString 0x1b1c6d3e0 [0x1b762cbb8]>{contents = "CVBytesPerRow"} = <CFNumber 0xb00000000001e002 [0x1b762cbb8]>{value = +7680, type = kCFNumberSInt32Type} 
} 
} 
} 
    sbufToTrackReadiness = 0x0 
    numSamples = 1 
    sampleTimingArray[1] = { 
     {PTS = {290309939228910/1000000000 = 290309.939}, DTS = {INVALID}, duration = {INVALID}}, 
    } 
    imageBuffer = 0x170321180 

I have a sample code here如果你想查詢的問題。該代碼準備以4K拍攝視頻。如果您的設備無法做到這一點,請將AVCaptureSessionPreset3840x2160行更改爲AVCaptureSessionPresetHigh inside ProcessadorVideo.m`。示例代碼從視頻流中裁剪出一個矩形,並對其應用漫畫效果。 謝謝

+0

您是否調用'startSessionAtSourceTime'? –

+0

這是一個類似於你的其他問題的問題http://stackoverflow.com/a/41207678/22147? –

+0

抱歉,延遲迴答:不。試過了。問題依然存在。 – SpaceDog

回答

1

我試過你的示例,但無法重現錯誤-12783。但是我得到了另一個錯誤-12780。我使用iPhone 6s,所以不知道是否是由於這一點。

無論如何,我可以修復錯誤-12780。由於舊時間戳,您正面臨此問題。爲了進行調試,我在應用程序中添加了一些日誌。見下文

2017年1月26日15:00:35.809590 NotWriting [16829:3116125]起始於401051199680537 2017年1月26日15:00:35.809986 NotWriting [16829:3116125]具有時間戳附加視頻緩衝器401051199680537 2017 -01-26 15:00:35.810008 NotWriting [16829:3116125] presentationTimeStamp小於上一幀的時間戳,因此可能會失敗 2017-01-26 15:00:35.815605 NotWriting [16829:3116125]錯誤:發生未知錯誤(-12780)

寫入緩衝區時,您必須確保演示時間戳大於您寫入的最後一幀,否則寫入將失敗。您可以使用以下邏輯添加支票:

CMTime presentationTimeStamp = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); 
     if(CMTIME_COMPARE_INLINE(presentationTimeStamp, <=, lastpresentationTimeStamp)) 
     { 
      NSLog(@"presentationTimeStamp is less than last frame timestamp, So rejecting frame"); 
      return; 
     } 
     lastpresentationTimeStamp = presentationTimeStamp; 
+0

謝謝。輝煌! – SpaceDog

相關問題