2016-04-26 197 views
1

我試圖用AVAssetwriter錄製視頻,但在追加數據前檢查AVAssetWriterInput屬性readyForMoreMediaData時,我一直收到NO。使用AVAssetWriter錄製視頻

我看到相關的帖子提到類似的問題,當試圖記錄音頻+視頻,所以我拿出了錄音部分,但問題仍然存在(readyForMoreMediaData永遠是NO)。

我的代碼:

- (void)startRecordingWithAssetWriter { 
    NSLog(@"Setting up capture session"); 
    captureSession = [[AVCaptureSession alloc] init]; 

    //----- ADD INPUTS ----- 
    NSLog(@"Adding video input"); 

    //ADD VIDEO INPUT 
    AVCaptureDevice *videoCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; 
    if (videoCaptureDevice) { 
     NSError *error; 
     videoInputDevice = [AVCaptureDeviceInput deviceInputWithDevice:videoCaptureDevice error:&error]; 
     if (!error) { 
      if ([captureSession canAddInput:videoInputDevice]) { 

       [captureSession addInput:videoInputDevice]; 
      } else { 
       NSLog(@"Couldn't add video input"); 
      } 
     } else { 
      NSLog(@"Couldn't create video input"); 
     } 
    } else { 
     NSLog(@"Couldn't create video capture device"); 
    } 

    //ADD AUDIO INPUT 
    NSLog(@"Adding audio input"); 
    AVCaptureDevice *audioCaptureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio]; 
    NSError *error = nil; 
    AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioCaptureDevice error:&error]; 
    NSLog(@"Added audio input: %@", error.description); 
    if (audioInput) { 
     [captureSession addInput:audioInput]; 
    } 


    //----- ADD OUTPUTS ----- 

    captureQueue = dispatch_queue_create("com.recordingtest", DISPATCH_QUEUE_SERIAL); 


    //-- Create the output for the capture session. 
    videoOutput = [[AVCaptureVideoDataOutput alloc] init]; 
    [videoOutput setAlwaysDiscardsLateVideoFrames:YES]; 

    [videoOutput setVideoSettings: 
    [NSDictionary dictionaryWithObject: 
     [NSNumber numberWithInt:kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange] 
           forKey:(id)kCVPixelBufferPixelFormatTypeKey]]; 

    [videoOutput setSampleBufferDelegate:self queue:captureQueue]; 

    if ([captureSession canAddOutput:videoOutput]) { 
     NSLog(@"Added video Output"); 
     [captureSession addOutput:videoOutput]; 
    } 

// audioOutput = [[AVCaptureAudioDataOutput alloc] init]; 
// [audioOutput setSampleBufferDelegate:self queue:captureQueue]; 
//  
// if ([captureSession canAddOutput:audioOutput]) { 
//  NSLog(@"Added audio Output"); 
//  [captureSession addOutput:audioOutput]; 
// } 

    //Create temporary URL to record to 
    NSString *outputPath = [[NSString alloc] initWithFormat:@"%@%@", NSTemporaryDirectory(), @"output.mp4"]; 
    NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath]; 
    NSFileManager *fileManager = [NSFileManager defaultManager]; 
    if ([fileManager fileExistsAtPath:outputPath]) 
    { 
     NSError *error; 
     if ([fileManager removeItemAtPath:outputPath error:&error] == NO) 
     { 
      //Error - handle if requried 
     } 
    } 
    NSError *assetWriterError; 
    assetWriter = [AVAssetWriter assetWriterWithURL:outputURL fileType:AVFileTypeMPEG4 error:&assetWriterError]; 
    if (assetWriterError) { 

     NSLog(@"Error Setting assetWriter: %@", assetWriterError); 
    } 
    if (assetWriter != nil) { 

    } else { 

     NSLog(@"Error Setting assetWriter: %@", assetWriterError); 
    } 
    assetWriterVideoIn = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:nil]; 
    assetWriterVideoIn.expectsMediaDataInRealTime = YES; 
// assetWriterAudioIn = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeAudio outputSettings:nil]; 
// assetWriterAudioIn.expectsMediaDataInRealTime = YES; 
    isRecording = YES; 


    if ([assetWriter canAddInput:assetWriterVideoIn]) { 
     [assetWriter addInput:assetWriterVideoIn]; 
    } 
// if ([assetWriter canAddInput:assetWriterAudioIn]) { 
//  [assetWriter addInput:assetWriterAudioIn]; 
// } 



    [captureSession commitConfiguration]; 

    [captureSession startRunning]; 

} 



- (void)captureOutput:(AVCaptureOutput *)captureOutput 
didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer 
     fromConnection:(AVCaptureConnection *)connection { 
    NSLog(@"didOutputSampleBuffer"); 


    CFRetain(sampleBuffer); 

    dispatch_async(captureQueue, ^{ 

     if (assetWriter) { 

      if (isRecording) { 
       if (captureOutput == videoOutput) { 
        [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeVideo]; 
       } 
//    else if (captureOutput == audioOutput) { 
//     [self writeSampleBuffer:sampleBuffer ofType:AVMediaTypeAudio]; 
//    } 
      } 


     } 

     CFRelease(sampleBuffer); 
    }); 

} 

- (void)writeSampleBuffer:(CMSampleBufferRef)sampleBuffer ofType:(NSString *)mediaType { 
    NSLog(@"writeSampleBuffer: %ld", (long) assetWriter.status); 
    CMTime presentationTime = CMSampleBufferGetPresentationTimeStamp(sampleBuffer); 

    if (assetWriter.status == AVAssetWriterStatusUnknown) { 

     if ([assetWriter startWriting]) { 
      NSLog(@"startSessionAtSourceTime"); 
      [assetWriter startSessionAtSourceTime:presentationTime]; 
     } else { 
      NSLog(@"Error writing initial buffer"); 
     } 
    } 

    if (assetWriter.status == AVAssetWriterStatusWriting) { 

     if (mediaType == AVMediaTypeVideo) { 
      NSLog(@"assetWriterVideoIn.readyForMoreMediaData: %d", assetWriterVideoIn.readyForMoreMediaData); 

      if (assetWriterVideoIn.readyForMoreMediaData) { 
       NSLog(@"appendSampleBuffer"); 

       if (![assetWriterVideoIn appendSampleBuffer:sampleBuffer]) { 
        NSLog(@"Error writing video buffer"); 
       } 
      } 
     } 
//  else if (mediaType == AVMediaTypeAudio) { 
//   if (assetWriterAudioIn.readyForMoreMediaData) { 
// 
//    if (![assetWriterAudioIn appendSampleBuffer:sampleBuffer]) { 
//     NSLog(@"Error writing audio buffer"); 
//    } 
//   } 
//  } 
    } 
} 

回答

0

我設置assetWriterVideoIn = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:nil]; 後能得到一些實際的設置,而不是零它終於奏效。

更改爲此:

NSDictionary *settings = [NSDictionary dictionaryWithObjectsAndKeys:AVVideoCodecH264, AVVideoCodecKey, 
          [NSNumber numberWithInt:480], AVVideoWidthKey,[NSNumber numberWithInt:640], AVVideoHeightKey, nil]; 

assetWriterVideoIn = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:settings]; 
+0

難道你弄到音頻工作壓力太大? – Dmitry