AvCapture Session full screen in iphone 4s - ios

I am developing with AvCapture session to add cutom overlays on camera screen. I have added an AvCaptureVidePreview layer as
AvCaptureVideoPreviewLayer*layer = [[AvCaptureVideoPreviewLayer alloc] iniWithSession:session];
layer.frame = self.view.layer.bounds;
but the camera preview is not full screen in case of iPhone 4S. It works fine in iPhone 5.

CGRect bounds=view.layer.bounds;
layer.videoGravity = AVLayerVideoGravityResizeAspectFill;
layer.bounds=bounds;
layer.position=CGPointMake(CGRectGetMidX(bounds), CGRectGetMidY(bounds));
may be it can help you..

Related

Is Apple using black magic to accomplish camera's preview orientation?

I have this AVFoundation camera app of mine. The camera preview is the result of a filter, applied by didOutputSampleBuffer method.
When I setup the camera I am following what apple did on one of their sample codes (CIFunHouse):
// setting up the camera
CGRect bounds = [self.containerOpenGL bounds];
_eaglContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
_videoPreviewView = [[GLKView alloc] initWithFrame:bounds
context:_eaglContext];
[self.containerOpenGL addSubview:_videoPreviewView];
[self.containerOpenGL sendSubviewToBack:_videoPreviewView];
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
NSDictionary *options = #{kCIContextUseSoftwareRenderer : #(NO),
kCIContextPriorityRequestLow : #(YES),
kCIContextWorkingColorSpace : [NSNull null]};
_ciContext = [CIContext contextWithEAGLContext:_eaglContext options:options];
[_videoPreviewView bindDrawable];
_videoPreviewViewBounds = CGRectZero;
_videoPreviewViewBounds.size.width = _videoPreviewView.drawableWidth;
_videoPreviewViewBounds.size.height = _videoPreviewView.drawableHeight;
dispatch_async(dispatch_get_main_queue(), ^(void) {
CGAffineTransform transform = CGAffineTransformMakeRotation(M_PI);
_videoPreviewView.transform = transform;
_videoPreviewView.frame = bounds;
});
self.containerOpenGL is a full screen view and is constrained to the four corners of the screen. Autorotation is on.
But this is the problem...
When I setup the GLKView and self.ciContext it is created assuming the device is on a particular orientation. If the device is on a particular orientation and I run the application, the previewView will fit the entire self.containerOpenGL area but when I rotate the device the previewView will be out center.
I see that Apple code works perfectly and they don't use any constraints. They do not use any autorotation method, no didLayoutSubviews and when you rotate the device, running their code, everything rotates except the preview view. And worse than that, my previewView appears to rotate but not their's.
Is this black magic? How do I they do that?
They add their preview view to a uiwindow and that is why it does not rotate. I hope this answers the question. If not I will continue to look through their source code.
Quote from source code.
we make our video preview view a subview of the window, and send it to the back; this makes FHViewController's view (and its UI elements) on top of the video preview, and also makes video preview unaffected by device rotation
They also add this
_videoPreviewView.enableSetNeedsDisplay = NO;
This may keep it from responding as well
Edit: It appears that now the preview rotates and the UI does as well so to combat this you can add a second window and send it to the back and make the main window clear and add the previewView to the second window with a dummyViewController that tells it not to autorotate by overriding the appropriate method. This will allow the preview to not rotate but the UI to rotate.

ReplayKit square recording

I was wondering is there any way to force replaykit to record only a part of the screen in square mode? The current API seems to record the whole screen!
ReplayKit records everything on the screen exempt system prompts and dialogs.
You can however overlay another UIWindow on top of your main one and apply a mask to an empty UIView to hide parts of the screen and force a square recording.
The frame ratio of the final recording will still be equal to the screen though.
_overlayWindow = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds]; //Full sized window
_overlayWindow.backgroundColor = [UIColor clearColor];
_overlayWindow.userInteractionEnabled = false;
_overlayWindow.hidden = NO;
UIView *maskedView = [[UIView alloc] initWithFrame:_overlayWindow.bounds];
// Create a mask layer
CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init];
CGRect maskRect = CGRectMake(0, 0, 200, 200);
// Create a path with the rectangle in it.
CGPathRef path = CGPathCreateWithRect(maskRect, NULL);
maskLayer.path = path;
// Set the mask of the view.
maskedView.layer.mask = maskLayer;
[_overlayWindow addSubview:maskedView];
At the moment ReplayKit framework does not provide customisation of Screen Recording in terms of Screen size. So you have to record whole screen of GamePlay.

AVCaptureVideoPreviewLayer frame in Swift

I'm trying to get the video output on my screen in Swift. But the screen stays completely white. I found this tutorial in ObjC and I followed it (only in Swift style syntax).
In there there is a line previewLayer.frame = myView.bounds;
But the field .frame seems to be read only in swift. And I think this might be why I don't see anything on the screen.
How can I set the frame for the previewLayer in Swift?
I see three points in that tutorial where you could end up not displaying the preview, and thus getting a white screen. Below are the Obj-C and Swift counterparts.
1) You might have missed adding the input to the capture session:
// [session addInput:input];
session.addInput(input)
2) You might not have initialized the preview layer's bounds to that of your view controller:
// UIView *myView = self.view;
// previewLayer.frame = myView.bounds;
previewLayer.frame = self.view.bounds
3) You might not have added the preview layer as a sublayer of your view:
// [self.view.layer addSublayer:previewLayer];
self.view.layer.addSublayer(previewLayer)

iPad video in portrait mode

I have made an iPad video in portrait mode i.e. 768*1024. Now when I convert it in mp4 format the converter converts it into 1024*768 i.e landscape mode.Is there any way to show the portrait video in portrait mode or any software to convert the portrait video in mp4 portrait mode?
or I would have to make the video again in landscape mode?
I am using MPMoviePlayerController.
Thanks in advance.
MPMoviePlayerController no longer works in landscape by default so to make it work in landscape you need to apply a transform to the view.
UIView * playerView = [moviePlayerController view];
[playerView setFrame: CGRectMake(0, 0, 480, 320)];//iPhone
CGAffineTransform landscapeTransform;
landscapeTransform = CGAffineTransformMakeRotation(90*M_PI/180.0f);
landscapeTransform = CGAffineTransformTranslate(landscapeTransform, 80, 80);
[playerView setTransform: landscapeTransform];
In addition, if you want the regular full screen controls, use the following sample.
moviePlayerController.fullscreen = TRUE;
moviePlayerController.controlStyle = MPMovieControlStyleFullscreen;
This is for your information "playing a video with MPMoviePlayerController in Portrait WITHOUT Private API-Will get rejected by Apple".Good luck and happy coding :-)

Cropping an AVCaptureSession preview

I'm displaying a video preview of a 320x320 capture window, and using videoGravity to have it fill the square:
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
I'm then grabbing a photo quality image from the session and cropping it, starting at 0, 0. The problem I have is the saved image shows more to the top (but not left) of the frame than the preview. I'd like to basically only see the top of the frame, it seems I'm seeing the middle section, hope I'm explaining myself properly.
Here is the code snippet if it helps:
AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
captureVideoPreviewLayer.frame = _cameraView.bounds;
[_cameraView.layer addSublayer:captureVideoPreviewLayer];
captureVideoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
Thanks in advance for any help.
Cheers.
I couldn't figure out how to do this, so I decided to fix it by changing the cropping region instead of the preview region.

Resources