0

I have a View Controller that is using AV Foundation. As soon as the View controller loads, the user is able to see exactly what the input device is seeing. This is because I have started the AVCaptureSession in the viewDidLoad method implementation.

Here is the code that I have in viewDidLoad:

[super viewDidLoad];


AVCaptureSession *session =[[AVCaptureSession alloc]init];


[session setSessionPreset:AVCaptureSessionPresetHigh];


AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];


NSError *error = [[NSError alloc]init];


AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];


if([session canAddInput:deviceInput])
    [session addInput:deviceInput];


AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc]initWithSession:session];



[previewLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];



CALayer *rootLayer = [[self view]layer];


[rootLayer setMasksToBounds:YES];



[previewLayer setFrame:CGRectMake(0, 0, rootLayer.bounds.size.width, rootLayer.bounds.size.height/2)];


[rootLayer insertSublayer:previewLayer atIndex:0];


[session startRunning];

And then I have an IBAction method implementation that has been connected to a UIButton for this view controller. Here is the IBAction implementation's code:

AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc]init];


AVCaptureConnection *connection = [[AVCaptureConnection alloc]init];

[stillImageOutput captureStillImageAsynchronouslyFromConnection:connection completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) {

    NSLog(@"Image Data Captured: %@", imageDataSampleBuffer);
    NSLog(@"Any errors? %@", error);

    if(imageDataSampleBuffer) {


        NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageDataSampleBuffer];


        UIImage *image = [[UIImage alloc]initWithData:imageData];


        NSLog(@"%@", image);


    }

}];

When I run the app on my iPhone and press the button connected to this implementation, I get this error in the console:

*** -[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:] - inactive/invalid connection passed.'

I looked in the xcode docs and it does say "You can only add an AVCaptureConnection instance to a session using addConnection: if canAddConnection: returns YES", but I have tried doing the method call on my AVCaptureSession object for addConnection and canAddConnection but they don't even show up as available options.

I also read somewhere else that for iOS you don't have to manually create a connection, but this doesn't make sense to me because in my IBAction's code there is a method call of: captureStillImageAsynchronouslyFromConnection: which requires an input.

So if the connection is automatically created for you, what is it called so I can use it for the input?

This is my first time working with AV Foundation and I just can't seem to figure out this connection error.

Any help is greatly appreciated.

user3117509
  • 833
  • 3
  • 14
  • 32

2 Answers2

1

When you set up camera, add a stillImageOutput to your AVCaptureSession.

self.stillImageOutput = AVCaptureStillImageOutput()
let stillSettings = [AVVideoCodecJPEG:AVVideoCodecKey]
self.stillImageOutput.outputSettings = stillSettings
if(self.session.canAddOutput(self.stillImageOutput)){
self.session.addOutput(self.stillImageOutput)
}

Then when taking photo, get the AVCaptureSession from stillImageOutput.

func takePhoto(sender: UIButton!){
let connection = self.stillImageOutput.connectionWithMediaType(AVMediaTypeVideo)

if(connection.enabled){
    self.stillImageOutput.captureStillImageAsynchronouslyFromConnection(connection, completionHandler: {(buffer: CMSampleBuffer!, error: NSError!) -> Void in
        println("picture taken")//this never gets executed
    })
}

}

Mark
  • 271
  • 1
  • 9
0

Did you have a property to retain the AVCaptureSession, like

@property (nonatomic, strong) AVCaptureSession *captureSession;
//...
self.captureSession = session;

I hope it helps you.

Xwoder
  • 1