簡體   English   中英

如何在Windows Phone上設置AudioVideoCaptureDevice的捕獲源

[英]how to set capture source of AudioVideoCaptureDevice on Windows Phone

我正在嘗試使用AudioVideoCaptureDevice在Windows Phone上捕獲視頻,但是當我嘗試設置captureSource時,出現一條錯誤消息,提示“由於對象的狀態,操作無效”。 您能在以下代碼中告訴我該怎么做嗎?

程式碼片段:

    // Viewfinder for capturing video.
    private VideoBrush videoRecorderBrush;

    // Source and device for capturing video.
    private CaptureSource _cs;
    private VideoCaptureDevice _cd;
    private AudioVideoCaptureDevice vcDevice;
    double w, h;

    // File details for storing the recording.        
    private IsolatedStorageFileStream isoVideoFile;
    private FileSink fileSink;
    private string isoVideoFileName = "iClips_Video.mp4";
    private StorageFile sfVideoFile;

    // For managing button and application state.
    private enum ButtonState { Initialized, Stopped, Ready, Recording, Playback, Paused, NoChange, CameraNotSupported };
    private ButtonState currentAppState;


 // Constructor
    public MainPage()
    {
        try
        {
            InitializeComponent();
            //setup recording
            // Prepare ApplicationBar and buttons.
            PhoneAppBar = (ApplicationBar)ApplicationBar;
            PhoneAppBar.IsVisible = true;
            StartRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[0]);
            StopPlaybackRecording = ((ApplicationBarIconButton)ApplicationBar.Buttons[1]);
            StartPlayback = ((ApplicationBarIconButton)ApplicationBar.Buttons[2]);
            PausePlayback = ((ApplicationBarIconButton)ApplicationBar.Buttons[3]);

            SetScreenResolution();

            //initialize the camera task
            cameraCaptureTask = new CameraCaptureTask();
            cameraCaptureTask.Completed += new EventHandler<PhotoResult>(cameraCaptureTask_Completed);

            if (isFilePresent("username") && isFilePresent("Password"))
            {
                if (isFilePresent("IsProfilePhotoOnServer"))
                {
                    connectToSocket();
                }
                else
                {
                    SignUpProfilePhoto();
                }  
            }
            else
            {
                SignIn();
            }
        }
        catch (Exception ex)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                MessageBox.Show("Constructor Error:\n"+ ex.Message);
            });
        }
    }



    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        // Initialize the video recorder.
        InitializeVideoRecorder();

        //prepare shutter hot keys 
        CameraButtons.ShutterKeyHalfPressed += OnButtonHalfPress;
        CameraButtons.ShutterKeyPressed += OnButtonFullPress;
        CameraButtons.ShutterKeyReleased += OnButtonRelease;
    }
    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        // Dispose of camera and media objects.
        DisposeVideoPlayer();
        DisposeVideoRecorder();

        base.OnNavigatedFrom(e);

        CameraButtons.ShutterKeyHalfPressed -= OnButtonHalfPress;
        CameraButtons.ShutterKeyPressed -= OnButtonFullPress;
        CameraButtons.ShutterKeyReleased -= OnButtonRelease;
    }
    protected override void OnOrientationChanged(OrientationChangedEventArgs e)
    {
        if (vcDevice != null)
        {
            if (e.Orientation == PageOrientation.LandscapeLeft)
            {
                txtDebug.Text = "LandscapeLeft";
                videoRecorderBrush.RelativeTransform =
                    new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };

                //rotate logo
                if (logo != null) 
                {
                    RotateTransform rt = new RotateTransform();
                    rt.Angle = 90;
                    //default rotation is around top left corner of the control,
                    //but you sometimes want to rotate around the center of the control
                    //to do that, you need to set the RenderTransFormOrigin
                    //of the item you're going to rotate
                    //I did not test this approach, maybe You're going to need to use actual coordinates
                    //so this bit is for information purposes only
                    logo.RenderTransformOrigin = new Point(0.5, 0.5);
                    logo.RenderTransform = rt;                    
                }

                //rotate sign in link
                if (MyGrid != null)
                {
                    RotateTransform rt = new RotateTransform();
                    rt.Angle = 90;
                    //default rotation is around top left corner of the control,
                    //but you sometimes want to rotate around the center of the control
                    //to do that, you need to set the RenderTransFormOrigin
                    //of the item you're going to rotate
                    //I did not test this approach, maybe You're going to need to use actual coordinates
                    //so this bit is for information purposes only
                    MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
                    MyGrid.RenderTransform = rt;                    
                }

            }
            if (e.Orientation == PageOrientation.PortraitUp)
            {
                txtDebug.Text = "PortraitUp";
                videoRecorderBrush.RelativeTransform =
                    new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 90 };
                //rotate logo
                if (logo != null)
                {
                    RotateTransform rt = new RotateTransform();
                    rt.Angle = 0;
                    //default rotation is around top left corner of the control,
                    //but you sometimes want to rotate around the center of the control
                    //to do that, you need to set the RenderTransFormOrigin
                    //of the item you're going to rotate
                    //I did not test this approach, maybe You're going to need to use actual coordinates
                    //so this bit is for information purposes only
                    logo.RenderTransformOrigin = new Point(0.5, 0.5);
                    logo.RenderTransform = rt;
                }

                //rotate sign in link
                if (MyGrid != null)
                {
                    RotateTransform rt = new RotateTransform();
                    rt.Angle = 0;
                    //default rotation is around top left corner of the control,
                    //but you sometimes want to rotate around the center of the control
                    //to do that, you need to set the RenderTransFormOrigin
                    //of the item you're going to rotate
                    //I did not test this approach, maybe You're going to need to use actual coordinates
                    //so this bit is for information purposes only
                    MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
                    MyGrid.RenderTransform = rt;
                }
            }

            if (e.Orientation == PageOrientation.LandscapeRight)
            {
                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtDebug.Text = "LandscapeRight";
                    // Rotate for LandscapeRight orientation.
                    //videoRecorderBrush.RelativeTransform =
                    //new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 180 };
                    //rotate logo
                    if (logo != null)
                    {
                        RotateTransform rt = new RotateTransform();
                        rt.Angle = -90;
                        //default rotation is around top left corner of the control,
                        //but you sometimes want to rotate around the center of the control
                        //to do that, you need to set the RenderTransFormOrigin
                        //of the item you're going to rotate
                        //I did not test this approach, maybe You're going to need to use actual coordinates
                        //so this bit is for information purposes only
                        logo.RenderTransformOrigin = new Point(0.5, 0.5);
                        logo.RenderTransform = rt;
                    }

                    //rotate MyGrid
                    if (MyGrid != null)
                    {
                        RotateTransform rt = new RotateTransform();
                        rt.Angle = -90;
                        //default rotation is around top left corner of the control,
                        //but you sometimes want to rotate around the center of the control
                        //to do that, you need to set the RenderTransFormOrigin
                        //of the item you're going to rotate
                        //I did not test this approach, maybe You're going to need to use actual coordinates
                        //so this bit is for information purposes only
                        MyGrid.RenderTransformOrigin = new Point(0.5, 0.5);
                        MyGrid.RenderTransform = rt;
                    }
                }); 

            }
            if (e.Orientation == PageOrientation.PortraitDown)
            {
                this.Dispatcher.BeginInvoke(delegate()
                {
                    txtDebug.Text = "PortraitDown";
                    videoRecorderBrush.RelativeTransform =
                        new CompositeTransform() { CenterX = 0.5, CenterY = 0.5, Rotation = 270 };
                });
            }
        }
    }

    // Hardware shutter button Hot-Actions.
    private void OnButtonHalfPress(object sender, EventArgs e)
    {
        //toggle between video- play and pause
        try
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                if (StartPlayback.IsEnabled)
                {
                    PlayVideo();
                }
                if (PausePlayback.IsEnabled)
                {
                    PauseVideo();
                }
            });

        }
        catch (Exception focusError)
        {
            // Cannot focus when a capture is in progress.
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = focusError.Message;
            });
        }
    }
    private void OnButtonFullPress(object sender, EventArgs e)
    {
        // Focus when a capture is not in progress.
        try
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                if (vcDevice != null)
                {
                    //stopVideoPlayer if it's playing back
                    if (currentAppState == ButtonState.Playback || currentAppState == ButtonState.Paused)
                    {
                        DisposeVideoPlayer();
                        StartVideoPreview();
                    }

                    if (StartRecording.IsEnabled)
                    {
                        StartVideoRecording();
                    }
                    else
                    {
                        StopVideoRecording();
                    }
                }

            });
        }
        catch (Exception focusError)
        {
            // Cannot focus when a capture is in progress.
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = focusError.Message;
            });
        }
    }
    private void OnButtonRelease(object sender, EventArgs e)
    {
        try
        {
            this.Dispatcher.BeginInvoke(delegate()
            {

            });

        }
        catch (Exception focusError)
        {
            // Cannot focus when a capture is in progress.
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = focusError.Message;
            });
        }
    }

    // Update the buttons and text on the UI thread based on app state.
    private void UpdateUI(ButtonState currentButtonState, string statusMessage)
    {
        // Run code on the UI thread.
        Dispatcher.BeginInvoke(delegate
        {

            switch (currentButtonState)
            {
                // When the camera is not supported by the phone.
                case ButtonState.CameraNotSupported:
                    StartRecording.IsEnabled = false;
                    StopPlaybackRecording.IsEnabled = false;
                    StartPlayback.IsEnabled = false;
                    PausePlayback.IsEnabled = false;
                    break;

                // First launch of the application, so no video is available.
                case ButtonState.Initialized:
                    StartRecording.IsEnabled = true;
                    StopPlaybackRecording.IsEnabled = false;
                    StartPlayback.IsEnabled = false;
                    PausePlayback.IsEnabled = false;
                    break;

                // Ready to record, so video is available for viewing.
                case ButtonState.Ready:
                    StartRecording.IsEnabled = true;
                    StopPlaybackRecording.IsEnabled = false;
                    StartPlayback.IsEnabled = true;
                    PausePlayback.IsEnabled = false;
                    break;

                // Video recording is in progress.
                case ButtonState.Recording:
                    StartRecording.IsEnabled = false;
                    StopPlaybackRecording.IsEnabled = true;
                    StartPlayback.IsEnabled = false;
                    PausePlayback.IsEnabled = false;
                    break;

                // Video playback is in progress.
                case ButtonState.Playback:
                    StartRecording.IsEnabled = false;
                    StopPlaybackRecording.IsEnabled = true;
                    StartPlayback.IsEnabled = false;
                    PausePlayback.IsEnabled = true;
                    break;

                // Video playback has been paused.
                case ButtonState.Paused:
                    StartRecording.IsEnabled = false;
                    StopPlaybackRecording.IsEnabled = true;
                    StartPlayback.IsEnabled = true;
                    PausePlayback.IsEnabled = false;
                    break;

                default:
                    break;
            }

            // Display a message.
            txtDebug.Text = statusMessage;

            // Note the current application state.
            currentAppState = currentButtonState;
        });
    }

    public async void InitializeVideoRecorder()
    {
        try
        {
            if (_cs == null)
            {
                _cs = new CaptureSource();
                fileSink = new FileSink();
                _cd = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();

                CameraSensorLocation location = CameraSensorLocation.Back;
                var captureResolutions =
                    AudioVideoCaptureDevice.GetAvailableCaptureResolutions(location);
                vcDevice = await AudioVideoCaptureDevice.OpenAsync(location, captureResolutions[0]);
                vcDevice.RecordingFailed += OnCaptureFailed;
                vcDevice.VideoEncodingFormat = CameraCaptureVideoFormat.H264;
                vcDevice.AudioEncodingFormat = CameraCaptureAudioFormat.Aac;

                // Initialize the camera if it exists on the phone.
                if (vcDevice != null)
                {
                    //initialize fileSink
                    await InitializeFileSink();

                    // Create the VideoBrush for the viewfinder.
                    videoRecorderBrush = new VideoBrush();
                    videoRecorderBrush.SetSource(_cs);

                    // Display the viewfinder image on the rectangle.
                    viewfinderRectangle.Fill = videoRecorderBrush;

                    _cs.Start();

                    // Set the button state and the message.
                    UpdateUI(ButtonState.Initialized, "Tap record to start recording...");
                }
                else
                {
                    // Disable buttons when the camera is not supported by the phone.
                    UpdateUI(ButtonState.CameraNotSupported, "A camera is not supported on this phone.");
                }
            }
        }
        catch(Exception ex)
        {
            MessageBox.Show("InitializeVideoRecorder Error:\n" + ex.Message);
        }
    }
    public async Task InitializeFileSink()
    {
        StorageFolder isoStore = ApplicationData.Current.LocalFolder;
        sfVideoFile = await isoStore.CreateFileAsync(
            isoVideoFileName,
          CreationCollisionOption.ReplaceExisting);
    }
    private void OnCaptureFailed(AudioVideoCaptureDevice sender, CaptureFailedEventArgs args)
    {
        MessageBox.Show(args.ToString());
    }

    private void OnCaptureSourceFailed(object sender, ExceptionRoutedEventArgs e)
    {
        MessageBox.Show(e.ErrorException.Message.ToString());
    }

    // Set the recording state: display the video on the viewfinder.
    private void StartVideoPreview()
    {
        try
        {
            // Display the video on the viewfinder.
            if (_cs.VideoCaptureDevice != null
            && _cs.State == CaptureState.Stopped)
            {
                // Add captureSource to videoBrush.
                videoRecorderBrush.SetSource(_cs);

                // Add videoBrush to the visual tree.
                viewfinderRectangle.Fill = videoRecorderBrush;

                _cs.Start();

                // Set the button states and the message.
                UpdateUI(ButtonState.Ready, "Ready to record.");

                //Create optional Resolutions
            }
        }
        // If preview fails, display an error.
        catch (Exception e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = "ERROR: " + e.Message.ToString();
            });
        }
    }
    // Set recording state: start recording.
    private void StartVideoRecording()
    {
        try
        {
            // Connect fileSink to captureSource.
            if (_cs.VideoCaptureDevice != null
                && _cs.State == CaptureState.Started)
            {
                _cs.Stop();

                // Connect the input and output of fileSink.
                fileSink.CaptureSource = _cs;
                fileSink.IsolatedStorageFileName = isoVideoFileName;
            }

            // Begin recording.
            if (_cs.VideoCaptureDevice != null
                && _cs.State == CaptureState.Stopped)
            {
                _cs.Start();
            }

            // Set the button states and the message.
            UpdateUI(ButtonState.Recording, "Recording...");
            StartTimer();
        }

        // If recording fails, display an error.
        catch (Exception e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = "ERROR: " + e.Message.ToString();
            });
        }
    }
    // Set the recording state: stop recording.
    private void StopVideoRecording()
    {
        try
        {
            // Stop recording.
            if (_cs.VideoCaptureDevice != null
            && _cs.State == CaptureState.Started)
            {
                _cs.Stop();

                // Disconnect fileSink.
                fileSink.CaptureSource = null;
                fileSink.IsolatedStorageFileName = null;

                // Set the button states and the message.
                UpdateUI(ButtonState.Stopped, "Preparing viewfinder...");
                StopTimer();
                StartVideoPreview();
            }
        }
        // If stop fails, display an error.
        catch (Exception e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = "ERROR: " + e.Message.ToString();
            });
        }
    }
    // Start the video recording.
    private void StartRecording_Click(object sender, EventArgs e)
    {
        // Avoid duplicate taps.
        StartRecording.IsEnabled = false;
        StartVideoRecording();
    }
    private void DisposeVideoRecorder()
    {
        if (_cs != null)
        {
            // Stop captureSource if it is running.
            if (_cs.VideoCaptureDevice != null
                && _cs.State == CaptureState.Started)
            {
                _cs.Stop();
            }

            // Remove the event handler for captureSource.
            _cs.CaptureFailed -= OnCaptureFailed;

            // Remove the video recording objects.
            _cs = null;
            vcDevice = null;
            fileSink = null;
            videoRecorderBrush = null;
        }
    }

    private void OnCaptureFailed(object sender, ExceptionRoutedEventArgs e)
    {
        throw new NotImplementedException();
    }

    //STOP WATCH
    private void StartTimer()
    {
        dispatcherTimer = new System.Windows.Threading.DispatcherTimer();

        dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);

        dispatcherTimer.Interval = new TimeSpan(0, 0, 1);

        dispatcherTimer.Start();
        startTime = System.DateTime.Now;
    }
    private void StopTimer()
    {
        dispatcherTimer.Stop();
    }
    private void dispatcherTimer_Tick(object sender, EventArgs e)
    {
        System.DateTime now = System.DateTime.Now;
        txtRecTime.Text = now.Subtract(startTime).ToString();
    } 

錯誤會在initializeVideoRecorder()內部引發。

似乎您的代碼太長,無法分析,就像評論中提到的@john一樣。 但是,由於您建議在此處發布一些有用的鏈接,因此您可以繼續:在msdn中按照以下步驟進行操作,因為我嘗試過一次,因此不會出現任何問題。

如果您真的需要一個樣本作為開始,請使用msdn中的一個樣本。 希望您會充分利用這些實用程序。

我發現我必須將捕獲設備傳遞給視頻刷才能使其正常工作。 我仍然不確定在使用AudioVideoCaptureDevice進行捕獲時應在何處以及是否應使用CaptureSource。 無論如何,這里是解決方案代碼:

                // Create the VideoBrush for the viewfinder.
                videoRecorderBrush = new VideoBrush();
                videoRecorderBrush.SetSource(vcDevice); //substitute vcDevice with captureSource - vcDevice is the reference of AudioVideoCaptureDevice

                // Display the viewfinder image on the rectangle.
                viewfinderRectangle.Fill = videoRecorderBrush;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM