/// <summary>
        /// Shows the preview asynchronously (completes when the camera is initialized)..
        /// </summary>
        /// <returns></returns>
        public async Task <CameraInitializationResult> ShowAsync()
        {
            await this.WaitForLoadedAsync();

            await this.WaitForNonZeroSizeAsync();

            var result = await InitializeAsync();

            if (!result.Success)
            {
                return(result);
            }

            try
            {
                _internalState = CameraCaptureControlStates.Shown;

                if (_captureElement != null)
                {
                    _captureElement.Source = MediaCapture;
                    await MediaCapture.StartPreviewAsync();
                }

                return(result);
            }
            catch (Exception ex)
            {
                return(new CameraInitializationResult(false, "Camera display failed", ex));
            }
        }
Example #2
0
        private async Task StartPreviewAsync()
        {
            _mediaCapture = new MediaCapture();

            if (_currentVideoCaptureDeviceIndex >= 0)
            {
                this.VideoDevice     = _videoCaptureDevices[_currentVideoCaptureDeviceIndex];
                this.VideoDeviceId   = this.VideoDevice.Id;
                this.VideoDeviceName = this.VideoDevice.Name;
                this.VideoDeviceEnclosureLocation = this.VideoDevice.EnclosureLocation;
            }

            if (_currentAudioCaptureDeviceIndex >= 0)
            {
                this.AudioDevice     = _audioCaptureDevices[_currentAudioCaptureDeviceIndex];
                this.AudioDeviceId   = this.AudioDevice.Id;
                this.AudioDeviceName = this.AudioDevice.Name;
            }

            if (CheckStreamingCaptureModeConfiguration())
            {
                return;
            }

            var settings = new MediaCaptureInitializationSettings
            {
                StreamingCaptureMode = this.StreamingCaptureMode,
                PhotoCaptureSource   = PhotoCaptureSource.Auto //TODO: Figure out if this is worth exposing
            };

            if (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo)
            {
                settings.VideoDeviceId = this.VideoDeviceId;
                settings.AudioDeviceId = this.AudioDeviceId;
            }
            else if (this.StreamingCaptureMode == StreamingCaptureMode.Video)
            {
                settings.VideoDeviceId = this.VideoDeviceId;
            }
            else if (this.StreamingCaptureMode == StreamingCaptureMode.Audio)
            {
                settings.AudioDeviceId = this.AudioDeviceId;
            }

            await _mediaCapture.InitializeAsync(settings);

            _captureElement.Source = _mediaCapture;
            await _mediaCapture.StartPreviewAsync();

            _internalState = CameraCaptureControlStates.Shown;
        }
Example #3
0
        public async Task HideAsync()
        {
            _internalState = CameraCaptureControlStates.Deinitializing;

            if (_mediaCapture != null)
            {
                await _mediaCapture.StopPreviewAsync();

                _mediaCapture = null;
            }

            _captureElement.Source = null;
            _internalState         = CameraCaptureControlStates.Hidden;
        }
        /// <summary>
        /// Hides the camera preview asynchronously.
        /// </summary>
        /// <returns></returns>
        public async Task HideAsync()
        {
            _internalState = CameraCaptureControlStates.Deinitializing;

            if (MediaCapture != null)
            {
                try
                {
                    await MediaCapture.StopPreviewAsync();
                }
                catch {}

                //_mediaCapture.Failed -= OnMediaCaptureFailed;
                //_mediaCapture = null;
            }

            if (_captureElement != null)
            {
                _captureElement.Source = null;
            }

            _internalState = CameraCaptureControlStates.Hidden;
        }
        /// <summary>
        /// Starts the video capture asynchronously.
        /// </summary>
        /// <param name="folder">The folder.</param>
        /// <param name="fileName">Name of the file.</param>
        /// <returns></returns>
        /// <exception cref="System.InvalidOperationException"></exception>
        public async Task<StorageFile> StartVideoCaptureAsync(StorageFolder folder = null, string fileName = null)
        {
            if (_internalState == CameraCaptureControlStates.Recording)
            {
                // Note: Already recording - ignoring the folder and filename and returning result of previous request.
                await _recordingTaskSource.Task;
                return _videoFile;
            }

            if (_internalState != CameraCaptureControlStates.Shown)
            {
                var result = await ShowAsync();

                if (!result.Success)
                {
                    //TODO: Add error handling here.

                    return null;
                }
            }

            _internalState = CameraCaptureControlStates.Recording;
            _recordingTaskSource = new TaskCompletionSource<bool>(false);

            if (MediaCapture == null)
            {
                throw new InvalidOperationException();
            }

            if (folder == null)
            {
                folder = KnownFolders.VideosLibrary;
            }

            if (fileName == null)
            {
                fileName = await folder.CreateTempFileNameAsync(".mp4");
            }

            _videoFile = await folder.CreateFileAsync(
                fileName,
                CreationCollisionOption.FailIfExists);

            if (_recordingIndicator != null)
            {
                _recordingIndicator.Visibility = Visibility.Visible;
            }

            if (_recordingAnimation != null)
            {
                _recordingAnimation.Begin();
            }

            var encodingProfile =
                Path.GetExtension(fileName).Equals(".wmv", StringComparison.OrdinalIgnoreCase) ?
                MediaEncodingProfile.CreateWmv(VideoEncodingQuality) :
                MediaEncodingProfile.CreateMp4(VideoEncodingQuality);

            await MediaCapture.StartRecordToStorageFileAsync(encodingProfile, _videoFile);
            await _recordingTaskSource.Task;
            _recordingTaskSource = null;

            if (_recordingAnimation != null)
            {
                _recordingAnimation.Stop();
            }

            if (_recordingIndicator != null)
            {
                _recordingIndicator.Visibility = Visibility.Collapsed;
            }

            _internalState = CameraCaptureControlStates.Shown;

            return _videoFile;
        }
        /// <summary>
        /// Hides the camera preview asynchronously.
        /// </summary>
        /// <returns></returns>
        public async Task HideAsync()
        {
            _internalState = CameraCaptureControlStates.Deinitializing;

            if (MediaCapture != null)
            {
                try
                {
                    await MediaCapture.StopPreviewAsync();
                }
                catch {}

                //_mediaCapture.Failed -= OnMediaCaptureFailed;
                //_mediaCapture = null;
            }

            if (_captureElement != null)
            {
                _captureElement.Source = null;
            }

            _internalState = CameraCaptureControlStates.Hidden;
        }
        /// <summary>
        /// Shows the preview asynchronously (completes when the camera is initialized)..
        /// </summary>
        /// <returns></returns>
        public async Task<CameraInitializationResult> ShowAsync()
        {
            await this.WaitForLoadedAsync();
            await this.WaitForNonZeroSizeAsync();
            var result = await InitializeAsync();

            if (!result.Success)
            {
                return result;
            }

            try
            {
                _internalState = CameraCaptureControlStates.Shown;

                if (_captureElement != null)
                {
                    _captureElement.Source = MediaCapture;
                    await MediaCapture.StartPreviewAsync();
                }

                return result;
            }
            catch (Exception ex)
            {
                return new CameraInitializationResult(false, "Camera display failed", ex);
            }
        }
        /// <summary>
        /// Performs the one time initialization and shows the preview (if video).
        /// </summary>
        /// <returns></returns>
        private async Task<CameraInitializationResult> InitializeAsync()
        {
            CameraInitializationResult result;

            try
            {
                Debug.Assert(Dispatcher.HasThreadAccess);

                if (_initializationTaskSource != null)
                {
                    // Already initializing or initialized
                    await _initializationTaskSource.Task;
                    _initializationTaskSource = new TaskCompletionSource<CameraInitializationResult>();
                }

                _internalState = CameraCaptureControlStates.Initializing;
                _initializationTaskSource = new TaskCompletionSource<CameraInitializationResult>();

                if (_currentAudioCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                    this.StreamingCaptureMode == StreamingCaptureMode.Audio))
                {
                    await FindAudioCaptureDevicesAsync();

                    if (_audioCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Audio)
                        {
                            _internalState = CameraCaptureControlStates.Hidden;
                            Debugger.Break();

                            result = new CameraInitializationResult(false, "No audio devices found.");
                            _initializationTaskSource.SetResult(result);

                            return result;
                        }
                    }
                    else if (this.AudioDeviceId != null)
                    {
                        var device = _audioCaptureDevices.FirstOrDefault(d => d.Id == this.AudioDeviceId);

                        if (device != null)
                        {
                            _currentAudioCaptureDeviceIndex = Array.IndexOf(_audioCaptureDevices, device);
                        }
                    }
                    else if (this.PickAudioDeviceAutomatically)
                    {
                        _currentAudioCaptureDeviceIndex = 0;
                    }
                    else
                    {
                        await ShowMicrophoneSelector();
                    }
                }

                if (_currentVideoCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                    this.StreamingCaptureMode == StreamingCaptureMode.Video))
                {
                    await FindVideoCaptureDevicesAsync();

                    if (_videoCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Video)
                        {
                            Debugger.Break();
                            _internalState = CameraCaptureControlStates.Hidden;

                            result = new CameraInitializationResult(false, "No video devices found.");
                            _initializationTaskSource.SetResult(result);

                            return result;
                        }

                        // Audio only
                        result = new CameraInitializationResult(true);
                        _initializationTaskSource.SetResult(result);

                        return result;
                    }

                    if (_videoCaptureDevices.Length == 1)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        result = await this.StartPreviewAsync();
                        _initializationTaskSource.SetResult(result);

                        return result;
                    }

                    if (this.VideoDeviceId != null)
                    {
                        var device = _videoCaptureDevices.FirstOrDefault(d => d.Id == this.VideoDeviceId);

                        if (device != null)
                        {
                            _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, device);
                            result = await this.StartPreviewAsync();
                            _initializationTaskSource.SetResult(result);

                            return result;
                        }

                        // If requested device was not found - don't give up, but look for another one
                    }

                    if (_preferredVideoCaptureDevice != null)
                    {
                        _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, _preferredVideoCaptureDevice);
                        result = await this.StartPreviewAsync();
                        _initializationTaskSource.SetResult(result);

                        return result;
                    }

                    if (PickVideoDeviceAutomatically)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        result = await this.StartPreviewAsync();
                        _initializationTaskSource.SetResult(result);

                        return result;
                    }

                    bool success = await ShowWebCamSelector();

                    if (success)
                    {
                        result = new CameraInitializationResult(true);
                        _initializationTaskSource.SetResult(result);

                        return result;
                        
                    }

                    result = new CameraInitializationResult(false, "Unable to select video device.");
                    _initializationTaskSource.SetResult(result);

                    return result;
                }

                // Audio only recording
                result = await this.StartPreviewAsync();
                _initializationTaskSource.SetResult(result);

                return result;
            }
            catch (Exception ex)
            {
                result = new CameraInitializationResult(false, "An unkown error has occured.", ex);

                if (_initializationTaskSource != null)
                {
                    _initializationTaskSource.SetResult(result);
                }

                return result;
            }
        }
Example #9
0
        public async Task <StorageFile> StartVideoCaptureAsync(StorageFolder folder = null, string fileName = null)
        {
            if (_internalState == CameraCaptureControlStates.Recording)
            {
                // Note: Already recording - ignoring the folder and filename and returning result of previous request.
                await _recordingTaskSource.Task;
                return(_videoFile);
            }

            _internalState       = CameraCaptureControlStates.Recording;
            _recordingTaskSource = new TaskCompletionSource <bool>(false);

            if (_internalState != CameraCaptureControlStates.Shown)
            {
                await ShowAsync();
            }

            if (_mediaCapture == null)
            {
                throw new InvalidOperationException();
            }

            if (folder == null)
            {
                folder = KnownFolders.VideosLibrary;
            }

            if (fileName == null)
            {
                fileName = await folder.CreateTempFileNameAsync(".mp4");
            }

            _videoFile = await folder.CreateFileAsync(
                fileName,
                CreationCollisionOption.FailIfExists);

            if (_recordingIndicator != null)
            {
                _recordingIndicator.Visibility = Visibility.Visible;
            }

            if (_recordingAnimation != null)
            {
                _recordingAnimation.Begin();
            }

            var encodingProfile =
                Path.GetExtension(fileName).Equals(".wmv", StringComparison.OrdinalIgnoreCase) ?
                MediaEncodingProfile.CreateWmv(VideoEncodingQuality) :
                MediaEncodingProfile.CreateMp4(VideoEncodingQuality);

            await _mediaCapture.StartRecordToStorageFileAsync(encodingProfile, _videoFile);

            await _recordingTaskSource.Task;

            _recordingTaskSource = null;

            if (_recordingAnimation != null)
            {
                _recordingAnimation.Stop();
            }

            if (_recordingIndicator != null)
            {
                _recordingIndicator.Visibility = Visibility.Collapsed;
            }

            _internalState = CameraCaptureControlStates.Shown;
            return(_videoFile);
        }
Example #10
0
        public async Task <bool> ShowAsync()
        {
            if (_internalState != CameraCaptureControlStates.Hidden)
            {
                //TODO: Handle this case better - wait for the state to be hidden if deinitializing or wait for initialization to complete before returning if initializing
                return(false);
            }

            _internalState = CameraCaptureControlStates.Initializing;

            try
            {
                if (_currentAudioCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                     this.StreamingCaptureMode == StreamingCaptureMode.Audio))
                {
                    await FindAudioCaptureDevicesAsync();

                    if (_audioCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Audio)
                        {
                            _internalState = CameraCaptureControlStates.Hidden;
                            Debugger.Break();
                            return(false);
                        }
                    }
                    else if (this.AudioDeviceId != null)
                    {
                        var device = _audioCaptureDevices.FirstOrDefault(d => d.Id == this.AudioDeviceId);

                        if (device != null)
                        {
                            _currentAudioCaptureDeviceIndex = Array.IndexOf(_audioCaptureDevices, device);
                        }
                    }
                    else if (this.PickAudioDeviceAutomatically)
                    {
                        _currentAudioCaptureDeviceIndex = 0;
                    }
                    else
                    {
                        await ShowMicrophoneSelector();
                    }
                }

                if (_currentVideoCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                     this.StreamingCaptureMode == StreamingCaptureMode.Video))
                {
                    await FindVideoCaptureDevicesAsync();

                    if (_videoCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Video)
                        {
                            Debugger.Break();
                            _internalState = CameraCaptureControlStates.Hidden;
                            return(false);
                        }

                        // Audio only
                        return(true);
                    }

                    if (_videoCaptureDevices.Length == 1)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        await StartPreviewAsync();

                        return(true);
                    }

                    if (this.VideoDeviceId != null)
                    {
                        var device = _videoCaptureDevices.FirstOrDefault(d => d.Id == this.VideoDeviceId);

                        if (device != null)
                        {
                            _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, device);
                            await StartPreviewAsync();

                            return(true);
                        }

                        // If requested device was not found - don't give up, but look for another one
                    }

                    if (_preferredVideoCaptureDevice != null)
                    {
                        _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, _preferredVideoCaptureDevice);
                        await StartPreviewAsync();

                        return(true);
                    }

                    if (PickVideoDeviceAutomatically)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        await StartPreviewAsync();

                        return(true);
                    }

                    return(await ShowWebCamSelector());
                }

                // Audio only recording
                await StartPreviewAsync();

                return(true);
            }
            catch
            {
                _internalState = CameraCaptureControlStates.Hidden;
                throw;
            }
        }
        private async Task StartPreviewAsync()
        {
            _mediaCapture = new MediaCapture();

            if (_currentVideoCaptureDeviceIndex >= 0)
            {
                this.VideoDevice = _videoCaptureDevices[_currentVideoCaptureDeviceIndex];
                this.VideoDeviceId = this.VideoDevice.Id;
                this.VideoDeviceName = this.VideoDevice.Name;
                this.VideoDeviceEnclosureLocation = this.VideoDevice.EnclosureLocation;
            }

            if (_currentAudioCaptureDeviceIndex >= 0)
            {
                this.AudioDevice = _audioCaptureDevices[_currentAudioCaptureDeviceIndex];
                this.AudioDeviceId = this.AudioDevice.Id;
                this.AudioDeviceName = this.AudioDevice.Name;
            }

            if (CheckStreamingCaptureModeConfiguration())
            {
                return;
            }

            var settings = new MediaCaptureInitializationSettings
            {
                StreamingCaptureMode = this.StreamingCaptureMode,
                PhotoCaptureSource = PhotoCaptureSource.Auto //TODO: Figure out if this is worth exposing
            };

            if (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo)
            {
                settings.VideoDeviceId = this.VideoDeviceId;
                settings.AudioDeviceId = this.AudioDeviceId;
            }
            else if (this.StreamingCaptureMode == StreamingCaptureMode.Video)
            {
                settings.VideoDeviceId = this.VideoDeviceId;
            }
            else if (this.StreamingCaptureMode == StreamingCaptureMode.Audio)
            {
                settings.AudioDeviceId = this.AudioDeviceId;
            }

            await _mediaCapture.InitializeAsync(settings);

            _captureElement.Source = _mediaCapture;
            await _mediaCapture.StartPreviewAsync();
            _internalState = CameraCaptureControlStates.Shown;
        }
        public async Task HideAsync()
        {
            _internalState = CameraCaptureControlStates.Deinitializing;

            if (_mediaCapture != null)
            {
                await _mediaCapture.StopPreviewAsync();
                _mediaCapture = null;
            }

            _captureElement.Source = null;
            _internalState = CameraCaptureControlStates.Hidden;
        }
        public async Task<bool> ShowAsync()
        {
            if (_internalState != CameraCaptureControlStates.Hidden)
            {
                //TODO: Handle this case better - wait for the state to be hidden if deinitializing or wait for initialization to complete before returning if initializing
                return false;
            }

            _internalState = CameraCaptureControlStates.Initializing;

            try
            {
                if (_currentAudioCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                    this.StreamingCaptureMode == StreamingCaptureMode.Audio))
                {
                    await FindAudioCaptureDevicesAsync();

                    if (_audioCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Audio)
                        {
                            _internalState = CameraCaptureControlStates.Hidden;
                            Debugger.Break();
                            return false;
                        }
                    }
                    else if (this.AudioDeviceId != null)
                    {
                        var device = _audioCaptureDevices.FirstOrDefault(d => d.Id == this.AudioDeviceId);

                        if (device != null)
                        {
                            _currentAudioCaptureDeviceIndex = Array.IndexOf(_audioCaptureDevices, device);
                        }
                    }
                    else if (this.PickAudioDeviceAutomatically)
                    {
                        _currentAudioCaptureDeviceIndex = 0;
                    }
                    else
                    {
                        await ShowMicrophoneSelector();
                    }
                }

                if (_currentVideoCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                    this.StreamingCaptureMode == StreamingCaptureMode.Video))
                {
                    await FindVideoCaptureDevicesAsync();

                    if (_videoCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Video)
                        {
                            Debugger.Break();
                            _internalState = CameraCaptureControlStates.Hidden;
                            return false;
                        }

                        // Audio only
                        return true;
                    }

                    if (_videoCaptureDevices.Length == 1)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        await StartPreviewAsync();
                        return true;
                    }

                    if (this.VideoDeviceId != null)
                    {
                        var device = _videoCaptureDevices.FirstOrDefault(d => d.Id == this.VideoDeviceId);

                        if (device != null)
                        {
                            _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, device);
                            await StartPreviewAsync();
                            return true;
                        }

                        // If requested device was not found - don't give up, but look for another one
                    }

                    if (_preferredVideoCaptureDevice != null)
                    {
                        _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, _preferredVideoCaptureDevice);
                        await StartPreviewAsync();
                        return true;
                    }

                    if (PickVideoDeviceAutomatically)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        await StartPreviewAsync();
                        return true;
                    }

                    return await ShowWebCamSelector();
                }

                // Audio only recording
                await StartPreviewAsync();
                return true;
            }
            catch
            {
                _internalState = CameraCaptureControlStates.Hidden;
                throw;
            }
        }
        /// <summary>
        /// Performs the one time initialization and shows the preview (if video).
        /// </summary>
        /// <returns></returns>
        private async Task <CameraInitializationResult> InitializeAsync()
        {
            CameraInitializationResult result;

            try
            {
                Debug.Assert(Dispatcher.HasThreadAccess);

                if (_initializationTaskSource != null)
                {
                    // Already initializing or initialized
                    await _initializationTaskSource.Task;
                    _initializationTaskSource = new TaskCompletionSource <CameraInitializationResult>();
                }

                _internalState            = CameraCaptureControlStates.Initializing;
                _initializationTaskSource = new TaskCompletionSource <CameraInitializationResult>();

                if (_currentAudioCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                     this.StreamingCaptureMode == StreamingCaptureMode.Audio))
                {
                    await FindAudioCaptureDevicesAsync();

                    if (_audioCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Audio)
                        {
                            _internalState = CameraCaptureControlStates.Hidden;
                            Debugger.Break();

                            result = new CameraInitializationResult(false, "No audio devices found.");
                            _initializationTaskSource.SetResult(result);

                            return(result);
                        }
                    }
                    else if (this.AudioDeviceId != null)
                    {
                        var device = _audioCaptureDevices.FirstOrDefault(d => d.Id == this.AudioDeviceId);

                        if (device != null)
                        {
                            _currentAudioCaptureDeviceIndex = Array.IndexOf(_audioCaptureDevices, device);
                        }
                    }
                    else if (this.PickAudioDeviceAutomatically)
                    {
                        _currentAudioCaptureDeviceIndex = 0;
                    }
                    else
                    {
                        await ShowMicrophoneSelector();
                    }
                }

                if (_currentVideoCaptureDeviceIndex < 0 &&
                    (this.StreamingCaptureMode == StreamingCaptureMode.AudioAndVideo ||
                     this.StreamingCaptureMode == StreamingCaptureMode.Video))
                {
                    await FindVideoCaptureDevicesAsync();

                    if (_videoCaptureDevices.Length == 0)
                    {
                        if (this.StreamingCaptureMode == StreamingCaptureMode.Video)
                        {
                            Debugger.Break();
                            _internalState = CameraCaptureControlStates.Hidden;

                            result = new CameraInitializationResult(false, "No video devices found.");
                            _initializationTaskSource.SetResult(result);

                            return(result);
                        }

                        // Audio only
                        result = new CameraInitializationResult(true);
                        _initializationTaskSource.SetResult(result);

                        return(result);
                    }

                    if (_videoCaptureDevices.Length == 1)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        result = await this.StartPreviewAsync();

                        _initializationTaskSource.SetResult(result);

                        return(result);
                    }

                    if (this.VideoDeviceId != null)
                    {
                        var device = _videoCaptureDevices.FirstOrDefault(d => d.Id == this.VideoDeviceId);

                        if (device != null)
                        {
                            _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, device);
                            result = await this.StartPreviewAsync();

                            _initializationTaskSource.SetResult(result);

                            return(result);
                        }

                        // If requested device was not found - don't give up, but look for another one
                    }

                    if (_preferredVideoCaptureDevice != null)
                    {
                        _currentVideoCaptureDeviceIndex = Array.IndexOf(_videoCaptureDevices, _preferredVideoCaptureDevice);
                        result = await this.StartPreviewAsync();

                        _initializationTaskSource.SetResult(result);

                        return(result);
                    }

                    if (PickVideoDeviceAutomatically)
                    {
                        _currentVideoCaptureDeviceIndex = 0;
                        result = await this.StartPreviewAsync();

                        _initializationTaskSource.SetResult(result);

                        return(result);
                    }

                    bool success = await ShowWebCamSelector();

                    if (success)
                    {
                        result = new CameraInitializationResult(true);
                        _initializationTaskSource.SetResult(result);

                        return(result);
                    }

                    result = new CameraInitializationResult(false, "Unable to select video device.");
                    _initializationTaskSource.SetResult(result);

                    return(result);
                }

                // Audio only recording
                result = await this.StartPreviewAsync();

                _initializationTaskSource.SetResult(result);

                return(result);
            }
            catch (Exception ex)
            {
                result = new CameraInitializationResult(false, "An unkown error has occured.", ex);

                if (_initializationTaskSource != null)
                {
                    _initializationTaskSource.SetResult(result);
                }

                return(result);
            }
        }