title: Capture Video Frames sample code for IOS 7.0 and up
body: <p>I am trying to come up with IOS 7 code for this Apple Q&amp;A code on how to capture video frames: <a href="https://developer.apple.com/library/ios/qa/qa1702/_index.html" rel="nofollow">AppleQ&amp;A1702</a></p>
  
  <p>So far I think that I have replaced the deprecated minFrameDuration correctly with is code:</p>
  
  <pre><code>// If you wish to cap the frame rate to a known value, such as 2 fps, set minFrameDuration.
  //output.minFrameDuration = CMTimeMake(1, 2); //deprecated
  [device setActiveVideoMinFrameDuration:CMTimeMake(1, 2)];  //new in IOS7
  [device setActiveVideoMaxFrameDuration:CMTimeMake(1, 2)];
  </code></pre>
  
  <p>But, I can not run the code because I get a 'No interface error' for setSession on this line:</p>
  
  <pre><code>// Assign session to an ivar.
  [self setSession:session];
  </code></pre>
  
  <p>Also, I get an incompatible type warning on this line:</p>
  
  <pre><code>[output setSampleBufferDelegate:self queue:queue];
  </code></pre>
  
  <p>I believe there are simple answers for this error and warning but after lots of searching I am stumped.
  Can someone help me figure out why I get this error and warning straight from Apple sample code? Thanks Carmen</p>
  
  <p>[EDIT1] I don't think I was quite there with my deprecated minFrameDuration fix and it may be that the setSession method is NOT necessary. I am trying to piece together cut and paste code that works to capture images from a video at a specified frame rate for IOS7  App that does NOT need to run on less than 7.0.  I am temporarily putting the captured images in a UIImageView on my storyboard.</p>
  
  <p>It shouldn't be this hard.</p>
  
  <p>Here is the whole code section I have so far but it still does not trigger the captureOutput Method after I call setupCaptureSession from my viewDidLoad and the incompatible type warning mentioned above still exists, can anyone see what is wrong (I am still a newbie so be nice :)</p>
  
  <pre><code>// Create and configure a capture session and start it running
  - (void)setupCaptureSession
  {
      NSError *error = nil;
  
      // Create the session
      AVCaptureSession *session = [[AVCaptureSession alloc] init];
  
      // Configure the session to produce resolution for video frames
      session.sessionPreset = AVCaptureSessionPresetHigh;
  
      // Find a suitable AVCaptureDevice
      AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
  
      // Create a device input with the device and add it to the session.
      AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
                                                                                                error:&amp;error];
      if (!input) {
          // Handling the error appropriately.
      }
      [session addInput:input];
  
      // Create a VideoDataOutput and add it to the session
      AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
      [session addOutput:output];
  
      // Configure your output.
      dispatch_queue_t queue = dispatch_queue_create("myQueue", NULL);
      [output setSampleBufferDelegate:self queue:queue];
  
      // Specify the pixel format
      output.videoSettings =
      [NSDictionary dictionaryWithObject:
       [NSNumber numberWithInt:kCVPixelFormatType_32BGRA]
                                           forKey:(id)kCVPixelBufferPixelFormatTypeKey];
  
  
      // If you wish to cap the frame rate to a known value, such as 2 fps, set
      // minFrameDuration.
      //output.minFrameDuration = CMTimeMake(1, 2); //deprecated
  
  
      //AVCaptureConnection *conn = [output connectionWithMediaType:AVMediaTypeVideo];
  
      //if (conn.supportsVideoMinFrameDuration)  // these are deprecated in IOS7
      //  conn.videoMinFrameDuration = CMTimeMake(1,2);
      //if (conn.supportsVideoMaxFrameDuration)
      //  conn.videoMaxFrameDuration = CMTimeMake(1,2);
  
      NSError *error2;
      [device lockForConfiguration:&amp;error2];
      if (error2 == nil) {
          if (device.activeFormat.videoSupportedFrameRateRanges){
              [device setActiveVideoMinFrameDuration:CMTimeMake(1, 2)];
              [device setActiveVideoMaxFrameDuration:CMTimeMake(1, 2)];
          }else{
              //handle condition
          }
      }else{
          // handle error2
      }
      [device unlockForConfiguration];
  
  
      // Start the session running to start the flow of data
      [session startRunning];
  
      // Assign session to an ivar.
      //[self setSession:session];  //not sure why need this, can't find code that works for it
  }
  
  - (void)captureOutput:(AVCaptureOutput *)captureOutput
  didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer
         fromConnection:(AVCaptureConnection *)connection
  {
      NSLog(@"captureOutput: didOutputSampleBufferFromConnection");
  
      // Create a UIImage from the sample buffer data
      UIImage *image = [self imageFromSampleBuffer:sampleBuffer];
      dispatch_async(dispatch_get_main_queue(), ^{
          //&lt; Add your code here that uses the image &gt;
          [self.imageView setImage:image];
          [self.view setNeedsDisplay];}
          );
  }
  
  // Create a UIImage from sample buffer data
  - (UIImage *) imageFromSampleBuffer:(CMSampleBufferRef) sampleBuffer
  {
      // Get a CMSampleBuffer's Core Video image buffer for the media data
      CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
      // Lock the base address of the pixel buffer
      CVPixelBufferLockBaseAddress(imageBuffer, 0);
  
      // Get the number of bytes per row for the pixel buffer
      void *baseAddress = CVPixelBufferGetBaseAddress(imageBuffer);
  
      // Get the number of bytes per row for the pixel buffer
      size_t bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer);
      // Get the pixel buffer width and height
      size_t width = CVPixelBufferGetWidth(imageBuffer);
      size_t height = CVPixelBufferGetHeight(imageBuffer);
  
      // Create a device-dependent RGB color space
      CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
  
      // Create a bitmap graphics context with the sample buffer data
      CGContextRef context = CGBitmapContextCreate(baseAddress, width, height, 8,
                                                                  bytesPerRow, colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
      // Create a Quartz image from the pixel data in the bitmap graphics context
      CGImageRef quartzImage = CGBitmapContextCreateImage(context);
      // Unlock the pixel buffer
      CVPixelBufferUnlockBaseAddress(imageBuffer,0);
  
      // Free up the context and color space
      CGContextRelease(context);
      CGColorSpaceRelease(colorSpace);
  
      // Create an image object from the Quartz image
      UIImage *image = [UIImage imageWithCGImage:quartzImage];
  
      // Release the Quartz image
      CGImageRelease(quartzImage);
  
      return (image);
  } 
  </code></pre>