I need some help with our CameraView inside our app. We have built a CameraView with Rectangle / Zoom capabilities (in a webView). When integrating this webCameraView in our app, accessing the camera does not work. Seems like we do have 2 options:
Make the app allow camera access from a webView (is this still not possible 2021?)
Build a copy of the webCameraView directly in the app with rectangle frame instead
Above is what the webCameraView looks like in the app. Rectangle / Zoom is displayed, but the app does not get access to the camera.
If it is not possible to access camera directly in the app via a webView I need to go for alternative nr 2.
I will try to build the same UI via Objc in the app directly. But good updated tutorials for Objc is hard to find or being outdated. All Swift boys have taken over the town! This what I have done so far:
- (void) viewDidLoad {
//-- Setup Capture Session.
_captureSession = [[AVCaptureSession alloc] init];
//-- Creata a video device and input from that Device. Add the input to the capture session.
AVCaptureDevice * videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if(videoDevice == nil)
assert(0);
//-- Add the device to the session.
NSError *error;
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice
error:&error];
if(error)
assert(0);
[_captureSession addInput:input];
//-- Configure the preview layer
_previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:_captureSession];
_previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[_previewLayer setFrame:CGRectMake(0, 0,
self.view.frame.size.width,
self.view.frame.size.height)];
//-- Add the layer to the view that should display the camera input
[self.view.layer addSublayer:_previewLayer];
//-- Start the camera
[_captureSession startRunning];
[super viewDidLoad];
}
The code above gives me access to the camera
How do I create a dragable Rectangle / Zoom area in the middle of the screen via Objc?
Also With capabilities to take a photo (and the photo taken should only represent the inside-area of the rectangle-area) ?
Help!
The sample code you provided is for native camera control, I wonder what it has to do with webview camera?
If you want to turn on the system camera in webview and process the acquired content, you can try to look at webrtc. This has version restrictions, but it is open in WKWebView after iOS 14.3.
Related
I am using core WebRTC framework and rendering my local stream in IPhone full screen mode. Unfortunately, my video shows stretched, doesn't show like video view in camera app.
I tried to add aspect ratio in RTCMediaConstraints and also used adaptOutputFormatToWidth method to fix the output.
NSDictionary* mandatoryConstraints;
/* want to calculate aspect ratio dynamically */
NSString *aspectRatio = [NSString stringWithFormat:#"%f",(double)4/3];
if (aspectRatio) {
mandatoryConstraints = #{ kRTCMediaConstraintsMaxAspectRatio:
aspectRatio};
}
RTCMediaConstraints *cameraConstraints = [RTCMediaConstraints alloc];
cameraConstraints = [cameraConstraints initWithMandatoryConstraints:mandatoryConstraints optionalConstraints:nil];
RTCAVFoundationVideoSource *localVideoSource = [peerFactory avFoundationVideoSourceWithConstraints:mediaConstraint];
[localVideoSource adaptOutputFormatToWidth:devicewidth:devicewidth fps:30];
In below link, the difference between camera video view and my app call video view is shown
https://drive.google.com/file/d/1HN3KQcJphtC3VzJjlI4Hm-D3u2E6qmdQ/view?usp=sharing
I believe you are rendering your video in RTCEAGLVideoView, which require adjustment for size, you can use RTCMTLVideoView in place of RTCEAGLVideoView.
and if you want to use RTCEAGLVideoView, use RTCEAGLVideoViewDelegate method.
- (void)videoView:(RTCEAGLVideoView *)videoView didChangeVideoSize:(CGSize)size;
this method will give you correct size of the video.
(For Swift) -> Use RTCMTLVideoView and set videoContentMode
#if arch(arm64)
let renderer = RTCMTLVideoView(frame: videoView.frame)
renderer.videoContentMode = .scaleAspectFill
#else
let renderer = RTCEAGLVideoView(frame: videoView.frame)
#endif
I would like to use the ZXing iOS framework to bring barcode scanning to my iOS application.
After downloading the Github project (https://github.com/TheLevelUp/ZXingObjC) I played around with the iOS demo project.
In the demo project the phone camera is fullscreen - for my needs I would like to adjust the size of the camera.
ZXing is using the class 'ZXCapture' for doing live barcode scanning.
The demo app has the following viewDidLoad function:
- (void)viewDidLoad {
[super viewDidLoad];
self.capture = [[ZXCapture alloc] init];
self.capture.camera = self.capture.back;
self.capture.focusMode = AVCaptureFocusModeContinuousAutoFocus;
// here I tried to change the size of the camera
self.capture.layer.frame = CGRectMake(0, 0, 200, 200);
[self.view.layer addSublayer:self.capture.layer];
[self.view bringSubviewToFront:self.scanRectView];
[self.view bringSubviewToFront:self.decodedLabel];
}
As you can see, I added a line of code to change the size of the capture frame.
Without success... (I also tried to add the capture layer to a custom sized UIView - also without success - the camera still has a fixed size)
Has anybody ever had the same problem or use case with ZXing for iOS?
Or dose anybody has an idea to do what I want?
I am trying to create a custom camera experience on iOS and the following code snippet is as far as I got. Basically I want the usual camera view (i.e. with the following buttons: capture, flash, grid, front/back, cancel). But the only difference between the normal camera and mine is that I want a square for the preview surface; not a rectangle. And then, what you see is what you get (WYSIWYG) such that there is no cropping necessary; as the user would have taken a square picture in the first place.
I have also been looking at the library https://github.com/danielebogo/DBCamera but I am not seeing how to customize it to my end. Any help? Thanks.
MY CODE SO FAR:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//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) };
//Preview Layer
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:session];
UIView *myView = self.view;
previewLayer.frame = myView.bounds;
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
[self.view.layer addSublayer:previewLayer];
//Start capture session
[session startRunning];
}
This is the only custom code in a single view project on Xcode
You have two options for doing what you want, either stick with and customize a UIImagePickerController, or create your own by using the AVFoundation.
The UIImagePickerController does provide a fair bit of customization options, and this similar thread has some good information on that: link.
If you still want to make your own, I suggest heading over to the Apple Documentation and checking out this demo project called AVCam: link. However, it's way more in-depth than you'll probably need so I can recommend this video tutorial as well: link.
If going for the last option, I would like to mention that to make the "actual camera" fit the frame of your previewLayer, you can set the videoGravity on the AVCaptureVideoPreviewLayer to AVLayerVideoGravityResizeAspectFill.
Working with a custom camera can be a bit of a pain, but it’ll pay dividends given that you’ll really be able to customize your app experience.
The easiest way to do it is to use TGCameraViewController.
Using this TGCameraViewController, you can edit whole camera view. Also, It provides following functionalities:-
Easy way to access album (camera roll)
Flash auto, off and on
Focus
Front and back camera
Also you can refer AVCamManual: Extending AVCam to Use Manual Capture document for creating own custom camera.
I'm a n00b to AVCaptureSession. I'm using OpenTok to implement video chat. I want to preserve bandwidth and the UI is designed so the video views are only 100 x 100 presently.
This is part of the code from an OpenTok example where it sets the preset:
- (void) setCaptureSessionPreset:(NSString*)preset {
AVCaptureSession *session = [self captureSession];
if ([session canSetSessionPreset:preset] &&
![preset isEqualToString:session.sessionPreset]) {
[_captureSession beginConfiguration];
_captureSession.sessionPreset = preset;
_capturePreset = preset;
[_videoOutput setVideoSettings:
[NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithInt:
kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange],
kCVPixelBufferPixelFormatTypeKey,
nil]];
[_captureSession commitConfiguration];
}
}
When I pass in AVCaptureSessionPresetLow (on an iPhone 6) I get NO. Is there any way I can set AVCaptureSession so I can only capture video with a frame as close to 100 x 100 as possible?
Also, is this the correct strategy for trying to save bandwidth?
You cannot force the camera to a resolution it does not support.
A lower resolution frame size will lead to lower network traffic.
Lowering FPS is one other way.
A view size does not have to map to a resolution. You can always fit a frame in any size view.
Look at the Let-Build-OTPublisher app in OpenTok SDK and more specifically TBExampleVideoCapture.m file, on how resolution and FPS are handled.
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.