public Task <OperationResult> StartRecording(string filePath) { TaskCompletionSource <OperationResult> tcs = new TaskCompletionSource <OperationResult>(); if (_movieFileOutput.Recording) { tcs.SetResult(OperationResult.AsFailure("Recording already in progress")); } else { if (UIDevice.CurrentDevice.IsMultitaskingSupported) { // Setup background task. This is needed because the IAVCaptureFileOutputRecordingDelegate.FinishedRecording // callback is not received until AVCam returns to the foreground unless you request background execution time. // This also ensures that there will be time to write the file to the photo library when AVCam is backgrounded. // To conclude this background execution, UIApplication.SharedApplication.EndBackgroundTask is called in // IAVCaptureFileOutputRecordingDelegate.FinishedRecording after the recorded file has been saved. _backgroundRecordingID = UIApplication.SharedApplication.BeginBackgroundTask(null); } // Update the orientation on the movie file output video connection before starting recording. AVCaptureConnection connection = _movieFileOutput.ConnectionFromMediaType(AVMediaType.Video); connection.VideoOrientation = PreviewLayer.Connection.VideoOrientation; // Turn OFF flash for video recording. _videoDeviceInput.Device.SetFlashMode(AVCaptureFlashMode.Off); // Start recording to a temporary file. _movieFileOutput.StartRecordingToOutputFile(new NSUrl(filePath, false), this); tcs.SetResult(OperationResult.AsSuccess()); } return(tcs.Task); }
#pragma warning restore CS4014 private void SetupLiveCameraStream() { captureSession = new AVCaptureSession(); var viewLayer = CameraFeedView.Layer; videoPreviewLayer = new AVCaptureVideoPreviewLayer(captureSession) { Frame = CameraFeedView.Frame, VideoGravity = AVLayerVideoGravity.ResizeAspectFill }; CameraFeedView.Layer.AddSublayer(videoPreviewLayer); AVCaptureDevice captureDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Video); ConfigureCameraForDevice(captureDevice); captureDeviceInput = AVCaptureDeviceInput.FromDevice(captureDevice); captureSession.AddInput(captureDeviceInput); if (isMovie) { // Add audio var audioDevice = AVCaptureDevice.GetDefaultDevice(AVMediaTypes.Audio); var audioDeviceInput = AVCaptureDeviceInput.FromDevice(audioDevice, out NSError audioErr); if (audioErr != null) { Console.WriteLine("Couldn't create audio device input: " + audioErr.LocalizedDescription); } if (captureSession.CanAddInput(audioDeviceInput)) { captureSession.AddInput(audioDeviceInput); } else { Console.WriteLine("Couldn't add audio input to session"); } movieOutput = new AVCaptureMovieFileOutput(); captureSession.AddOutput(movieOutput); captureSession.SessionPreset = AVCaptureSession.Preset1280x720; var connection = movieOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection != null && connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } captureSession.CommitConfiguration(); } else { stillImageOutput = new AVCapturePhotoOutput(); stillImageOutput.IsHighResolutionCaptureEnabled = true; stillImageOutput.IsLivePhotoCaptureEnabled = false; captureSession.AddOutput(stillImageOutput); captureSession.CommitConfiguration(); } ShutterButton.Hidden = false; captureSession.StartRunning(); }
private AVCaptureMovieFileOutput _getMovieOutput() { var shouldReinitializeMovieOutput = movieOutput == null; if (!shouldReinitializeMovieOutput) { var connection = movieOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection != null) { shouldReinitializeMovieOutput = shouldReinitializeMovieOutput || !connection.Active; } } if (shouldReinitializeMovieOutput) { movieOutput = new AVCaptureMovieFileOutput(); movieOutput.MovieFragmentInterval = CMTime.Invalid; captureSession.BeginConfiguration(); captureSession.AddOutput(movieOutput); captureSession.CommitConfiguration(); } return(movieOutput); }
private void SetupLiveCameraStream() { captureSession = new AVCaptureSession(); captureSession.SessionPreset = AVCaptureSession.PresetMedium; videoPreviewLayer = new AVCaptureVideoPreviewLayer(captureSession) { Frame = new CGRect(0f, 0f, View.Bounds.Width, View.Bounds.Height), Orientation = GetCameraForOrientation() }; liveCameraStream.Layer.AddSublayer(videoPreviewLayer); var captureDevice = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video); ConfigureCameraForDevice(captureDevice); captureDeviceInput = AVCaptureDeviceInput.FromDevice(captureDevice); aVCaptureMovieFileOutput = new AVCaptureMovieFileOutput(); var audioDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Audio); var audioDeviceInput = AVCaptureDeviceInput.FromDevice(audioDevice); captureSession.AddOutput(aVCaptureMovieFileOutput); captureSession.AddInput(captureDeviceInput); captureSession.AddInput(audioDeviceInput); aVCaptureMovieFileOutput.ConnectionFromMediaType(AVMediaType.Video).VideoOrientation = GetCameraForOrientation(); captureSession.StartRunning(); }
void ToggleCaptureMode() { if (CaptureModeControl.SelectedSegment == (int)CaptureMode.Photo) { RecordButton.Enabled = false; sessionQueue.DispatchAsync(() => { // Remove the AVCaptureMovieFileOutput from the session because movie recording is // not supported with AVCaptureSessionPresetPhoto. Additionally, Live Photo // capture is not supported when an AVCaptureMovieFileOutput is connected to the session. session.BeginConfiguration(); session.RemoveOutput(MovieFileOutput); session.SessionPreset = AVCaptureSession.PresetPhoto; session.CommitConfiguration(); MovieFileOutput = null; if (photoOutput.IsLivePhotoCaptureSupported) { photoOutput.IsLivePhotoCaptureEnabled = true; DispatchQueue.MainQueue.DispatchAsync(() => { LivePhotoModeButton.Enabled = true; LivePhotoModeButton.Hidden = false; }); } }); } else if (CaptureModeControl.SelectedSegment == (int)CaptureMode.Movie) { LivePhotoModeButton.Hidden = true; sessionQueue.DispatchAsync(() => { var output = new AVCaptureMovieFileOutput(); if (session.CanAddOutput(output)) { session.BeginConfiguration(); session.AddOutput(output); session.SessionPreset = AVCaptureSession.PresetHigh; var connection = output.ConnectionFromMediaType(AVMediaType.Video); if (connection != null) { if (connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } } session.CommitConfiguration(); MovieFileOutput = output; DispatchQueue.MainQueue.DispatchAsync(() => { RecordButton.Enabled = true; }); } }); } }
public void ChangeCamera(AVCaptureSession session) { _videoDeviceInputManager.ConfigureVideoDeviceInput(session); var connection = _videoFileOutput?.ConnectionFromMediaType(AVMediaType.Video); if (connection?.SupportsVideoStabilization == true) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } }
private void ToggleRecording() { if (_videoOutput == null) { return; } _isRecording = !_isRecording; var shotImage = _isRecording ? _videoStopImage : _videoStartImage; ShutterButton.SetImage(shotImage, UIControlState.Normal); if (_isRecording) { var outputPath = Path.Combine(Path.GetTempPath(), "output.mov"); var outputUrl = NSUrl.FromString("file:///" + outputPath); var fileManager = NSFileManager.DefaultManager; if (fileManager.FileExists(outputPath)) { NSError error; fileManager.Remove(outputPath, out error); if (error != null) { Console.WriteLine($"Error removing item at path {outputPath}"); _isRecording = false; return; } } FlipButton.Enabled = false; FlashButton.Enabled = false; var connection = _videoOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection.SupportsVideoOrientation) { connection.VideoOrientation = GetOrientation(); } _videoOutput.StartRecordingToOutputFile(outputUrl, this); } else { _videoOutput.StopRecording(); FlipButton.Enabled = true; FlashButton.Enabled = true; } }
partial void TakePhoto(UIButton sender) { AVCaptureVideoOrientation layerOrientation = videoPreviewLayer.Connection.VideoOrientation; if (isMovie) { ShutterButton.Enabled = false; // disable until recording starts/stops if (!movieOutput.Recording) { // set up recording if (UIDevice.CurrentDevice.IsMultitaskingSupported) { backgroundRecordingId = UIApplication.SharedApplication.BeginBackgroundTask(null); } AVCaptureConnection connection = movieOutput?.ConnectionFromMediaType(AVMediaType.Video); if (connection != null) { connection.VideoOrientation = layerOrientation; } SetPaths(".mov"); movieOutput.StartRecordingToOutputFile(NSUrl.FromFilename(filePath), this); } else { // finish recording movieOutput.StopRecording(); } } else { AVCapturePhotoSettings photoSettings = AVCapturePhotoSettings.Create(); // The first format in the array is the preferred format if (photoSettings.AvailablePreviewPhotoPixelFormatTypes.Length > 0) { photoSettings.PreviewPhotoFormat = new NSDictionary <NSString, NSObject>(CVPixelBuffer.PixelFormatTypeKey, photoSettings.AvailablePreviewPhotoPixelFormatTypes[0]); } stillImageOutput.CapturePhoto(photoSettings, this); } }
protected void Initialize() { // configure the capture session for medium resolution, change this if your code // can cope with more data or volume CaptureSession = new AVCaptureSession { SessionPreset = AVCaptureSession.PresetMedium }; previewLayer = new AVCaptureVideoPreviewLayer(CaptureSession) { Frame = Bounds, VideoGravity = AVLayerVideoGravity.ResizeAspectFill }; var videoDevices = AVCaptureDevice.DevicesWithMediaType(AVMediaType.Video); var cameraPosition = (cameraOptions == CameraOptions.Front) ? AVCaptureDevicePosition.Front : AVCaptureDevicePosition.Back; var device = videoDevices.FirstOrDefault(d => d.Position == cameraPosition); if (device == null) { return; } // SET to slow motion NSError error; var input = new AVCaptureDeviceInput(device, out error); movieFileOutput = new AVCaptureMovieFileOutput { //set max record time to 10 minutes MaxRecordedDuration = CMTime.FromSeconds(600, 1) }; photoFileOutput = new AVCapturePhotoOutput(); photoFileOutput.IsHighResolutionCaptureEnabled = true; if (CaptureSession.CanAddOutput(movieFileOutput)) { CaptureSession.BeginConfiguration(); CaptureSession.AddOutput(movieFileOutput); CaptureSession.AddOutput(photoFileOutput); var ranges = device.ActiveFormat.VideoSupportedFrameRateRanges; if (device.LockForConfiguration(out error)) { device.ActiveVideoMinFrameDuration = new CMTime(1, (int)ranges.First().MinFrameRate); device.ActiveVideoMaxFrameDuration = new CMTime(1, (int)ranges.First().MaxFrameRate); } var connection = movieFileOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection != null) { if (connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } } CaptureSession.CommitConfiguration(); } CaptureSession.AddInput(input); Layer.AddSublayer(previewLayer); CaptureSession.StartRunning(); // set frame rate if Slow-mo is requested if (speedOptions == SpeedOptions.SlowMo) { foreach (var vFormat in device.Formats) { var _ranges = vFormat.VideoSupportedFrameRateRanges as AVFrameRateRange[]; var frameRates = _ranges[0]; if (frameRates.MaxFrameRate >= 240.0) { device.LockForConfiguration(out NSError _error); if (_error is null) { device.ActiveFormat = vFormat as AVCaptureDeviceFormat; device.ActiveVideoMinFrameDuration = frameRates.MinFrameDuration; device.ActiveVideoMaxFrameDuration = frameRates.MaxFrameDuration; device.UnlockForConfiguration(); break; } } } } IsPreviewing = true; }
void ChangeCamera(NSObject sender) { //CameraButton.Enabled = false; //RecordButton.Enabled = false; //PhotoButton.Enabled = false; //LivePhotoModeButton.Enabled = false; //CaptureModeControl.Enabled = false; sessionQueue.DispatchAsync(() => { var currentVideoDevice = videoDeviceInput.Device; var currentPosition = currentVideoDevice.Position; AVCaptureDevicePosition preferredPosition = AVCaptureDevicePosition.Unspecified; AVCaptureDeviceType preferredDeviceType = AVCaptureDeviceType.BuiltInDualCamera; switch (currentPosition) { //case AVCaptureDevicePosition.Unspecified: //preferredPosition = AVCaptureDevicePosition.Back; //preferredDeviceType = AVCaptureDeviceType.BuiltInDualCamera; //break; case AVCaptureDevicePosition.Unspecified: case AVCaptureDevicePosition.Front: preferredPosition = AVCaptureDevicePosition.Back; preferredDeviceType = AVCaptureDeviceType.BuiltInDualCamera; break; case AVCaptureDevicePosition.Back: preferredPosition = AVCaptureDevicePosition.Front; preferredDeviceType = AVCaptureDeviceType.BuiltInWideAngleCamera; break; } var devices = videoDeviceDiscoverySession.Devices; AVCaptureDevice newVideoDevice = null; // First, look for a device with both the preferred position and device type. foreach (var device in devices) { if (device.Position == preferredPosition && device.DeviceType.GetConstant() == preferredDeviceType.GetConstant()) { newVideoDevice = device; break; } } // Otherwise, look for a device with only the preferred position. if (newVideoDevice == null) { foreach (var device in devices) { if (device.Position == preferredPosition) { newVideoDevice = device; break; } } } if (newVideoDevice != null) { var lVideoDeviceInput = AVCaptureDeviceInput.FromDevice(newVideoDevice); session.BeginConfiguration(); // Remove the existing device input first, since using the front and back camera simultaneously is not supported. session.RemoveInput(videoDeviceInput); if (session.CanAddInput(lVideoDeviceInput)) { if (subjectAreaDidChangeObserver != null) { subjectAreaDidChangeObserver.Dispose(); } subjectAreaDidChangeObserver = NSNotificationCenter.DefaultCenter.AddObserver(AVCaptureDevice.SubjectAreaDidChangeNotification, SubjectAreaDidChange, newVideoDevice); session.AddInput(lVideoDeviceInput); videoDeviceInput = lVideoDeviceInput; } else { session.AddInput(videoDeviceInput); } if (movieFileOutput != null) { var movieFileOutputConnection = movieFileOutput.ConnectionFromMediaType(AVMediaType.Video); if (movieFileOutputConnection.SupportsVideoStabilization) { movieFileOutputConnection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } } /* * Set Live Photo capture and depth data delivery if it is supported. When changing cameras, the * `livePhotoCaptureEnabled` and `depthDataDeliveryEnabled` properties of the AVCapturePhotoOutput gets set to NO when * a video device is disconnected from the session. After the new video device is * added to the session, re-enable Live Photo capture and depth data delivery if they are supported. */ photoOutput.IsLivePhotoCaptureEnabled = photoOutput.IsLivePhotoCaptureSupported; //photoOutput.IsDepthDataDeliveryEnabled(photoOutput.IsDepthDataDeliverySupported()); session.CommitConfiguration(); } //DispatchQueue.MainQueue.DispatchAsync(() => //{ // CameraButton.Enabled = true; // RecordButton.Enabled = CaptureModeControl.SelectedSegment == (int)AVCamCaptureMode.Movie; // PhotoButton.Enabled = true; // LivePhotoModeButton.Enabled = true; // CaptureModeControl.Enabled = true; // DepthDataDeliveryButton.Enabled = photoOutput.IsDepthDataDeliveryEnabled(); // DepthDataDeliveryButton.Hidden = !photoOutput.IsDepthDataDeliverySupported(); //}); }); }
void ToggleCaptureMode(UISegmentedControl captureModeControl) { if (captureModeControl.SelectedSegment == (int)AVCamCaptureMode.Photo) { //RecordButton.Enabled = false; sessionQueue.DispatchAsync(() => { /* * Remove the AVCaptureMovieFileOutput from the session because movie recording is * not supported with AVCaptureSessionPresetPhoto. Additionally, Live Photo * capture is not supported when an AVCaptureMovieFileOutput is connected to the session. */ session.BeginConfiguration(); session.RemoveOutput(movieFileOutput); session.SessionPreset = AVCaptureSession.PresetPhoto; session.CommitConfiguration(); movieFileOutput = null; if (photoOutput.IsLivePhotoCaptureSupported) { photoOutput.IsLivePhotoCaptureEnabled = true; //DispatchQueue.MainQueue.DispatchAsync(() => //{ // LivePhotoModeButton.Enabled = true; // LivePhotoModeButton.Hidden = false; //}); } //if (photoOutput.IsDepthDataDeliverySupported()) //{ // photoOutput.IsDepthDataDeliveryEnabled(true); // DispatchQueue.MainQueue.DispatchAsync(() => // { // DepthDataDeliveryButton.Hidden = false; // DepthDataDeliveryButton.Enabled = true; // }); //} }); } else if (captureModeControl.SelectedSegment == (int)AVCamCaptureMode.Movie) { //LivePhotoModeButton.Hidden = true; //DepthDataDeliveryButton.Hidden = true; sessionQueue.DispatchAsync(() => { var lMovieFileOutput = new AVCaptureMovieFileOutput(); if (session.CanAddOutput(lMovieFileOutput)) { session.BeginConfiguration(); session.AddOutput(lMovieFileOutput); session.SessionPreset = AVCaptureSession.PresetHigh; var connection = lMovieFileOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } session.CommitConfiguration(); movieFileOutput = lMovieFileOutput; //DispatchQueue.MainQueue.DispatchAsync(() => //{ // RecordButton.Enabled = true; //}); } }); } }
void ChangeCamera() { CameraButton.Enabled = false; RecordButton.Enabled = false; PhotoButton.Enabled = false; LivePhotoModeButton.Enabled = false; CaptureModeControl.Enabled = false; sessionQueue.DispatchAsync(() => { var currentVideoDevice = videoDeviceInput.Device; var currentPosition = currentVideoDevice.Position; var preferredPosition = AVCaptureDevicePosition.Unspecified; var preferredDeviceType = AVCaptureDeviceType.BuiltInMicrophone; switch (currentPosition) { case AVCaptureDevicePosition.Unspecified: case AVCaptureDevicePosition.Front: preferredPosition = AVCaptureDevicePosition.Back; preferredDeviceType = AVCaptureDeviceType.BuiltInDuoCamera; break; case AVCaptureDevicePosition.Back: preferredPosition = AVCaptureDevicePosition.Front; preferredDeviceType = AVCaptureDeviceType.BuiltInWideAngleCamera; break; } var devices = videoDeviceDiscoverySession.Devices; AVCaptureDevice newVideoDevice = null; // First, look for a device with both the preferred position and device type. Otherwise, look for a device with only the preferred position. newVideoDevice = devices.FirstOrDefault(d => d.Position == preferredPosition && d.DeviceType == preferredDeviceType) ?? devices.FirstOrDefault(d => d.Position == preferredPosition); if (newVideoDevice != null) { NSError error; var input = AVCaptureDeviceInput.FromDevice(newVideoDevice, out error); if (error == null) { session.BeginConfiguration(); // Remove the existing device input first, since using the front and back camera simultaneously is not supported. session.RemoveInput(videoDeviceInput); if (session.CanAddInput(input)) { subjectSubscriber?.Dispose(); subjectSubscriber = NSNotificationCenter.DefaultCenter.AddObserver(AVCaptureDevice.SubjectAreaDidChangeNotification, SubjectAreaDidChange, input.Device); session.AddInput(input); videoDeviceInput = input; } else { session.AddInput(videoDeviceInput); } var connection = MovieFileOutput?.ConnectionFromMediaType(AVMediaType.Video); if (connection != null) { if (connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } } // Set Live Photo capture enabled if it is supported.When changing cameras, the // IsLivePhotoCaptureEnabled property of the AVCapturePhotoOutput gets set to false when // a video device is disconnected from the session.After the new video device is // added to the session, re - enable Live Photo capture on the AVCapturePhotoOutput if it is supported. photoOutput.IsLivePhotoCaptureEnabled = photoOutput.IsLivePhotoCaptureSupported; session.CommitConfiguration(); } } DispatchQueue.MainQueue.DispatchAsync(() => { CameraButton.Enabled = true; RecordButton.Enabled = MovieFileOutput != null; PhotoButton.Enabled = true; LivePhotoModeButton.Enabled = true; CaptureModeControl.Enabled = true; }); }); }
void ToggleCaptureMode (UISegmentedControl captureModeControl) { if (captureModeControl.SelectedSegment == (int)CaptureMode.Photo) { RecordButton.Enabled = false; sessionQueue.DispatchAsync (() => { // Remove the AVCaptureMovieFileOutput from the session because movie recording is // not supported with AVCaptureSessionPresetPhoto. Additionally, Live Photo // capture is not supported when an AVCaptureMovieFileOutput is connected to the session. session.BeginConfiguration (); session.RemoveOutput (MovieFileOutput); session.SessionPreset = AVCaptureSession.PresetPhoto; session.CommitConfiguration (); MovieFileOutput = null; if (photoOutput.IsLivePhotoCaptureSupported) { photoOutput.IsLivePhotoCaptureEnabled = true; DispatchQueue.MainQueue.DispatchAsync (() => { LivePhotoModeButton.Enabled = true; LivePhotoModeButton.Hidden = false; }); } }); } else if (captureModeControl.SelectedSegment == (int)CaptureMode.Movie) { LivePhotoModeButton.Hidden = true; sessionQueue.DispatchAsync (() => { var output = new AVCaptureMovieFileOutput (); if (session.CanAddOutput (output)) { session.BeginConfiguration (); session.AddOutput (output); session.SessionPreset = AVCaptureSession.PresetHigh; var connection = output.ConnectionFromMediaType (AVMediaType.Video); if (connection != null) { if (connection.SupportsVideoStabilization) connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } session.CommitConfiguration (); MovieFileOutput = output; DispatchQueue.MainQueue.DispatchAsync (() => { RecordButton.Enabled = true; }); } }); } }
public async override void ViewDidLoad() { base.ViewDidLoad(); // Disable UI. The UI is enabled if and only if the session starts running. CameraButton.Enabled = false; RecordButton.Enabled = false; StillButton.Enabled = false; // Create the AVCaptureSession. Session = new AVCaptureSession(); // Setup the preview view. PreviewView.Session = Session; // Communicate with the session and other session objects on this queue. SessionQueue = new DispatchQueue("session queue"); SetupResult = AVCamSetupResult.Success; // 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)) { // The user has previously granted access to the camera. case AVAuthorizationStatus.Authorized: break; // 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 to avoid // asking the user for audio access if video access is denied. // Note that audio access will be implicitly requested when we create an AVCaptureDeviceInput for audio during session setup. case AVAuthorizationStatus.NotDetermined: SessionQueue.Suspend(); var granted = await AVCaptureDevice.RequestAccessForMediaTypeAsync(AVMediaType.Video); if (!granted) { SetupResult = AVCamSetupResult.CameraNotAuthorized; } SessionQueue.Resume(); break; // The user has previously denied access. default: SetupResult = AVCamSetupResult.CameraNotAuthorized; 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(() => { if (SetupResult != AVCamSetupResult.Success) { return; } backgroundRecordingID = -1; NSError error; AVCaptureDevice videoDevice = CreateDevice(AVMediaType.Video, AVCaptureDevicePosition.Back); AVCaptureDeviceInput videoDeviceInput = AVCaptureDeviceInput.FromDevice(videoDevice, out error); if (videoDeviceInput == null) { Console.WriteLine("Could not create video device input: {0}", error); } Session.BeginConfiguration(); if (Session.CanAddInput(videoDeviceInput)) { Session.AddInput(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 is not necessary to serialize video orientation changes // on the AVCaptureVideoPreviewLayer’s connection with other session manipulation. // Use the status bar orientation as the initial video orientation. Subsequent orientation changes are handled by // ViewWillTransitionToSize method. UIInterfaceOrientation statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; AVCaptureVideoOrientation initialVideoOrientation = AVCaptureVideoOrientation.Portrait; if (statusBarOrientation != UIInterfaceOrientation.Unknown) { initialVideoOrientation = (AVCaptureVideoOrientation)(long)statusBarOrientation; } var previewLayer = (AVCaptureVideoPreviewLayer)PreviewView.Layer; previewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else { Console.WriteLine("Could not add video device input to the session"); SetupResult = AVCamSetupResult.SessionConfigurationFailed; } AVCaptureDevice audioDevice = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio); AVCaptureDeviceInput audioDeviceInput = AVCaptureDeviceInput.FromDevice(audioDevice, out error); if (audioDeviceInput == null) { Console.WriteLine("Could not create audio device input: {0}", error); } if (Session.CanAddInput(audioDeviceInput)) { Session.AddInput(audioDeviceInput); } else { Console.WriteLine("Could not add audio device input to the session"); } var movieFileOutput = new AVCaptureMovieFileOutput(); if (Session.CanAddOutput(movieFileOutput)) { Session.AddOutput(MovieFileOutput = movieFileOutput); AVCaptureConnection connection = movieFileOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } } else { Console.WriteLine("Could not add movie file output to the session"); SetupResult = AVCamSetupResult.SessionConfigurationFailed; } var stillImageOutput = new AVCaptureStillImageOutput(); if (Session.CanAddOutput(stillImageOutput)) { stillImageOutput.CompressedVideoSetting = new AVVideoSettingsCompressed { Codec = AVVideoCodec.JPEG }; Session.AddOutput(StillImageOutput = stillImageOutput); } else { Console.WriteLine("Could not add still image output to the session"); SetupResult = AVCamSetupResult.SessionConfigurationFailed; } Session.CommitConfiguration(); }); }
void ChangeCaptureMode (UISegmentedControl captureModeControl) { if (captureModeControl.SelectedSegment == (int)CaptureMode.Photo) { RecordButton.Enabled = false; // Remove the AVCaptureMovieFileOutput from the session because movie recording is not supported with AVCaptureSessionPresetPhoto. Additionally, Live Photo // capture is not supported when an AVCaptureMovieFileOutput is connected to the session. sessionQueue.DispatchAsync (() => { Session.BeginConfiguration (); Session.RemoveOutput (movieFileOutput); Session.SessionPreset = AVCaptureSession.PresetPhoto; Session.CommitConfiguration (); movieFileOutput = null; }); } else if (captureModeControl.SelectedSegment == (int)CaptureMode.Movie) { sessionQueue.DispatchAsync (() => { var mfo = new AVCaptureMovieFileOutput (); if (Session.CanAddOutput (mfo)) { Session.BeginConfiguration (); Session.AddOutput (mfo); Session.SessionPreset = AVCaptureSession.PresetHigh; AVCaptureConnection connection = mfo.ConnectionFromMediaType (AVMediaType.Video); if (connection.SupportsVideoStabilization) connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; Session.CommitConfiguration (); movieFileOutput = mfo; DispatchQueue.MainQueue.DispatchAsync (() => { RecordButton.Enabled = true; }); } }); } }
public async override void ViewDidLoad () { base.ViewDidLoad (); // Disable UI. The UI is enabled if and only if the session starts running. CameraButton.Enabled = false; RecordButton.Enabled = false; StillButton.Enabled = false; // Create the AVCaptureSession. Session = new AVCaptureSession (); // Setup the preview view. PreviewView.Session = Session; // Communicate with the session and other session objects on this queue. SessionQueue = new DispatchQueue ("session queue"); SetupResult = AVCamSetupResult.Success; // 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)) { // The user has previously granted access to the camera. case AVAuthorizationStatus.Authorized: break; // 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 to avoid // asking the user for audio access if video access is denied. // Note that audio access will be implicitly requested when we create an AVCaptureDeviceInput for audio during session setup. case AVAuthorizationStatus.NotDetermined: SessionQueue.Suspend (); var granted = await AVCaptureDevice.RequestAccessForMediaTypeAsync (AVMediaType.Video); if (!granted) SetupResult = AVCamSetupResult.CameraNotAuthorized; SessionQueue.Resume (); break; // The user has previously denied access. default: SetupResult = AVCamSetupResult.CameraNotAuthorized; 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 (() => { if (SetupResult != AVCamSetupResult.Success) return; backgroundRecordingID = -1; NSError error; AVCaptureDevice videoDevice = CreateDevice (AVMediaType.Video, AVCaptureDevicePosition.Back); AVCaptureDeviceInput videoDeviceInput = AVCaptureDeviceInput.FromDevice (videoDevice, out error); if (videoDeviceInput == null) Console.WriteLine ("Could not create video device input: {0}", error); Session.BeginConfiguration (); if (Session.CanAddInput (videoDeviceInput)) { Session.AddInput (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 is not necessary to serialize video orientation changes // on the AVCaptureVideoPreviewLayer’s connection with other session manipulation. // Use the status bar orientation as the initial video orientation. Subsequent orientation changes are handled by // ViewWillTransitionToSize method. UIInterfaceOrientation statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; AVCaptureVideoOrientation initialVideoOrientation = AVCaptureVideoOrientation.Portrait; if (statusBarOrientation != UIInterfaceOrientation.Unknown) initialVideoOrientation = (AVCaptureVideoOrientation)(long)statusBarOrientation; var previewLayer = (AVCaptureVideoPreviewLayer)PreviewView.Layer; previewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else { Console.WriteLine ("Could not add video device input to the session"); SetupResult = AVCamSetupResult.SessionConfigurationFailed; } AVCaptureDevice audioDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Audio); AVCaptureDeviceInput audioDeviceInput = AVCaptureDeviceInput.FromDevice (audioDevice, out error); if (audioDeviceInput == null) Console.WriteLine ("Could not create audio device input: {0}", error); if (Session.CanAddInput (audioDeviceInput)) Session.AddInput (audioDeviceInput); else Console.WriteLine ("Could not add audio device input to the session"); var movieFileOutput = new AVCaptureMovieFileOutput (); if (Session.CanAddOutput (movieFileOutput)) { Session.AddOutput (MovieFileOutput = movieFileOutput); AVCaptureConnection connection = movieFileOutput.ConnectionFromMediaType (AVMediaType.Video); if (connection.SupportsVideoStabilization) connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } else { Console.WriteLine ("Could not add movie file output to the session"); SetupResult = AVCamSetupResult.SessionConfigurationFailed; } var stillImageOutput = new AVCaptureStillImageOutput (); if (Session.CanAddOutput (stillImageOutput)) { stillImageOutput.CompressedVideoSetting = new AVVideoSettingsCompressed { Codec = AVVideoCodec.JPEG }; Session.AddOutput (StillImageOutput = stillImageOutput); } else { Console.WriteLine ("Could not add still image output to the session"); SetupResult = AVCamSetupResult.SessionConfigurationFailed; } Session.CommitConfiguration (); }); }
public Task <OperationResult> Setup(bool enableAudioRecording, bool enableStillImageCapture = false, UIInterfaceOrientation orientation = UIInterfaceOrientation.Portrait, int numberOfCameras = 1) { TaskCompletionSource <OperationResult> tcs = new TaskCompletionSource <OperationResult>(); var warnings = new List <string>(); NumberOfCameras = numberOfCameras; _enableAudioRecording = enableAudioRecording; _enableStillImageCapture = enableStillImageCapture; _session = new AVCaptureSession(); _backgroundRecordingID = -1; NSError error; var result = AVCaptureDeviceFactory.CreateDevice(AVMediaType.Video, AVCaptureDevicePosition.Back); if (!result.IsSuccessful) { _setupResult = CameraSetupResult.SessionConfigurationFailed; tcs.SetResult(OperationResult.AsFailure("No video devices found, probably running in the simulator")); return(tcs.Task); } _videoDeviceInput = AVCaptureDeviceInput.FromDevice(result.Result, out error); if (_videoDeviceInput == null) { _setupResult = CameraSetupResult.SessionConfigurationFailed; tcs.SetResult(OperationResult.AsFailure(@"Could not create video device input: {error}")); return(tcs.Task); } _session.BeginConfiguration(); if (_session.CanAddInput(_videoDeviceInput)) { _session.AddInput(_videoDeviceInput); var initialVideoOrientation = (AVCaptureVideoOrientation)(long)orientation; PreviewLayer.Session = _session; PreviewLayer.VideoGravity = AVLayerVideoGravity.ResizeAspectFill; PreviewLayer.Connection.VideoOrientation = initialVideoOrientation; } else { _setupResult = CameraSetupResult.SessionConfigurationFailed; tcs.SetResult(OperationResult.AsFailure("Could not add video device input to the session")); return(tcs.Task); } if (_enableAudioRecording) { AVCaptureDevice audioDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Audio); AVCaptureDeviceInput audioDeviceInput = AVCaptureDeviceInput.FromDevice(audioDevice, out error); if (audioDeviceInput == null) { warnings.Add(@"Could not create audio device input: {error}"); } else { if (_session.CanAddInput(audioDeviceInput)) { _session.AddInput(audioDeviceInput); } else { warnings.Add("Could not add audio device input to the session"); } } } _movieFileOutput = new AVCaptureMovieFileOutput(); if (_session.CanAddOutput(_movieFileOutput)) { _session.AddOutput(_movieFileOutput); AVCaptureConnection connection = _movieFileOutput.ConnectionFromMediaType(AVMediaType.Video); if (connection.SupportsVideoStabilization) { connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto; } } else { warnings.Add("Could not add movie file output to the session"); _setupResult = CameraSetupResult.SessionConfigurationFailed; } if (_enableStillImageCapture) { _stillImageOutput = new AVCaptureStillImageOutput(); if (_session.CanAddOutput(_stillImageOutput)) { _stillImageOutput.CompressedVideoSetting = new AVVideoSettingsCompressed { Codec = AVVideoCodec.JPEG }; _session.AddOutput(_stillImageOutput); } else { warnings.Add("Could not add still image output to the session"); _setupResult = CameraSetupResult.SessionConfigurationFailed; } } _session.CommitConfiguration(); _setupResult = CameraSetupResult.Success; tcs.SetResult(OperationResult.AsSuccess(string.Empty, warnings)); AddObservers(); return(tcs.Task); }