2012-12-07 8 views
7

पर तस्वीरों से फिल्म बनाने में त्रुटि मैं कुछ चित्रों से एक फिल्म बनाने की कोशिश कर रहा हूं। यह एचडी चित्रों ({720, 1280}) या निचले संकल्प के साथ ठीक काम करता है। लेकिन जब मैं पूर्ण एचडी चित्रों के साथ फिल्म बनाने की कोशिश करता हूं {1080, 1920}, वीडियो खराब हो गया है। यह देखने के लिए एक लिंक है कि यह http://www.youtube.com/watch?v=BfYldb8e_18 कैसा दिखता है। क्या आपके पास कोई विचार है कि मैं क्या गलत कर सकता हूं?आईफोन - AVAssetWriter - 1920 × 1080 पिक्सेल

- (void) createMovieWithOptions:(NSDictionary *) options 
{ 
@autoreleasepool { 
    NSString *path = [options valueForKey:@"path"]; 
    CGSize size = [(NSValue *)[options valueForKey:@"size"] CGSizeValue]; 
    NSArray *imageArray = [options valueForKey:@"pictures"]; 
    NSInteger recordingFPS = [[options valueForKey:@"fps"] integerValue]; 
    BOOL success=YES; 
    NSError *error = nil; 

    AVAssetWriter *assetWriter = [[AVAssetWriter alloc] initWithURL:[NSURL fileURLWithPath:path] 
                  fileType:AVFileTypeQuickTimeMovie 
                   error:&error]; 
    NSParameterAssert(assetWriter); 

    NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: 
            AVVideoCodecH264, AVVideoCodecKey, 
            [NSNumber numberWithFloat:size.width], AVVideoWidthKey, 
            [NSNumber numberWithFloat:size.height], AVVideoHeightKey, 
            nil]; 

    AVAssetWriterInput *videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo 
                       outputSettings:videoSettings]; 

    // Configure settings for the pixel buffer adaptor. 
    NSDictionary* bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys: 
             [NSNumber numberWithInt:kCVPixelFormatType_32ARGB], kCVPixelBufferPixelFormatTypeKey, nil]; 

    AVAssetWriterInputPixelBufferAdaptor *adaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:videoWriterInput 
                                sourcePixelBufferAttributes:bufferAttributes]; 

    NSParameterAssert(videoWriterInput); 
    NSParameterAssert([assetWriter canAddInput:videoWriterInput]); 

    videoWriterInput.expectsMediaDataInRealTime = NO; 
    [assetWriter addInput:videoWriterInput]; 

    //Start a session: 
    [assetWriter startWriting]; 
    [assetWriter startSessionAtSourceTime:kCMTimeZero]; 

    CVPixelBufferRef buffer = NULL; 

    //convert uiimage to CGImage. 

    int frameCount = 0; 
    float progress = 0; 
    float progressFromFrames = _progressView.progress; //only for create iflipbook movie 

    for(UIImage * img in imageArray) 
    { 
     if([[NSThread currentThread] isCancelled]) 
     { 
      [NSThread exit]; 
     } 

     [condCreateMovie lock]; 
     if(isCreateMoviePaused) 
     { 
      [condCreateMovie wait]; 
     } 

     uint64_t totalFreeSpace=[Utils getFreeDiskspace]; 
     if(((totalFreeSpace/1024ll)/1024ll)<50) 
     { 
      success=NO; 
      break; 
     } 

     //  @autoreleasepool { 
     NSLog(@"size:%@",NSStringFromCGSize(img.size)); 

     buffer = [[MovieWritter sharedMovieWritter] pixelBufferFromCGImage:[img CGImage] andSize:size]; 

     BOOL append_ok = NO; 
     int j = 0; 
     while (!append_ok && j < 60) 
     { 
      if(adaptor.assetWriterInput.readyForMoreMediaData) 
      { 
       CMTime frameTime = CMTimeMake(frameCount, recordingFPS); 
       append_ok = [adaptor appendPixelBuffer:buffer withPresentationTime:frameTime]; 

       CVPixelBufferRelease(buffer); 

       [NSThread sleepForTimeInterval:0.1]; 


       if(isCreatingiFlipBookFromImported) 
        progress = (float)frameCount/(float)[imageArray count]/2.0 + progressFromFrames; 
       else 
        progress = (float)frameCount/(float)[imageArray count]; 

       [[NSNotificationCenter defaultCenter] postNotificationName:@"movieCreationProgress" object:[NSNumber numberWithFloat:progress]]; 
      } 
      else 
      { 
       [NSThread sleepForTimeInterval:0.5]; 
      } 
      j++; 
     } 
     if (!append_ok) 
     { 
      NSLog(@"error appending image %d times %d\n", frameCount, j); 
     } 
     frameCount++; 

     [condCreateMovie unlock]; 
    } 

    //Finish the session: 
    [videoWriterInput markAsFinished]; 
    [assetWriter finishWriting]; 

    NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:success], @"success", 
          path, @"path", nil]; 

    [[NSNotificationCenter defaultCenter] postNotificationName:@"movieCreationFinished" object:dict]; 
} 
} 

* संपादित करें। यहाँ के लिए कोड है [[MovieWritter sharedMovieWritter] pixelBufferFromCGImage:]

- (CVPixelBufferRef) pixelBufferFromCGImage: (CGImageRef) image andSize:(CGSize) size 
{ 
@autoreleasepool { 
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys: 
          [NSNumber numberWithBool:YES], kCVPixelBufferCGImageCompatibilityKey, 
          [NSNumber numberWithBool:YES], kCVPixelBufferCGBitmapContextCompatibilityKey, 
          nil]; 
    CVPixelBufferRef pxbuffer = NULL; 

    CVReturn status = CVPixelBufferCreate(kCFAllocatorDefault, size.width, 
              size.height, kCVPixelFormatType_32ARGB, (__bridge CFDictionaryRef) options, 
              &pxbuffer); 
    NSParameterAssert(status == kCVReturnSuccess && pxbuffer != NULL); 

    CVPixelBufferLockBaseAddress(pxbuffer, 0); 
    void *pxdata = CVPixelBufferGetBaseAddress(pxbuffer); 
    NSParameterAssert(pxdata != NULL); 

    CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB(); 
    CGContextRef context = CGBitmapContextCreate(pxdata, size.width, 
               size.height, 8, 4*size.width, rgbColorSpace, 
               kCGImageAlphaNoneSkipFirst); 
    NSParameterAssert(context); 
    CGContextConcatCTM(context, CGAffineTransformMakeRotation(0)); 
    CGContextDrawImage(context, CGRectMake(0, 0, CGImageGetWidth(image), 
              CGImageGetHeight(image)), image); 
    CGColorSpaceRelease(rgbColorSpace); 
    CGContextRelease(context); 

    CVPixelBufferUnlockBaseAddress(pxbuffer, 0); 

    return pxbuffer; 
} 
} 
+1

की एक बहु के लिए कोड पोस्ट करें होना चाहिए भी। –

+0

यह अच्छा लगता है कि –

उत्तर

2

सुंदर यकीन है कि यह या तो एक HW सीमा या एक बग है। कृपया रडार दर्ज करें।

+0

मैंने स्वयं को इस समस्या में चलाया है और हां यह सिम्युलेटर में अपेक्षाकृत काम करता है क्योंकि यह 9 0% हार्डवेयर सीमा है। –

2

कैसे कुछ इस तरह प्राप्त करने के बारे पिक्सेल बफर

//you could use a cgiimageref here instead 
    CFDataRef imageData= CGDataProviderCopyData(CGImageGetDataProvider(imageView.image.CGImage)); 
    NSLog (@"copied image data"); 
    cvErr = CVPixelBufferCreateWithBytes(kCFAllocatorDefault, 
             FRAME_WIDTH, 
             FRAME_HEIGHT, 
             kCVPixelFormatType_32BGRA, 
             (void*)CFDataGetBytePtr(imageData), 
             CGImageGetBytesPerRow(imageView.image.CGImage), 
             NULL, 
             NULL, 
             NULL, 
             &pixelBuffer); 
    NSLog (@"CVPixelBufferCreateWithBytes returned %d", cvErr); 

    CFAbsoluteTime thisFrameWallClockTime = CFAbsoluteTimeGetCurrent(); 
    CFTimeInterval elapsedTime = thisFrameWallClockTime - firstFrameWallClockTime; 
    NSLog (@"elapsedTime: %f", elapsedTime); 
    CMTime presentationTime = CMTimeMake(elapsedTime * TIME_SCALE, TIME_SCALE); 

    // write the sample 
    BOOL appended = [assetWriterPixelBufferAdaptor appendPixelBuffer:pixelBuffer withPresentationTime:presentationTime]; 
    CVPixelBufferRelease(pixelBuffer); 
    CFRelease(imageData); 
    if (appended) { 
     NSLog (@"appended sample at time %lf", CMTimeGetSeconds(presentationTime)); 
    } else { 
     NSLog (@"failed to append"); 
     [self stopRecording]; 
     self.startStopButton.selected = NO; 
    } 
-1

तुम भी, कब्जा सेटिंग्स पूर्व निर्धारित सेट करने के लिए हालांकि उच्च आम तौर पर उपयुक्त है चाहते हो सकता है और उस डिफ़ॉल्ट */ कब्जा स्थापित करने प्रीसेट को परिभाषित करने के स्थिरांक है sessionPreset संपत्ति का उपयोग कर।

एनएसएसटींग * कॉन्स AVCaptureSessionPresetPhoto;

एनएसएसटींग * कॉन्स AVCaptureSessionPresetHigh;

एनएसएसटींग * कॉन्स AVCaptureSessionPresetMedium;

एनएसएसटींग * कॉन्स AVCaptureSessionPresetLow;

एनएसएसटींग * कॉन्स AVCaptureSessionPreset352x288;

एनएसएसटींग * कॉन्स AVCaptureSessionPreset640x480;

एनएसएसटींग * कॉन्स AVCaptureSessionPreset1280x720;

एनएसएसटींग * कॉन्स AVCaptureSessionPreset1920x1080;

एनएसएसटींग * कॉन्स AVCaptureSessionPresetiFrame960x540;

एनएसएसटींग * कॉन्स AVCaptureSessionPresetiFrame1280x720; */

// इस तरह यह सेट

self.captureSession.sessionPreset = AVCaptureSessionPreset1920x1080;

// या इस जब आप avcapturesession परिभाषित तरह

[self.captureSession setSessionPreset: AVCaptureSessionPreset1920x1080];

+1

यह सबसे अप्रासंगिक है। मेरे सहयोगी और मुझे इस समस्या को ठीक करने की आवश्यकता है जब हम पूर्ण HD छवियों को AVAssetWriterInputPixelBufferAdaptor पर खिला रहे हैं। छवियों को कैमरा रोल से लिया जा सकता है ...हम पूर्ण एचडी रिज़ॉल्यूशन को सुइट करने के लिए उनका आकार बदल रहे हैं। हम कैमरा बफर से भी फ्रेम को कैप्चर कर रहे हैं लेकिन वे अभी भी AVAssetWriterInputPixelBufferAdaptor का उपयोग करके काम नहीं करते हैं। शायद यह AVAssetWriterInputPixelBufferAdaptor के साथ एक बग या सीमा है। –

+1

प्रीसेट को सेट करने से पहले मेरे पास कुछ समस्याएं हैं इसलिए मैंने इसका उल्लेख किया, खराब व्यवहार होने से आपको त्वरित मदद नहीं मिलेगी। क्या पिक्सेल प्रारूप गलत हो सकता है kCVPixelFormatType_32ARGB को kCVPixelFormatType_32BGRA को नमूना में बदलने की कोशिश करें, मैं दिखाता हूं कि –

+0

पिक्सेल प्रारूप में कुछ भी नहीं है। appendPixelBuffer ... विधि भी एक हाँ प्रतिक्रिया देता है। हमने आकार, सेटिंग्स, सब कुछ जांच लिया है, लेकिन यह अभी भी काम नहीं कर रहा है। –

3

मैं एक ही समस्या थी और this answer यह हल: [MovieWritter sharedMovieWritter] pixelBufferFromCGImage: वीडियो के आकार 16.

+0

आपको बहुत बहुत धन्यवाद! दिनों के लिए इस के विभिन्न बिट्स के साथ संघर्ष कर रहे थे। एक हास्यास्पद आवश्यकता है, लेकिन ऐप्पल उनसे भरा है। – Linuxios

संबंधित मुद्दे