示例#1
0
        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);
        }
示例#4
0
        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();
        }
示例#5
0
        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;
                        });
                    }
                });
            }
        }
示例#6
0
        public void ChangeCamera(AVCaptureSession session)
        {
            _videoDeviceInputManager.ConfigureVideoDeviceInput(session);

            var connection = _videoFileOutput?.ConnectionFromMediaType(AVMediaType.Video);

            if (connection?.SupportsVideoStabilization == true)
            {
                connection.PreferredVideoStabilizationMode = AVCaptureVideoStabilizationMode.Auto;
            }
        }
示例#7
0
        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);
            }
        }
示例#9
0
        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;
        }
示例#10
0
        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();
                //});
            });
        }
示例#11
0
        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;
                        //});
                    }
                });
            }
        }
示例#12
0
        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;
						});
					}
				});
			}
		}
示例#14
0
        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 ();
			});
		}
示例#17
0
        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);
        }