Search code examples
iphoneiosxcodexcode4uiimagepickercontroller

Secretly record a movie using UIImagePickerController


I am making a password app for iPhone 4/4S. When user enters the password 3 times unsuccessfully I would like to make a movie of the user using the iPhone's front facing camera. This is nothing new a lot of apps in the appstore do something similar. Take pic of the guy, get his GEO coordinates etc.

The challenge that I am facing is that when I try to setup a movie recording, the camera overlay takes up the whole screen. What I really want to do is let the user still see the login screen and buttons but secretly record and make a movie of the user. Is there a way I can do this?

This is the code that I am using.

in my *.h file

@interface v1InstantController : UIViewController <UIImagePickerControllerDelegate>
{   
    UIImagePickerController *picpicker;
}

@property (nonatomic, retain) UIImagePickerController *picpicker;

in my *.m file

-(IBAction) makeMovieNow
{
    picpicker = [[UIImagePickerController alloc] init];
        picpicker.delegate = self;


        picpicker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary;
        picpicker.sourceType = UIImagePickerControllerSourceTypeCamera;

        picpicker.showsCameraControls = NO;
        picpicker.navigationBarHidden = YES;
        picpicker.wantsFullScreenLayout = NO;

        picpicker.mediaTypes = [NSArray arrayWithObject:(NSString *)kUTTypeMovie];
        picpicker.cameraCaptureMode = UIImagePickerControllerCameraCaptureModeVideo;

        picpicker.cameraFlashMode = UIImagePickerControllerCameraFlashModeOff;
        picpicker.cameraDevice = UIImagePickerControllerCameraDeviceFront;

        picpicker.videoQuality = UIImagePickerControllerQualityTypeHigh;

        picpicker.mediaTypes = [UIImagePickerController availableMediaTypesForSourceType:UIImagePickerControllerSourceTypeCamera];

        //The problem is right here! 
        //picpicker.cameraViewTransform = CGAffineTransformScale(picpicker.cameraViewTransform, 0.01, 0.01);
        [self presentModalViewController:picpicker animated:YES];

        [picpicker startVideoCapture];
}

The problem is right here "presentModalViewController:picpicker". When I use this it launches the camera screen with Iris splash etc and it shows what's being recorded on the whole screen. Even if I use cameraViewTransform it still disables anything on the page and puts this camera overlay in the middle of the page. (with a really tiny camera overlay) I don't want the user to know that I am recording and want him to think that it business as usual. i.e. let him keep trying to enter passwords unsuccessfully on the page.


Solution

  • Here's the answer for anyone that maybe interested in future. Do rate it up!

    Make sure to include coreVideo and CoreMedia frameworks

    in your *.h file

    @interface v1InstantController : UIViewController <UIImagePickerControllerDelegate,UINavigationControllerDelegate>
    {
        AVCaptureSession *session;
        NSString *videoPath2;
    }
    
    @property (nonatomic, retain) AVCaptureSession *session;
    @property (nonatomic, retain) NSString *videoPath2;
    

    in your *.m file

    @synthesize session;
    @synthesize videoPath2;
    
    -(IBAction) makeMovieNow
    {
    
        NSLog(@"makeMovieNow ..");
    
        //record movie
        session = [[AVCaptureSession alloc] init];
        [session beginConfiguration];
        session.sessionPreset = AVCaptureSessionPresetHigh;
    
        AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
        captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
    
    
        NSError *error = nil;
        AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
        device = [self frontFacingCameraIfAvailable];
        AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
        if (!videoInput) 
        {
            // Handle the error appropriately.
            NSLog(@"ERROR: trying to open camera: %@", error);
        }
    
        AVCaptureDevice *audioDevice     = [AVCaptureDevice defaultDeviceWithMediaType: AVMediaTypeAudio];
        AVCaptureDeviceInput *audioInput = [AVCaptureDeviceInput deviceInputWithDevice:audioDevice error:&error ]; 
    
    
        AVCaptureMovieFileOutput *movieFileOutput = [[AVCaptureMovieFileOutput alloc] init];
    
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectoryPath = [paths objectAtIndex:0];
        NSString *movieFileName = [NSString stringWithFormat: @"Secret.mov"];
        NSString *fullPathToFile2 = [documentsDirectoryPath stringByAppendingPathComponent:movieFileName];
        NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:fullPathToFile2];
    
        videoPath2=[outputURL path];
    
    
        [session addInput:videoInput];
        [session addInput:audioInput];
        [session addOutput:movieFileOutput];
        [session commitConfiguration];
    
        //start recording
        [session startRunning];
        [movieFileOutput startRecordingToOutputFileURL:outputURL recordingDelegate:self];
    }
    
    -(IBAction) makeMovieStop
    {
        NSLog(@"makeMovieStop ...");
    
        //stop recording
        [session stopRunning];
    
        //save video to photo-album
        UISaveVideoAtPathToSavedPhotosAlbum(videoPath2, self, nil, nil);
    
    }