void ToggleLivePhotoMode() { sessionQueue.DispatchAsync(() => { livePhotoMode = (livePhotoMode == LivePhotoMode.On) ? LivePhotoMode.Off : LivePhotoMode.On; var mode = livePhotoMode; DispatchQueue.MainQueue.DispatchAsync(() => { var title = (mode == LivePhotoMode.On) ? "Live Photo Mode: On" : "Live Photo Mode: Off"; LivePhotoModeButton.SetTitle(title, UIControlState.Normal); }); }); }
public void CapturePhoto(LivePhotoMode livePhotoMode, bool saveToPhotoLibrary) { _sessionQueue.DispatchAsync(() => { var photoSettings = AVCapturePhotoSettings.Create(); if (_photoOutput.SupportedFlashModes.Contains(NSNumber.FromInt32((int)AVCaptureFlashMode.Auto))) { photoSettings.FlashMode = AVCaptureFlashMode.Auto; } photoSettings.IsHighResolutionPhotoEnabled = true; var availablePhotoCodecTypes = photoSettings.AvailableEmbeddedThumbnailPhotoCodecTypes; if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0) && availablePhotoCodecTypes.Length > 0) { photoSettings.EmbeddedThumbnailPhotoFormat = new NSMutableDictionary { { AVVideo.CodecKey, availablePhotoCodecTypes[0].GetConstant() } }; } if (livePhotoMode == LivePhotoMode.On) { if (_presetConfiguration == SessionPresetConfiguration.LivePhotos && _photoOutput.IsLivePhotoCaptureSupported) { photoSettings.LivePhotoMovieFileUrl = NSUrl.CreateFileUrl(new[] { Path.GetTempPath(), $"{Guid.NewGuid()}.mov" }); } else { Console.WriteLine( "capture session: warning - trying to capture live photo but it's not supported by current configuration, capturing regular photo instead"); } } // Use a separate object for the photo capture delegate to isolate each capture life cycle. var photoCaptureDelegate = new PhotoCaptureDelegate(photoSettings, () => WillCapturePhotoAnimationAction(photoSettings), CapturingLivePhotoAction, CapturingCompletedAction) { ShouldSavePhotoToLibrary = saveToPhotoLibrary }; _photoOutput.CapturePhoto(photoSettings, photoCaptureDelegate); }); }
void ToggleLivePhotoMode (UIButton livePhotoModeButton) { sessionQueue.DispatchAsync (() => { livePhotoMode = (livePhotoMode == LivePhotoMode.On) ? LivePhotoMode.Off : LivePhotoMode.On; var mode = livePhotoMode; DispatchQueue.MainQueue.DispatchAsync (() => { var title = (mode == LivePhotoMode.On) ? "Live Photo Mode: On" : "Live Photo Mode: Off"; LivePhotoModeButton.SetTitle (title, UIControlState.Normal); }); }); }
void ConfigureSession() { if (setupResult != AVCamSetupResult.Success) { return; } session.BeginConfiguration(); // We do not create an AVCaptureMovieFileOutput when setting up the session because the // AVCaptureMovieFileOutput does not support movie recording with AVCaptureSessionPresetPhoto. session.SessionPreset = AVCaptureSession.PresetPhoto; // Add video input. // Choose the back dual camera if available, otherwise default to a wide angle camera. var defaultVideoDevice = AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInDuoCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice(AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Front); NSError error; var input = AVCaptureDeviceInput.FromDevice(defaultVideoDevice, out error); if (error != null) { Console.WriteLine($"Could not create video device input: {error.LocalizedDescription}"); setupResult = AVCamSetupResult.SessionConfigurationFailed; session.CommitConfiguration(); return; } if (session.CanAddInput(input)) { session.AddInput(input); videoDeviceInput = input; 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. var statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; var initialVideoOrientation = AVCaptureVideoOrientation.Portrait; AVCaptureVideoOrientation videoOrientation; if (statusBarOrientation != UIInterfaceOrientation.Unknown && TryConvertToVideoOrientation(statusBarOrientation, out videoOrientation)) { initialVideoOrientation = videoOrientation; } PreviewView.VideoPreviewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else { Console.WriteLine("Could not add video device input to the session"); setupResult = AVCamSetupResult.SessionConfigurationFailed; session.CommitConfiguration(); return; } // Add audio input. //var audioDevice = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio); var audioDevice = AVCaptureDevice.GetDefaultDevice(AVMediaType.Audio); var audioDeviceInput = AVCaptureDeviceInput.FromDevice(audioDevice, out error); if (error != null) { Console.WriteLine($"Could not create audio device input: {error.LocalizedDescription}"); } if (session.CanAddInput(audioDeviceInput)) { session.AddInput(audioDeviceInput); } else { Console.WriteLine("Could not add audio device input to the session"); } // Add photo output. if (session.CanAddOutput(photoOutput)) { session.AddOutput(photoOutput); photoOutput.IsHighResolutionCaptureEnabled = true; photoOutput.IsLivePhotoCaptureEnabled = photoOutput.IsLivePhotoCaptureSupported; livePhotoMode = photoOutput.IsLivePhotoCaptureSupported ? LivePhotoMode.On : LivePhotoMode.Off; } else { Console.WriteLine("Could not add photo output to the session"); setupResult = AVCamSetupResult.SessionConfigurationFailed; session.CommitConfiguration(); return; } session.CommitConfiguration(); }
void ConfigureSession () { if (setupResult != AVCamSetupResult.Success) return; session.BeginConfiguration (); // We do not create an AVCaptureMovieFileOutput when setting up the session because the // AVCaptureMovieFileOutput does not support movie recording with AVCaptureSessionPresetPhoto. session.SessionPreset = AVCaptureSession.PresetPhoto; // Add video input. // Choose the back dual camera if available, otherwise default to a wide angle camera. AVCaptureDevice defaultVideoDevice = AVCaptureDevice.GetDefaultDevice (AVCaptureDeviceType.BuiltInDuoCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice (AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Back) ?? AVCaptureDevice.GetDefaultDevice (AVCaptureDeviceType.BuiltInWideAngleCamera, AVMediaType.Video, AVCaptureDevicePosition.Front); NSError error; var input = AVCaptureDeviceInput.FromDevice (defaultVideoDevice, out error); if (error != null) { Console.WriteLine ($"Could not create video device input: {error.LocalizedDescription}"); setupResult = AVCamSetupResult.SessionConfigurationFailed; session.CommitConfiguration (); return; } if (session.CanAddInput (input)) { session.AddInput (input); videoDeviceInput = input; 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. var statusBarOrientation = UIApplication.SharedApplication.StatusBarOrientation; var initialVideoOrientation = AVCaptureVideoOrientation.Portrait; AVCaptureVideoOrientation videoOrientation; if (statusBarOrientation != UIInterfaceOrientation.Unknown && TryConvertToVideoOrientation(statusBarOrientation, out videoOrientation)) initialVideoOrientation = videoOrientation; PreviewView.VideoPreviewLayer.Connection.VideoOrientation = initialVideoOrientation; }); } else { Console.WriteLine ("Could not add video device input to the session"); setupResult = AVCamSetupResult.SessionConfigurationFailed; session.CommitConfiguration (); return; } // Add audio input. var audioDevice = AVCaptureDevice.DefaultDeviceWithMediaType (AVMediaType.Audio); var audioDeviceInput = AVCaptureDeviceInput.FromDevice (audioDevice, out error); if (error != null) Console.WriteLine ($"Could not create audio device input: {error.LocalizedDescription}"); if (session.CanAddInput (audioDeviceInput)) session.AddInput (audioDeviceInput); else Console.WriteLine ("Could not add audio device input to the session"); // Add photo output. if (session.CanAddOutput (photoOutput)) { session.AddOutput (photoOutput); photoOutput.IsHighResolutionCaptureEnabled = true; photoOutput.IsLivePhotoCaptureEnabled = photoOutput.IsLivePhotoCaptureSupported; livePhotoMode = photoOutput.IsLivePhotoCaptureSupported ? LivePhotoMode.On : LivePhotoMode.Off; } else { Console.WriteLine ("Could not add photo output to the session"); setupResult = AVCamSetupResult.SessionConfigurationFailed; session.CommitConfiguration (); return; } session.CommitConfiguration (); }