AVFoundation allows to easily spy you? - ios

I recently discovered this: http://openradar.appspot.com/15880263
Correct me if I'm wrong, but those lines allows a Developer to spy the user without the user even noticing, right?
AVCaptureDevice *frontDevice = nil;
for (AVCaptureDevice *device in [AVCaptureDevice devices]) {
if (device.position == AVCaptureDevicePositionFront) {
frontDevice = device;
}
}
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:frontDevice error:nil];
AVCaptureMovieFileOutput *output = [[AVCaptureMovieFileOutput alloc] init];
session = [[AVCaptureSession alloc] init];
[session beginConfiguration];
[session addInput:input];
[session addOutput:output];
[session commitConfiguration];
[session startRunning];
// Wait X seconds
NSString *path = [DOCUMENTS_DIRECTORY stringByAppendingPathComponent:#"output.mov"];
NSURL *url = [NSURL fileURLWithPath:path];
[output startRecordingToOutputFileURL:url recordingDelegate:self];
and boom, I could send that output.mov to my own server, for example. This is terrible, unless I'm missing something.......

Related

How to preview the livephoto

I am doing one application. In that I want to capture the live photo and show it to user for checking. I captured the live photo using below code. I got the output url once capture the live photo and now I want to show that live photo in PHLivePhotoView, how we can do that using output url. And I am getting the live photo data also, see the delegate methods below.
- (void)viewDidLoad {
[super viewDidLoad];
//Capture Session
AVCaptureSession *session = [[AVCaptureSession alloc]init];
session.sessionPreset = AVCaptureSessionPresetPhoto;
//Add device
AVCaptureDevice *device =
[AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
//Input
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
if (!input)
{
NSLog(#"No Input");
}
[session addInput:input];
//Output
// AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
// [session addOutput:output];
// output.videoSettings =
// #{ (NSString *)kCVPixelBufferPixelFormatTypeKey : #(kCVPixelFormatType_32BGRA) };
AVCapturePhotoOutput *output =[[AVCapturePhotoOutput alloc]init];
[session addOutput:output];
output.livePhotoCaptureEnabled = true;
output.highResolutionCaptureEnabled = YES;
//Preview Layer
previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
UIView *myView = self.previewView;
previewLayer.frame = myView.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.previewView.layer addSublayer:previewLayer];
//Start capture session
[session startRunning];
[session commitConfiguration];
captureOutput = [[AVCapturePhotoOutput alloc]init];
captureOutput = output;
// Do any additional setup after loading the view, typically from a nib.
}
- (IBAction)captureImage:(id)sender
{
AVCapturePhotoSettings * settings = [AVCapturePhotoSettings photoSettings];
settings.highResolutionPhotoEnabled = YES;
settings.flashMode = AVCaptureFlashModeOn;
NSString *livePhotoMovieFileName = [NSUUID UUID].UUIDString;
NSString *livePhotoMovieFilePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[livePhotoMovieFileName stringByAppendingPathExtension:#"mov"]];
settings.livePhotoMovieFileURL = [NSURL fileURLWithPath:livePhotoMovieFilePath];
[captureOutput capturePhotoWithSettings:settings delegate:self];
}
- (void)captureOutput:(AVCapturePhotoOutput *)captureOutput didFinishProcessingLivePhotoToMovieFileAtURL:(NSURL *)outputFileURL duration:(CMTime)duration photoDisplayTime:(CMTime)photoDisplayTime resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings error:(nullable NSError *)error
{
NSLog(#"%#",outputFileURL);
}
- (void)captureOutput:(AVCapturePhotoOutput *)captureOutput didFinishProcessingPhotoSampleBuffer:(nullable CMSampleBufferRef)photoSampleBuffer previewPhotoSampleBuffer:(nullable CMSampleBufferRef)previewPhotoSampleBuffer resolvedSettings:(AVCaptureResolvedPhotoSettings *)resolvedSettings bracketSettings:(nullable AVCaptureBracketedStillImageSettings *)bracketSettings error:(nullable NSError *)error
{
photoData = [AVCapturePhotoOutput JPEGPhotoDataRepresentationForJPEGSampleBuffer:photoSampleBuffer previewPhotoSampleBuffer:previewPhotoSampleBuffer];
NSLog(#"%#",photoData);
}
you can use
PHLivePhoto.requestLivePhotoWithResourceFileURLs
or u can use webview too

I am trying to switch this code to use the front camera

I am new to programming, and trying to fix this code to use the front camera instead of defaulting to the back. I'm not sure what I need to change to make this work properly.
Here is my sample code:
-(void)viewWillAppear:(BOOL)animated{
session = [[AVCaptureSession alloc] init];
[session setSessionPreset:AVCaptureSessionPresetPhoto];
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
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];
CGRect frame = self.frameForCapture.frame;
[previewLayer setFrame:frame];
[rootLayer insertSublayer:previewLayer atIndex:0];
stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG, AVVideoCodecKey, nil];
[stillImageOutput setOutputSettings:outputSettings];
[session addOutput:stillImageOutput];
[session startRunning];
Replace this:
AVCaptureDevice *inputDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error;
AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:inputDevice error:&error];
With this:
NSArray *devices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *frontCamera;
for (AVCaptureDevice *dev in devices) {
if (dev.position == AVCaptureDevicePositionFront) {
frontCamera = dev;
break;
}
}
if (!frontCamera) {
NSLog(#"No front camera found!");
// Handle no front camera error
}
NSError *error;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&error];

Rotating AV video preview area on iPad

I'd like to use the video preview layer on the iPhone and the iPad, but on the iPad it doesn't rotate and it has the wrong height.
Here is the code I have:
- (void)capture
{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (!input)
{
NSLog(#"Error: %#", error);
return;
}
[session addInput:input];
//Turn on point autofocus for middle of view
[device lockForConfiguration:&error];
CGPoint point = CGPointMake(0.5,0.5);
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device unlockForConfiguration];
//Add the metadata output device
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
NSLog(#"%lu",output.availableMetadataObjectTypes.count);
for (NSString *s in output.availableMetadataObjectTypes)
NSLog(#"%#",s);
//You should check here to see if the session supports these types, if they aren't support you'll get an exception
output.metadataObjectTypes = #[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeQRCode];
output.rectOfInterest = self.livevideo.bounds;
AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
newCaptureVideoPreviewLayer.frame = self.view.layer.bounds;
newCaptureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.livevideo.layer insertSublayer:newCaptureVideoPreviewLayer above:self.livevideo.layer];
[session startRunning];
}
And:
- (void)captureFront
{
AVCaptureSession *session = [[AVCaptureSession alloc] init];
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
NSError *error = nil;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device
error:&error];
if (!input)
{
NSLog(#"Error: %#", error);
return;
}
[session addInput:input];
//Turn on point autofocus for middle of view
[device lockForConfiguration:&error];
CGPoint point = CGPointMake(0.5,0.5);
[device setFocusPointOfInterest:point];
[device setFocusMode:AVCaptureFocusModeContinuousAutoFocus];
[device unlockForConfiguration];
//Add the metadata output device
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
[session addOutput:output];
NSLog(#"%lu",output.availableMetadataObjectTypes.count);
for (NSString *s in output.availableMetadataObjectTypes)
NSLog(#"%#",s);
//You should check here to see if the session supports these types, if they aren't support you'll get an exception
output.metadataObjectTypes = #[AVMetadataObjectTypeEAN13Code, AVMetadataObjectTypeEAN8Code, AVMetadataObjectTypeUPCECode, AVMetadataObjectTypeQRCode];
output.rectOfInterest = self.livevideo.bounds;
AVCaptureVideoPreviewLayer *newCaptureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
newCaptureVideoPreviewLayer.frame = self.view.layer.bounds;
newCaptureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[session startRunning];
}
Image

AVCaptureMovieFileOutput - no active/enabled connections

I am trying to record video in my iPhone app using AVFoundation.
But whenever I click the Record button app crashes with this message
-[AVCaptureMovieFileOutput startRecordingToOutputFileURL:recordingDelegate:] - no active/enabled
connections.
I know same question asked in SO, but none of its answers helped me.
My problem is the same code works with another application perfectly, and when I try using exactly same code in this app - crashes. But still photo capture is working fine.
Adding my codes here - please help me, Thanks in advance
-(void)viewDidLoad
{
[super viewDidLoad];
self.captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:nil];
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *stillImageOutputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.stillImageOutput setOutputSettings:stillImageOutputSettings];
self.movieOutput = [[AVCaptureMovieFileOutput alloc] init];
[self.captureSession addInput:self.videoInput];
[self.captureSession addOutput:self.stillImageOutput];
previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
UIView *aView = self.view;
previewLayer.frame = CGRectMake(70, 190, 270, 270);
[aView.layer addSublayer:previewLayer];
}
-(NSURL *) tempFileURL
{
NSString *outputPath = [[NSString alloc] initWithFormat:#"%#%#", NSTemporaryDirectory(), #"output.mov"];
NSURL *outputURL = [[NSURL alloc] initFileURLWithPath:outputPath];
NSFileManager *manager = [[NSFileManager alloc] init];
if ([manager fileExistsAtPath:outputPath])
{
[manager removeItemAtPath:outputPath error:nil];
}
return outputURL;
}
-(IBAction)capture:(id)sender
{
if (self.movieOutput.isRecording == YES)
{
[self.movieOutput stopRecording];
}
else
{
[self.movieOutput startRecordingToOutputFileURL:[self tempFileURL] recordingDelegate:self];
}
}
-(void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL
fromConnections:(NSArray *)connections
error:(NSError *)error
{
BOOL recordedSuccessfully = YES;
if ([error code] != noErr)
{
id value = [[error userInfo] objectForKey:AVErrorRecordingSuccessfullyFinishedKey];
if (value)
recordedSuccessfully = [value boolValue];
NSLog(#"A problem occurred while recording: %#", error);
}
if (recordedSuccessfully) {
ALAssetsLibrary *library = [[ALAssetsLibrary alloc] init];
[library writeVideoAtPathToSavedPhotosAlbum:outputFileURL
completionBlock:^(NSURL *assetURL, NSError *error)
{
UIAlertView *alert;
if (!error)
{
alert = [[UIAlertView alloc] initWithTitle:#"Video Saved"
message:#"The movie was successfully saved to you photos library"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
}
else
{
alert = [[UIAlertView alloc] initWithTitle:#"Error Saving Video"
message:#"The movie was not saved to you photos library"
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles:nil, nil];
}
[alert show];
}
];
}
}
I had the same problem while changing videoDevice activeFormat and later wanted to record video. Because I was using best quality video I had to set sessionPreset to high, like following
_session.sessionPreset = AVCaptureSessionPresetHigh;
and it worked for me! :)
Because currently you don't have an active connection to record video to file.
Check connection active status before recording to output file:
AVCaptureConnection *c = [self.movieOutput connectionWithMediaType:AVMediaTypeVideo];
if (c.active) {
//connection is active
} else {
//connection is not active
//try to change self.captureSession.sessionPreset,
//or change videoDevice.activeFormat
}
If connection is not active, try to change captureSession.sessionPreset or videoDevice.activeFormat.
Repeat until you have set a valid format (that means c.active == YES). Then you can record video to output file.
Several things are missing in your code :
You forgot to add movieOutput to your captureSession
Same for your audioInput
All your session configuration needs to be encapsulated by [_captureSession beginConfiguration] and [_captureSession commitConfiguration]
For audio recording you need to set the AVAudioSession to the correct category.
Here is your code updated :
- (void)viewDidLoad
{
[super viewDidLoad];
NSError *error = nil;
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryRecord
error:&error];
if(!error)
{
[[AVAudioSession sharedInstance] setActive:YES error:&error];
if(error) NSLog(#"Error while activating AudioSession : %#", error);
}
else
{
NSLog(#"Error while setting category of AudioSession : %#", error);
}
self.captureSession = [[AVCaptureSession alloc] init];
AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
self.videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:nil];
self.audioInput = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:nil];
self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
NSDictionary *stillImageOutputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:
AVVideoCodecJPEG, AVVideoCodecKey, nil];
[self.stillImageOutput setOutputSettings:stillImageOutputSettings];
self.movieOutput = [[AVCaptureMovieFileOutput alloc] init];
[self.captureSession beginConfiguration];
[self.captureSession addInput:self.videoInput];
[self.captureSession addInput:self.audioInput];
[self.captureSession addOutput:self.movieOutput];
[self.captureSession addOutput:self.stillImageOutput];
[self.captureSession commitConfiguration];
AVCaptureVideoPreviewLayer *previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
previewLayer.frame = CGRectMake(0, 0, 320, 500);
[self.view.layer addSublayer:previewLayer];
[self.captureSession startRunning];
}
- (IBAction)toggleRecording:(id)sender
{
if(!self.movieOutput.isRecording)
{
[self.recordButton setTitle:#"Stop" forState:UIControlStateNormal];
NSString *outputPath = [NSTemporaryDirectory() stringByAppendingPathComponent:#"output.mp4"];
NSFileManager *manager = [[NSFileManager alloc] init];
if ([manager fileExistsAtPath:outputPath])
{
[manager removeItemAtPath:outputPath error:nil];
}
[self.movieOutput startRecordingToOutputFileURL:[NSURL fileURLWithPath:outputPath]
recordingDelegate:self];
}
else
{
[self.recordButton setTitle:#"Start recording" forState:UIControlStateNormal];
[self.movieOutput stopRecording];
}
}
- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error
{
NSLog(#"Did finish recording, error %# | path %# | connections %#", error, [outputFileURL absoluteString], connections);
}
Hope this helps
I find the reason of this error.
check your session's "setSessionPreset" setting,
photo's resolution setting is different from video,
for iPhone5, video resolution of the back camera is 1920*1080, the front camere is 1280*720, and photo's max resolution is 3264*2488,
so if you set error resolution to video, the connect will not be actived.

AVCaptureSession does not record audio on iPad 2

I've been making this app that includes recording a video together with audio. The videorecording works as it should, and on most devices, so does the audo recording.
Except, on an iPad 2 (iOS 6.1.3) the audio recording does not work. In the official "Camera" app, the audio recording works flawlessly, so it's not a device-dependent problem.
This is the code:
NSURL *outputFileURL = [NSURL fileURLWithPath:[NSString stringWithFormat:#"%#%#", NSTemporaryDirectory(), #"output.mov"]];
NSError *error;
AVCaptureDevice *device = [self frontCamera];
AVCaptureDeviceInput *inputVideo = [AVCaptureDeviceInput deviceInputWithDevice:device error:&error];
self.session = [[AVCaptureSession alloc] init];
[self.session beginConfiguration];
if([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset1280x720]){
[self.session setSessionPreset:AVCaptureSessionPreset1280x720];
} else if([device supportsAVCaptureSessionPreset:AVCaptureSessionPresetiFrame960x540]){
[self.session setSessionPreset:AVCaptureSessionPresetiFrame960x540];
} else if([device supportsAVCaptureSessionPreset:AVCaptureSessionPreset640x480]){
[self.session setSessionPreset:AVCaptureSessionPreset640x480];
}
self.recorder = [[AVCamRecorder alloc] initWithSession:self.session outputFileURL:outputFileURL];
[self.recorder setDelegate:self];
AVCaptureDevice *audioDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeAudio];
NSError *audioError;
AVCaptureDeviceInput *inputAudio = [[AVCaptureDeviceInput alloc] initWithDevice:audioDevice error:&audioError];
NSLog(#"AudioError: %#", audioError);
NSLog(#"InputAudio: %#", inputAudio);
[self.session addInput:inputVideo];
[self.session addInput:inputAudio];
[self.session commitConfiguration];
[self.session startRunning];
In the log, "audioError" is null and "inputAudio“ seems to be a valid variable.
Any idea on how to fix this?

Resources