private void ConfigureSession() { if (_setupResult != SessionSetupResult.Success) { return; } Console.WriteLine("capture session: configuring - adding video input"); Session.BeginConfiguration(); switch (PresetConfiguration) { case SessionPresetConfiguration.Photos: case SessionPresetConfiguration.LivePhotos: _setupResult = PhotoCaptureSession.ConfigureSession(Session, PresetConfiguration); break; case SessionPresetConfiguration.Videos: Session.SessionPreset = AVCaptureSession.PresetHigh; _setupResult = VideoCaptureSession.ConfigureSession(Session); break; default: throw new ArgumentOutOfRangeException(); } if (_setupResult != SessionSetupResult.Success) { Console.WriteLine("Cannot configure session"); return; } Session.CommitConfiguration(); }
public override void ViewDidLoad() { base.ViewDidLoad(); // Disable UI. The UI is enabled if and only if the session starts running. // Add the open barcode gesture recognizer to the region of interest view. // Set up the video preview view. this.PreviewView.Session = session; // Check video authorization status. Video access is required and audio // access is optional. If audio access is denied, audio is not recorded // during movie recording. switch (AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video)) { case AVAuthorizationStatus.Authorized: // The user has previously granted access to the camera. break; case AVAuthorizationStatus.NotDetermined: // The user has not yet been presented with the option to grant // video access. We suspend the session queue to delay session // setup until the access request has completed. this.sessionQueue.Suspend(); AVCaptureDevice.RequestAccessForMediaType(AVMediaType.Video, (granted) => { if (!granted) { this.setupResult = SessionSetupResult.NotAuthorized; } this.sessionQueue.Resume(); }); break; default: // The user has previously denied access. this.setupResult = SessionSetupResult.NotAuthorized; break; } // Setup the capture session. // In general it is not safe to mutate an AVCaptureSession or any of its // inputs, outputs, or connections from multiple threads at the same time. // // Why not do all of this on the main queue? // Because AVCaptureSession.StartRunning() is a blocking call which can // take a long time. We dispatch session setup to the sessionQueue so // that the main queue isn't blocked, which keeps the UI responsive. this.sessionQueue.DispatchAsync(this.ConfigureSession); UISlider focusSlider = new UISlider(new CGRect(60, this.View.Frame.Location.Y - 60, 200, 20)); // focusSlider.AddTarget(focusSlider, new ObjCRuntime.Selector(AdjustFocusAction), UIControlEvent.ValueChanged); focusSlider.MaxValue = 1; focusSlider.MinValue = 0; this.View.AddSubview(focusSlider); }
public void Prepare(AVCaptureVideoOrientation captureVideoOrientation) { var status = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video); if (status == AVAuthorizationStatus.NotDetermined) { _sessionQueue.Suspend(); AVCaptureDevice.RequestAccessForMediaType(AVAuthorizationMediaType.Video, granted => { if (granted) { DispatchQueue.MainQueue.DispatchAsync(() => { _captureSessionDelegate.CaptureGrantedSession(AVAuthorizationStatus.Authorized); }); } else { _setupResult = SessionSetupResult.NotAuthorized; } _sessionQueue.Resume(); }); } else if (status != AVAuthorizationStatus.Authorized) { _setupResult = SessionSetupResult.NotAuthorized; } _sessionQueue.DispatchAsync(() => { ConfigureSession(); UpdateVideoOrientation(captureVideoOrientation); }); }
public override void ViewDidLoad() { base.ViewDidLoad(); //systemSoundBeep = new SystemSound(NSUrl.FromFilename("Sounds/beep07.mp3")); //systemSoundCaution = new SystemSound(NSUrl.FromFilename("Sounds/beep06.mp3")); //audioPlayer = AVAudioPlayer.FromUrl(NSUrl.FromFilename("Sounds/beep07.mp3")); //audioCautionPlayer = AVAudioPlayer.FromUrl(NSUrl.FromFilename("Sounds/beep06.mp3")); // Perform any additional setup after loading the view, typically from a nib. this.PreviewView.AddGestureRecognizer(this.OpenBarcodeURLGestureRecognizer); // Set up the video preview view. this.PreviewView.Session = session; // Check video authorization status. Video access is required and audio // access is optional. If audio access is denied, audio is not recorded // during movie recording. switch (AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video)) { case AVAuthorizationStatus.Authorized: // The user has previously granted access to the camera. break; case AVAuthorizationStatus.NotDetermined: // The user has not yet been presented with the option to grant // video access. We suspend the session queue to delay session // setup until the access request has completed. this.sessionQueue.Suspend(); AVCaptureDevice.RequestAccessForMediaType(AVMediaType.Video, (granted) => { if (!granted) { this.setupResult = SessionSetupResult.NotAuthorized; } this.sessionQueue.Resume(); }); break; default: // The user has previously denied access. this.setupResult = SessionSetupResult.NotAuthorized; break; } // Setup the capture session. // In general it is not safe to mutate an AVCaptureSession or any of its // inputs, outputs, or connections from multiple threads at the same time. // // Why not do all of this on the main queue? // Because AVCaptureSession.StartRunning() is a blocking call which can // take a long time. We dispatch session setup to the sessionQueue so // that the main queue isn't blocked, which keeps the UI responsive. this.sessionQueue.DispatchAsync(this.ConfigureSession); }
public override void ViewDidLoad() { base.ViewDidLoad(); // Disable UI. The UI is enabled if and only if the session starts running. this.MetadataObjectTypesButton.Enabled = false; this.SessionPresetsButton.Enabled = false; this.CameraButton.Enabled = false; this.ZoomSlider.Enabled = false; // Add the open barcode gesture recognizer to the region of interest view. this.PreviewView.AddGestureRecognizer(this.OpenBarcodeURLGestureRecognizer); // Set up the video preview view. this.PreviewView.Session = session; // Check video authorization status. Video access is required and audio // access is optional. If audio access is denied, audio is not recorded // during movie recording. switch (AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video)) { case AVAuthorizationStatus.Authorized: // The user has previously granted access to the camera. break; case AVAuthorizationStatus.NotDetermined: // The user has not yet been presented with the option to grant // video access. We suspend the session queue to delay session // setup until the access request has completed. this.sessionQueue.Suspend(); AVCaptureDevice.RequestAccessForMediaType(AVMediaType.Video, (granted) => { if (!granted) { this.setupResult = SessionSetupResult.NotAuthorized; } this.sessionQueue.Resume(); }); break; default: // The user has previously denied access. this.setupResult = SessionSetupResult.NotAuthorized; break; } // Setup the capture session. // In general it is not safe to mutate an AVCaptureSession or any of its // inputs, outputs, or connections from multiple threads at the same time. // // Why not do all of this on the main queue? // Because AVCaptureSession.StartRunning() is a blocking call which can // take a long time. We dispatch session setup to the sessionQueue so // that the main queue isn't blocked, which keeps the UI responsive. this.sessionQueue.DispatchAsync(this.ConfigureSession); }
void ConfigureSession() { if (setupResult != SessionSetupResult.Success) { return; } session.BeginConfiguration(); var videoDevice = DeviceWithMediaType(AVMediaType.Video, AVCaptureDevicePosition.Back); NSError err; var vDeviceInput = AVCaptureDeviceInput.FromDevice(videoDevice, out err); if (err != null) { Console.WriteLine($"Could not create video device input: ${err}"); setupResult = SessionSetupResult.ConfigurationFailed; session.CommitConfiguration(); return; } if (session.CanAddInput(vDeviceInput)) { session.AddInput(vDeviceInput); videoDeviceInput = vDeviceInput; } else { Console.WriteLine("Could not add video device input to the session"); setupResult = SessionSetupResult.ConfigurationFailed; session.CommitConfiguration(); return; } // Add metadata output. if (session.CanAddOutput(metadataOutput)) { session.AddOutput(metadataOutput); // Set this view controller as the delegate for metadata objects. metadataOutput.SetDelegate(this, metadataObjectsQueue); metadataOutput.MetadataObjectTypes = metadataOutput.AvailableMetadataObjectTypes; // Use all metadata object types by default. metadataOutput.RectOfInterest = CGRect.Empty; } else { Console.WriteLine("Could not add metadata output to the session"); setupResult = SessionSetupResult.ConfigurationFailed; session.CommitConfiguration(); return; } session.CommitConfiguration(); }
private void ConfigureSession() { if (setupResult == SessionSetupResult.Success) { this.session.BeginConfiguration(); // Add video input // Choose the back wide angle camera if available, otherwise default to the front wide angle camera AVCaptureDevice defaultVideoDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Front) ?? null; if (defaultVideoDevice == null) { Console.WriteLine("Could not get video device"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } //set the focus mode to AutoFocus if (defaultVideoDevice.IsFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus)) { NSError errorConfig; defaultVideoDevice.LockForConfiguration(out errorConfig); defaultVideoDevice.FocusMode = AVCaptureFocusMode.ContinuousAutoFocus; defaultVideoDevice.UnlockForConfiguration(); } if (defaultVideoDevice.AutoFocusRangeRestrictionSupported) { NSError errorConfig; defaultVideoDevice.LockForConfiguration(out errorConfig); defaultVideoDevice.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near; defaultVideoDevice.UnlockForConfiguration(); } //end focus mode setting NSError error; var videoDeviceInput = AVCaptureDeviceInput.FromDevice(defaultVideoDevice, out error); if (this.session.CanAddInput(videoDeviceInput)) { this.videoDeviceInput = videoDeviceInput; this.session.AddInput(videoDeviceInput); DispatchQueue.MainQueue.DispatchAsync(() => { // Why are we dispatching this to the main queue? // Because AVCaptureVideoPreviewLayer is the backing layer for PreviewView and UIView // can only be manipulated on the main thread // Note: As an exception to the above rule, it's not necessary to serialize video orientation changed // on the AVCaptureVideoPreviewLayer's connection with other session manipulation // // Use the status bar orientation as the internal video orientation. Subsequent orientation changes are // handled by CameraViewController.ViewWillTransition(to:with:). var initialVideoOrientation = AVCaptureVideoOrientation.Portrait; var statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; if (statusBarOrientation != UIInterfaceOrientation.Unknown) { AVCaptureVideoOrientation videoOrintation; if (Enum.TryParse(statusBarOrientation.ToString(), out videoOrintation)) { initialVideoOrientation = videoOrintation; } } this.PreviewView.VideoPreviewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else if (error != null) { Console.WriteLine($"Could not create video device input: {error}"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } else { Console.WriteLine("Could not add video device input to the session"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } if (this.session.CanAddOutput(videoOutput)) { this.session.AddOutput(videoOutput); frameExtractor.update = ResetResult; videoOutput.SetSampleBufferDelegateQueue(frameExtractor, sampleBufferQueue); videoOutput.WeakVideoSettings = new NSDictionary <NSString, NSObject>(CVPixelBuffer.PixelFormatTypeKey, NSNumber.FromInt32((int)CVPixelFormatType.CV32BGRA)); DispatchQueue.MainQueue.DispatchAsync(() => { //var initialRegionOfInterest = this.PreviewView.VideoPreviewLayer.MapToLayerCoordinates(initialRectOfInterest); }); } else { Console.WriteLine("Could not add metadata output to the session"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } this.session.CommitConfiguration(); } }
private void ConfigureSession() { if (setupResult == SessionSetupResult.Success) { this.session.BeginConfiguration(); // Add video input // Choose the back wide angle camera if available, otherwise default to the front wide angle camera defaultVideoDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Front) ?? null; if (defaultVideoDevice == null) { Console.WriteLine("Could not get video device"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } NSError error; var videoDeviceInput = AVCaptureDeviceInput.FromDevice(defaultVideoDevice, out error); if (this.session.CanAddInput(videoDeviceInput)) { this.session.AddInput(videoDeviceInput); this.videoDeviceInput = videoDeviceInput; if (this.videoDeviceInput.Device.LockForConfiguration(out error)) { if (this.videoDeviceInput.Device.IsFocusModeSupported(AVCaptureFocusMode.ContinuousAutoFocus)) { this.videoDeviceInput.Device.FocusMode = AVCaptureFocusMode.ContinuousAutoFocus; } if (this.videoDeviceInput.Device.AutoFocusRangeRestrictionSupported) { this.videoDeviceInput.Device.AutoFocusRangeRestriction = AVCaptureAutoFocusRangeRestriction.Near; //Near는 바코드 스캔용 } if (this.videoDeviceInput.Device.IsExposureModeSupported(AVCaptureExposureMode.ContinuousAutoExposure)) { this.videoDeviceInput.Device.ExposureMode = AVCaptureExposureMode.ContinuousAutoExposure; } //Console.WriteLine(this.videoDeviceInput.Device.ExposureMode.ToString()); this.videoDeviceInput.Device.UnlockForConfiguration(); } this.session.SessionPreset = AVCaptureSession.Preset1920x1080; //this.session.SessionPreset = AVCaptureSession.Preset1280x720; DispatchQueue.MainQueue.DispatchAsync(() => { // Why are we dispatching this to the main queue? // Because AVCaptureVideoPreviewLayer is the backing layer for PreviewView and UIView // can only be manipulated on the main thread // Note: As an exception to the above rule, it's not necessary to serialize video orientation changed // on the AVCaptureVideoPreviewLayer's connection with other session manipulation // // Use the status bar orientation as the internal video orientation. Subsequent orientation changes are // handled by CameraViewController.ViewWillTransition(to:with:). var initialVideoOrientation = AVCaptureVideoOrientation.Portrait; var statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; if (statusBarOrientation != UIInterfaceOrientation.Unknown) { AVCaptureVideoOrientation videoOrintation; if (Enum.TryParse(statusBarOrientation.ToString(), out videoOrintation)) { initialVideoOrientation = videoOrintation; } } this.PreviewView.VideoPreviewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else if (error != null) { Console.WriteLine($"Could not create video device input: {error}"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } else { Console.WriteLine("Could not add video device input to the session"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } // Add metadata output if (this.session.CanAddOutput(metadataOutput)) { this.session.AddOutput(metadataOutput); // Set this view controller as the delegate for metadata objects this.metadataOutput.SetDelegate(this, this.metadataObjectsQueue); AVMetadataObjectType supportBarcodeFormat = AVMetadataObjectType.None; //hm.ji, 지원하는 바코드 지정, Defualt로 모든바코드 // this.metadataOutput.MetadataObjectTypes = this.metadataOutput.AvailableMetadataObjectTypes; // Use all metadata object types by default string jsonList = Xamarin.Forms.Application.Current.Properties["SupportBarcodeFormat"].ToString(); List <Helpers.BarcodeFormat> tmpList = JsonConvert.DeserializeObject <List <Helpers.BarcodeFormat> >(jsonList); supportBarcodeFormat = ConvertToIOS(tmpList); this.metadataOutput.MetadataObjectTypes = supportBarcodeFormat; //this.metadataOutput.MetadataObjectTypes = AVMetadataObjectType.AztecCode | // AVMetadataObjectType.Code128Code | // AVMetadataObjectType.Code39Code | // AVMetadataObjectType.Code39Mod43Code | // AVMetadataObjectType.Code93Code | // AVMetadataObjectType.EAN13Code | // AVMetadataObjectType.EAN8Code | // AVMetadataObjectType.PDF417Code | // AVMetadataObjectType.QRCode | // AVMetadataObjectType.UPCECode | // AVMetadataObjectType.Interleaved2of5Code | // AVMetadataObjectType.ITF14Code | // AVMetadataObjectType.DataMatrixCode; // Set an initial rect of interest that is 80% of the views's shortest side // and 25% of the longest side. This means that the region on interest will // appear in the same spot regardless of whether the app starts in portrait // or landscape //var width = 0.7; //높이 기본값 : 0.25, 전체 사용하려면 1 //var height = 0.9; //넓이, 초기 값은 0.8 //var x = (1 - width) / 2; //var y = (1 - height) / 2; //var initialRectOfInterest = new CGRect(x + 0.01, y, width, height); CGRect initialRectOfInterest; if (Settings.ScanMode.Equals("FULL")) { var width = 1.0; //높이 기본값 : 0.25, 전체 사용하려면 1 var height = 1.0; //넓이, 초기 값은 0.8 var x = (1 - width) / 2; var y = (1 - height) / 2; initialRectOfInterest = new CGRect(x, y, width, height); } else if (Settings.ScanMode.Equals("WIDE")) { var width = 0.25; //높이 기본값 : 0.25, 전체 사용하려면 1 var height = 0.9; //넓이, 초기 값은 0.8 var x = (1 - width) / 2; var y = (1 - height) / 2; initialRectOfInterest = new CGRect(x, y, width, height); } else if (Settings.ScanMode.Equals("SPLIT")) { var width = 0.15; var height = 1.0; var x = (1 - width) / 2; var y = (1 - height) / 2; initialRectOfInterest = new CGRect(0.09, 0, width, height); } else { var width = 0.15; var height = 1.0; var x = (1 - width) / 2; var y = (1 - height) / 2; initialRectOfInterest = new CGRect(0.09, 0, width, height); } this.metadataOutput.RectOfInterest = initialRectOfInterest; DispatchQueue.MainQueue.DispatchAsync(() => { var initialRegionOfInterest = this.PreviewView.VideoPreviewLayer.MapToLayerCoordinates(initialRectOfInterest); this.PreviewView.SetRegionOfInterestWithProposedRegionOfInterest(initialRegionOfInterest); }); } else { Console.WriteLine("Could not add metadata output to the session"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } this.session.CommitConfiguration(); } }
private void ConfigureSession() { if (setupResult == SessionSetupResult.Success) { this.session.BeginConfiguration(); // Add video input // Choose the back wide angle camera if available, otherwise default to the front wide angle camera AVCaptureDevice defaultVideoDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Front) ?? null; if (defaultVideoDevice == null) { Console.WriteLine("Could not get video device"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } NSError error; var videoDeviceInput = AVCaptureDeviceInput.FromDevice(defaultVideoDevice, out error); if (this.session.CanAddInput(videoDeviceInput)) { this.session.AddInput(videoDeviceInput); this.videoDeviceInput = videoDeviceInput; DispatchQueue.MainQueue.DispatchAsync(() => { // Why are we dispatching this to the main queue? // Because AVCaptureVideoPreviewLayer is the backing layer for PreviewView and UIView // can only be manipulated on the main thread // Note: As an exception to the above rule, it's not necessary to serialize video orientation changed // on the AVCaptureVideoPreviewLayer's connection with other session manipulation // // Use the status bar orientation as the internal video orientation. Subsequent orientation changes are // handled by CameraViewController.ViewWillTransition(to:with:). var initialVideoOrientation = AVCaptureVideoOrientation.Portrait; var statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; if (statusBarOrientation != UIInterfaceOrientation.Unknown) { AVCaptureVideoOrientation videoOrintation; if (Enum.TryParse(statusBarOrientation.ToString(), out videoOrintation)) { initialVideoOrientation = videoOrintation; } } this.PreviewView.VideoPreviewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else if (error != null) { Console.WriteLine($"Could not create video device input: {error}"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } else { Console.WriteLine("Could not add video device input to the session"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } // Add metadata output if (this.session.CanAddOutput(metadataOutput)) { this.session.AddOutput(metadataOutput); // Set this view controller as the delegate for metadata objects this.metadataOutput.SetDelegate(this, this.metadataObjectsQueue); this.metadataOutput.MetadataObjectTypes = this.metadataOutput.AvailableMetadataObjectTypes; // Use all metadata object types by default // Set an initial rect of interest that is 80% of the views's shortest side // and 25% of the longest side. This means that the region on interest will // appear in the same spot regardless of whether the app starts in portrait // or landscape var width = 0.25; var height = 0.8; var x = (1 - width) / 2; var y = (1 - height) / 2; var initialRectOfInterest = new CGRect(x, y, width, height); this.metadataOutput.RectOfInterest = initialRectOfInterest; DispatchQueue.MainQueue.DispatchAsync(() => { var initialRegionOfInterest = this.PreviewView.VideoPreviewLayer.MapToLayerCoordinates(initialRectOfInterest); this.PreviewView.SetRegionOfInterestWithProposedRegionOfInterest(initialRegionOfInterest); }); } else { Console.WriteLine("Could not add metadata output to the session"); this.setupResult = SessionSetupResult.ConfigurationFailed; this.session.CommitConfiguration(); return; } this.session.CommitConfiguration(); } }
public override void ViewDidLoad () { base.ViewDidLoad (); // Disable UI. The UI is enabled if and only if the session starts running. MetadataObjectTypesButton.Enabled = false; SessionPresetsButton.Enabled = false; CameraButton.Enabled = false; ZoomSlider.Enabled = false; // Add the open barcode gesture recognizer to the region of interest view. PreviewView.AddGestureRecognizer (OpenBarcodeURLGestureRecognizer); // Set up the video preview view. PreviewView.Session = session; // Check video authorization status. Video access is required and audio // access is optional. If audio access is denied, audio is not recorded // during movie recording. switch (AVCaptureDevice.GetAuthorizationStatus (AVMediaType.Video)) { case AVAuthorizationStatus.Authorized: // The user has previously granted access to the camera. break; case AVAuthorizationStatus.NotDetermined: // The user has not yet been presented with the option to grant // video access. We suspend the session queue to delay session // setup until the access request has completed. sessionQueue.Suspend (); AVCaptureDevice.RequestAccessForMediaType (AVMediaType.Video, granted => { if (!granted) setupResult = SessionSetupResult.NotAuthorized; sessionQueue.Resume (); }); break; default: // The user has previously denied access. setupResult = SessionSetupResult.NotAuthorized; break; } // Setup the capture session. // In general it is not safe to mutate an AVCaptureSession or any of its // inputs, outputs, or connections from multiple threads at the same time. // Why not do all of this on the main queue? // Because AVCaptureSession.StartRunning() is a blocking call which can // take a long time. We dispatch session setup to the sessionQueue so // that the main queue isn't blocked, which keeps the UI responsive. sessionQueue.DispatchAsync (ConfigureSession); }
void ConfigureSession () { if (setupResult != SessionSetupResult.Success) return; session.BeginConfiguration (); var videoDevice = DeviceWithMediaType (AVMediaType.Video, AVCaptureDevicePosition.Back); NSError err; var vDeviceInput = AVCaptureDeviceInput.FromDevice (videoDevice, out err); if (err != null) { Console.WriteLine ($"Could not create video device input: ${err}"); setupResult = SessionSetupResult.ConfigurationFailed; session.CommitConfiguration (); return; } if (session.CanAddInput (vDeviceInput)) { session.AddInput (vDeviceInput); videoDeviceInput = vDeviceInput; } else { Console.WriteLine ("Could not add video device input to the session"); setupResult = SessionSetupResult.ConfigurationFailed; session.CommitConfiguration (); return; } // Add metadata output. if (session.CanAddOutput (metadataOutput)) { session.AddOutput (metadataOutput); // Set this view controller as the delegate for metadata objects. metadataOutput.SetDelegate (this, metadataObjectsQueue); metadataOutput.MetadataObjectTypes = metadataOutput.AvailableMetadataObjectTypes; // Use all metadata object types by default. metadataOutput.RectOfInterest = CGRect.Empty; } else { Console.WriteLine ("Could not add metadata output to the session"); setupResult = SessionSetupResult.ConfigurationFailed; session.CommitConfiguration (); return; } session.CommitConfiguration (); }