내보내기(0) 인쇄
모두 확장
정보
요청한 주제가 아래에 표시됩니다. 그러나 이 주제는 이 라이브러리에 포함되지 않습니다.

Windows Phone 8용 카메라 앱에서 동영상을 녹화하는 방법

2014-06-18

적용 대상: Windows Phone 8 및 Windows Phone Silverlight 8.1 | Windows Phone OS 7.1

 

Windows Phone OS 7.1 부터는 프로그래밍 방식으로 휴대폰 카메라에 액세스할 수 있습니다. 사진 캡처 이외에 휴대폰 카메라를 사용하여 동영상을 캡처할 수 있습니다. 이 항목에서는 동영상 레코드 앱을 만드는 방법에 대해 설명하고 Windows Phone 앱에서 동영상을 캡처, 표시 및 저장하는 방법을 보여 줍니다. 휴대폰 카메라를 사용하여 사진을 캡처하는 방법에 대한 자세한 내용은 Windows Phone 8용 기본 카메라 앱을 만드는 방법를 참조하세요.

팁팁:

이 항목에서는 System.Windows.Media.CaptureSourceFileSink 클래스를 사용하여 동영상을 녹화하는 방법에 대해 설명합니다. 앱에 이 항목에 설명된 컨트롤 외에 카메라 센서의 추가 컨트롤이 필요한 경우 AudioVideoCaptureDevice 클래스를 사용해 보세요. 자세한 내용은 AudioVideoCaptureDevice를 참조하세요.

이 항목은 동영상 레코더 샘플에 해당합니다.

이 항목에서는 다음 단계에 대해 설명합니다.

  1. 앱 및 UI 만들기

  2. UI 업데이트

  3. 카메라 초기화

  4. 미리 보기와 녹화 간 카메라 상태 전환

  5. 버튼 탭 처리

  6. 녹화 및 재생 개체 삭제

  7. 앱 완료

다음 이미지에서는 완성된 앱의 예를 보여 줍니다.

AP_Con_CameraVideoHowTo

녹화하는 동안 이 앱은 FileSink 클래스를 사용하여 CaptureSource 개체에서 동영상을 전달하고 이를 IsolatedStorageFileStream 개체를 통해 격리된 저장소에 저장합니다. 앱에 카메라 뷰파인더를 제공하기 위해서는 동일한 CaptureSourceVideoBrush 컨트롤에 대한 소스로도 사용됩니다. CaptureSourceFileSink에 연결되거나 여기에서 제거되면 실행할 수 없습니다. CaptureSourceFileSink에 연결되어 있는 동안 실행되면 동영상 녹화가 발생합니다.

녹화된 동영상 재생의 경우 IsolatedStorageFileStream 개체가 녹화된 동영상 파일을 읽어 MediaElement 컨트롤에 소스로 제공합니다. 이 앱의 구현 방법에 대한 자세한 내용은 다음 섹션을 참조하세요.

이 섹션에서는 앱을 만들고 개발할 준비를 합니다.

참고참고:

Windows Phone OS 7.1 의 기능을 사용하기 위해 Windows Phone OS 7.0 앱을 업그레이드하는 경우 카메라 기능 ID_CAP_ISV_CAMERA는 앱 매니페스트 파일 WMAppManifest.xml에 자동으로 추가되지 않습니다. ID_CAP_ISV_CAMERA가 없으면 카메라 API를 사용하는 앱이 작동하지 않습니다. 새 Windows Phone OS 7.1 프로젝트에서는 이 기능이 앱 매니페스트 파일에 포함되어 있습니다.

앱을 만들려면

  1. Windows Phone SDK 를 통해 Windows Phone 앱 템플릿을 사용하여 새 프로젝트를 만듭니다.

  2. 앱이 만들어진 후 MainPage.xaml이 Visual Studio 디자이너 창에서 열립니다.

앱 기능을 지정하려면

  1. 카메라 앱을 만들려면 앱 매니페스트 파일에서 카메라 기능을 선언해야 합니다. 동영상 앱은 사운드도 녹음하므로 마이크 기능도 선언해야 합니다. 이러한 기능을 선언하지 않으면 이 앱이 작동하지 않습니다. WMAppManifest.xml을 열고 다음 기능 요소가 있는지 확인합니다.

    <Capability Name="ID_CAP_ISV_CAMERA"/>
    <Capability Name="ID_CAP_MICROPHONE"/>
    
    

    Windows Phone 8 앱에 후면 카메라가 필요한 경우 ID_REQ_BACKCAMERA 하드웨어 요구 사항을 사용합니다. 이렇게 하면 사용자에게 후면 카메라가 없는 경우 사용자가 앱을 다운로드할 수 없습니다. 기능 및 요구 사항에 대한 자세한 내용은 Windows Phone 8의 앱 기능 및 하드웨어 요구 사항을 참조하세요.

    중요중요:

    CaptureSource 클래스를 사용하는 Windows Phone OS 7.1 앱에서 오디오를 캡처하고 앱의 기능을 정확하게 검색하려면 Microsoft.Devices.Camera, Microsoft.Devices.PhotoCamera 또는 Microsoft.Xna.Framework.Audio.Microphone 클래스도 사용해야 합니다.

    이 특정 앱에는 이러한 클래스가 필요하지 않지만, Windows Phone OS 7.1 앱에는 Windows Phone 스토어 기능 검색 프로세스에서 ID_CAP_MICROPHONE 기능을 통합 시 앱 기능 목록에 추가하도록 요구하기 위해 클래스 중 하나를 통합하는 코드가 계속 필요합니다. 예제를 보려면 동영상 레코더 샘플에서 CapabilityPlaceholder 파일을 참조하세요.

    Windows Phone 8 부터 마이크 기능을 지정하면 휴대폰 마이크에 액세스할 수 있습니다.

  2. (선택 사항) 앱 기능에 전면 카메라가 필요한 경우 앱이 사용되는 Windows Phone 버전에 따라 앱 매니페스트 파일에 전면 카메라 기능 또는 하드웨어 요구 사항을 추가해 보세요.

    • ID_HW_FRONTCAMERA: Windows Phone OS 7.1 앱에 이 기능을 사용할 수 있습니다. 이 기능을 통해 전면 카메라가 없는 사용자에게 앱의 일부 기능이 휴대폰에서 작동하지 않지만 앱을 다운로드할 수 있다는 알림이 표시됩니다.

    • ID_REQ_FRONTCAMERA: Windows Phone 8 앱에 이 하드웨어 요구 사항을 사용할 수 있습니다. 이 요구 사항에 따라 전면 카메라가 없는 사용자는 앱을 다운로드할 수 없습니다.

    기능 및 요구 사항에 대한 자세한 내용은 Windows Phone 8의 앱 기능 및 하드웨어 요구 사항을 참조하세요.

앱에서 사용되는 아이콘을 추가하려면

  1. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 버튼으로 클릭하고 추가, 새 폴더를 차례로 선택합니다.

  2. 새 폴더의 이름을 Icons로 지정합니다.

  3. 솔루션 탐색기에서 Icons 폴더를 마우스 오른쪽 버튼으로 클릭하고 추가, 기존 항목을 차례로 선택합니다. 앱에서 사용되는 아이콘을 선택할 수 있는 기존 항목 추가 메뉴가 열립니다.

  4. 기존 항목 추가 창에서 다음 경로로 이동하여 아이콘을 선택합니다. 이 단계에서는 Visual Studio의 기본 설치로 가정합니다. 다른 위치에 설치한 경우 해당 위치에서 아이콘을 찾습니다.

    C:\Program Files (x86)\Microsoft SDKs\Windows Phone\v8.0\Icons\dark

    폴더에서 다음 아이콘을 선택합니다.

    • appbar.feature.video.rest.png

    • appbar.stop.rest.png

    • appbar.transport.pause.rest.png

    • appbar.transport.play.rest.png

    이러한 아이콘은 어두운 배경에서 사용하도록 흰색으로 디자인되어 있으며 기존 항목 추가 창의 흰색 배경에서는 공백으로 나타날 수 있습니다.

  5. 솔루션 탐색기에서 각 아이콘을 마우스 오른쪽 버튼으로 클릭한 다음 아이콘이 콘텐츠로 빌드되고 항상 출력 디렉터리로 복사되도록(항상 복사) 파일 속성을 설정합니다.

UI를 빌드하려면

  1. MainPage.xaml에서 다음 코드에 표시된 대로 phone:PhoneApplicationPage 요소를 업데이트합니다.

    SupportedOrientations="Landscape" Orientation="LandscapeLeft"
        shell:SystemTray.IsVisible="False"
    
    

    이 코드는 시스템 트레이를 감추고 앱을 가로 방향으로 유지합니다. CaptureSource 개체의 동영상은 회전할 수 없습니다. 거꾸로 촬영할 경우 동영상은 거꾸로 녹화됩니다.

    참고참고:

    PhotoCamera 클래스의 이미지는 회전할 수 있습니다. 이 방법에 대한 예제를 보려면 Windows Phone 8용 기본 카메라 앱을 만드는 방법를 참조하세요.

  2. MainPage.xaml에서 이름이 LayoutRootGrid를 다음 코드로 바꿉니다.

        <!--LayoutRoot is the root grid where all page content is placed-->
        <Canvas x:Name="LayoutRoot" Background="Transparent">
    
            <!--Camera viewfinder >-->
            <Rectangle 
                x:Name="viewfinderRectangle"
                Width="640" 
                Height="480" 
                HorizontalAlignment="Left" 
                Canvas.Left="80"/>
    
            <MediaElement 
                x:Name="VideoPlayer" 
                Width="640" 
                Height="480"
                AutoPlay="True" 
                RenderTransformOrigin="0.5, 0.5" 
                VerticalAlignment="Center" 
                HorizontalAlignment="Center" 
                Stretch="Fill"
                Canvas.Left="80"/>
    
            <!--Used for debugging >-->
            <TextBlock 
                Height="40" 
                HorizontalAlignment="Left" 
                Margin="100,428,0,0"
                Name="txtDebug" 
                VerticalAlignment="Top"
                Width="626"
                FontSize="24" 
                FontWeight="ExtraBold"/>
    
        </Canvas>
    
    

    이 코드는 viewfinderRectangle이라는 Rectangle, VideoPlayer라는 MediaElement, txtDebug라는 TextBlock을 지정합니다. viewfinderRectangleCaptureSource 개체로부터 동영상 이미지를 표시하는 데 사용되고, VideoPlayer는 녹화된 동영상이 격리된 저장소에 저장된 후 이를 재생하는 데 사용되며, txtDebug는 앱 상태를 전달하는 데 사용됩니다.

  3. MainPage.xaml에서 LayoutRoot라는 Grid 아래에 다음 코드를 추가합니다.

        <phone:PhoneApplicationPage.ApplicationBar>
            <shell:ApplicationBar IsVisible="True" IsMenuEnabled="True" x:Name="PhoneAppBar" Opacity="0.0">
                <shell:ApplicationBarIconButton IconUri="/Icons/appbar.feature.video.rest.png" Text="record"  x:Name="StartRecording" Click="StartRecording_Click" />
                <shell:ApplicationBarIconButton IconUri="/Icons/appbar.stop.rest.png" Text="stop" x:Name="StopPlaybackRecording" Click="StopPlaybackRecording_Click"/>
                <shell:ApplicationBarIconButton IconUri="/Icons/appbar.transport.play.rest.png" Text="play" x:Name="StartPlayback" Click="StartPlayback_Click"  />
                <shell:ApplicationBarIconButton IconUri="/Icons/appbar.transport.pause.rest.png" Text="pause" x:Name="PausePlayback" Click="PausePlayback_Click"/>
            </shell:ApplicationBar>
        </phone:PhoneApplicationPage.ApplicationBar>
    
    

    이 코드는 4개 버튼 record, stop, playpause을 사용하여 앱 바를 지정합니다. 이 앱에서 stop 버튼은 녹화 및 재생을 중지하는 데 사용됩니다. 앱 바 사용에 대한 자세한 내용은 Windows Phone의 앱 바를 참조하세요.

코드 숨김 파일을 준비하려면

  1. 기본 페이지의 코드 숨김 파일 MainPage.xaml.cs에서 앱에 다음 지시문을 추가합니다.

    // Directives
    using System.ComponentModel;
    using System.Threading;
    using System.IO;
    using System.IO.IsolatedStorage;
    using Microsoft.Phone.Shell;
    using System.Windows.Navigation;
    using Microsoft.Devices;
    
    
  2. MainPage.xaml.cs에서 MainPage 생성자 위에 다음 변수를 추가합니다.

    // Viewfinder for capturing video.
    private VideoBrush videoRecorderBrush;
    
    // Source and device for capturing video.
    private CaptureSource captureSource;
    private VideoCaptureDevice videoCaptureDevice;
    
    // File details for storing the recording.        
    private IsolatedStorageFileStream isoVideoFile;
    private FileSink fileSink;
    private string isoVideoFileName = "CameraMovie.mp4";
    
    // For managing button and application state.
    private enum ButtonState { Initialized, Ready, Recording, Playback, Paused, NoChange, CameraNotSupported };
    private ButtonState currentAppState;
    
    

    이 코드는 앱에서 나중에 사용하는 변수를 선언합니다.

  3. MainPage.xaml.cs에서 MainPage 생성자의 InitializeComponent에 대한 호출 바로 아래에 다음 코드를 추가합니다.

    // 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]);
    
    

    이 코드에서는 코드 내에서 참조될 수 있도록 앱 바 버튼이 지정됩니다. 앱 바에 대한 자세한 내용은 Windows Phone의 앱 바를 참조하세요.

  4. MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);
    
        // Initialize the video recorder.
        InitializeVideoRecorder();
    }
    
    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        // Dispose of camera and media objects.
        DisposeVideoPlayer();
        DisposeVideoRecorder();
    
        base.OnNavigatedFrom(e);
    }
    

    앱을 벗어나서 페이지를 탐색할 때는 카메라 관련 개체 및 이벤트 처리기를 삭제해야 합니다. 그러면 앱이 사용되고 있지 않을 때 메모리를 비우는 데 도움이 됩니다. 페이지를 탐색할 때마다 녹화 동작 작업자 스레드 및 카메라 개체가 실행되고 있지 않으면 이를 시작해야 합니다.

코드의 가독성을 높이기 위해 앱의 다양한 상태를 통해 앱 바 버튼의 화면 표시를 관리하는 열거형 및 메서드가 사용됩니다. UpdateUI 메서드도 txtDebug를 업데이트합니다. UI 업데이트를 단일 메서드 호출로 추출하면 앱의 다른 부분에 코드가 덜 필요합니다.

UI를 업데이트하려면

  • 기본 페이지의 코드 숨김 파일 MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    // 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;
        });
    }
    
    

    이 코드는 앱 바 버튼 및 앱 상태를 업데이트합니다. 이 코드는 UI 스레드에서 문을 실행할 수 있도록 BeginInvoke 메서드를 사용합니다. 코드를 더 단순화하기 위해 앱 상태를 지정하는 ButtonState라는 열거형이 사용됩니다.

이 섹션에서는 CaptureSourceFileSink 개체를 초기화하고 앱 시작 방법을 설명하는 메시지를 표시합니다.

카메라를 초기화하려면

  • 기본 페이지의 코드 숨김 파일 MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    public void InitializeVideoRecorder()
    {
        if (captureSource == null)
        {
            // Create the VideoRecorder objects.
            captureSource = new CaptureSource();
            fileSink = new FileSink();
    
            videoCaptureDevice = CaptureDeviceConfiguration.GetDefaultVideoCaptureDevice();
    
            // Add eventhandlers for captureSource.
            captureSource.CaptureFailed += new EventHandler<ExceptionRoutedEventArgs>(OnCaptureFailed);
    
            // Initialize the camera if it exists on the phone.
            if (videoCaptureDevice != null)
            {
                // Create the VideoBrush for the viewfinder.
                videoRecorderBrush = new VideoBrush();
                videoRecorderBrush.SetSource(captureSource);
    
                // Display the viewfinder image on the rectangle.
                viewfinderRectangle.Fill = videoRecorderBrush;
    
                // Start video capture and display it on the viewfinder.
                captureSource.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.");
            }
        }
    }
    
    

    이 코드는 앱이 탐색될 때마다 여러 작업을 수행합니다. fileSink가 만들어지더라도 사용자가 동영상을 녹화하기 전에는 captureSource에 연결되지 않습니다. 그때까지 로컬 폴더에 동영상이 저장되지 않습니다.

    정적 메서드 GetDefaultVideoCaptureDevicecaptureSource를 휴대폰의 기본 카메라에 연결합니다. 카메라 뷰파인더를 제공하기 위해 captureSourceviewfinderRectangle을 채우는 데 사용되는 VideoBrush의 소스로 설정됩니다. 동영상 이미지가 뷰파인드에 표시되려면 captureSource가 시작되어야 합니다.

    팁팁:

    휴대폰이 다중 카메라를 지원하지 않으면 GetAvailableVideoCaptureDevices 메서드를 사용하여 동영상 캡처 휴대폰 컬렉션을 가져옵니다. 예를 들어 일부 휴대폰에는 전면 카메라가 있고 휴대폰 뒷면에 다른 카메라가 있을 수 있습니다. 또는 휴대폰에 카메라가 없는 경우도 있습니다. 이 경우 CameraNotSupported 버튼 상태를 사용하여 앱 바 버튼을 사용하지 않도록 설정합니다.

이 섹션에서는 카메라 상태를 미리 보기와 녹화 간에 변경하는 코드를 추가합니다. 이 항목 컨텍스트에서는 동영상 녹화가 카메라에서 로컬 폴더의 파일에 동영상을 스트리밍하는 것을 의미합니다. 이를 위해서는 fileSinkcaptureSource에 연결한 다음 동영상 파일에서 지속되도록 할 시간 동안 captureSource를 실행합니다. captureSource가 실행되고 있지 않거나 fileSinkcaptureSource에 연결되어 있지 않으면 동영상은 로컬 폴더의 파일에 스트리밍되지 않습니다.

미리 보기와 녹화 간에 카메라 상태를 전환하려면

  • MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    // Set recording state: start recording.
    private void StartVideoRecording()
    {
        try
        {
            // Connect fileSink to captureSource.
            if (captureSource.VideoCaptureDevice != null
                && captureSource.State == CaptureState.Started)
            {
                captureSource.Stop();
    
                // Connect the input and output of fileSink.
                fileSink.CaptureSource = captureSource;
                fileSink.IsolatedStorageFileName = isoVideoFileName;
            }
    
            // Begin recording.
            if (captureSource.VideoCaptureDevice != null
                && captureSource.State == CaptureState.Stopped)
            {
                captureSource.Start();
            }
    
            // Set the button states and the message.
            UpdateUI(ButtonState.Recording, "Recording...");
        }
    
        // 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 (captureSource.VideoCaptureDevice != null
            && captureSource.State == CaptureState.Started)
            {
                captureSource.Stop();
    
                // Disconnect fileSink.
                fileSink.CaptureSource = null;
                fileSink.IsolatedStorageFileName = null;
    
                // Set the button states and the message.
                UpdateUI(ButtonState.NoChange, "Preparing viewfinder...");
    
                StartVideoPreview();
            }
        }
        // If stop fails, display an error.
        catch (Exception e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = "ERROR: " + e.Message.ToString();
            });
        }
    }
    
    // Set the recording state: display the video on the viewfinder.
    private void StartVideoPreview()
    {
        try
        {
            // Display the video on the viewfinder.
            if (captureSource.VideoCaptureDevice != null
            && captureSource.State == CaptureState.Stopped)
            {
                // Add captureSource to videoBrush.
                videoRecorderBrush.SetSource(captureSource);
    
                // Add videoBrush to the visual tree.
                viewfinderRectangle.Fill = videoRecorderBrush;
    
                captureSource.Start();
    
                // Set the button states and the message.
                UpdateUI(ButtonState.Ready, "Ready to record.");
            }
        }
        // If preview fails, display an error.
        catch (Exception e)
        {
            this.Dispatcher.BeginInvoke(delegate()
            {
                txtDebug.Text = "ERROR: " + e.Message.ToString();
            });
        }
    }
    

    이 코드는 카메라의 녹화 상태를 변경합니다. StartVideoRecording 메서드는 captureSource를 중지하고 fileSink를 카메라 및 로컬 폴더에 연결한 다음 captureSource를 다시 시작합니다. StopVideoRecording 메서드는 captureSource를 중지하고 카메라 및 로컬 폴더에서 fileSink를 분리합니다. StartVideoPreview 메서드는 captureSource를 뷰파인더에 다시 연결한 다음 이를 시작합니다.

이 섹션에서는 4개 앱 바 버튼, record, stop, playpause에 대한 코드를 추가합니다. 두 번 탭으로 이러한 메서드를 중복 호출하지 않기 위해 각 메서드는 해당 버튼을 즉시 사용하지 않도록 설정합니다.

한 번에 하나의 동영상 스트림만 앱 UI에 표시할 수 있습니다. 동영상 재생에 앞서 동영상 미리 보기 컨트롤이 시각적 트리에서 제거되고, 동영상 미리 보기에 앞서 그 반대 작업이 수행됩니다. 제거는 이 항목의 뒷부분에서 만들 메서드인 DisposeVideoPlayerDisposeVideoRecorder에 의해 수행됩니다.

버튼 탭을 처리하려면

  • MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    // Start the video recording.
    private void StartRecording_Click(object sender, EventArgs e)
    {
        // Avoid duplicate taps.
        StartRecording.IsEnabled = false;
    
        StartVideoRecording();
    }
    
    // Handle stop requests.
    private void StopPlaybackRecording_Click(object sender, EventArgs e)
    {
        // Avoid duplicate taps.
        StopPlaybackRecording.IsEnabled = false;
    
        // Stop during video recording.
        if (currentAppState == ButtonState.Recording)
        {
            StopVideoRecording();
    
            // Set the button state and the message.
            UpdateUI(ButtonState.NoChange, "Recording stopped.");
        }
    
        // Stop during video playback.
        else
        {
            // Remove playback objects.
            DisposeVideoPlayer();
    
            StartVideoPreview();
    
            // Set the button state and the message.
            UpdateUI(ButtonState.NoChange, "Playback stopped.");
        }
    }
    
    // Start video playback.
    private void StartPlayback_Click(object sender, EventArgs e)
    {
        // Avoid duplicate taps.
        StartPlayback.IsEnabled = false;
    
        // Start video playback when the file stream exists.
        if (isoVideoFile != null)
        {
            VideoPlayer.Play();
        }
        // Start the video for the first time.
        else
        {
            // Stop the capture source.
            captureSource.Stop();
    
            // Remove VideoBrush from the tree.
            viewfinderRectangle.Fill = null;
    
            // Create the file stream and attach it to the MediaElement.
            isoVideoFile = new IsolatedStorageFileStream(isoVideoFileName,
                                    FileMode.Open, FileAccess.Read,
                                    IsolatedStorageFile.GetUserStoreForApplication());
    
            VideoPlayer.SetSource(isoVideoFile);
    
            // Add an event handler for the end of playback.
            VideoPlayer.MediaEnded += new RoutedEventHandler(VideoPlayerMediaEnded);
    
            // Start video playback.
            VideoPlayer.Play();
        }
    
        // Set the button state and the message.
        UpdateUI(ButtonState.Playback, "Playback started.");
    }
    
    // Pause video playback.
    private void PausePlayback_Click(object sender, EventArgs e)
    {
        // Avoid duplicate taps.
        PausePlayback.IsEnabled = false;
    
        // If mediaElement exists, pause playback.
        if (VideoPlayer != null)
        {
            VideoPlayer.Pause();
        }
    
        // Set the button state and the message.
        UpdateUI(ButtonState.Paused, "Playback paused.");
    }
    
    
    

    이 코드는 앱 바의 버튼 탭을 처리합니다. StartRecording_Click 메서드는 StartVideoRecording 메서드를 호출하여 녹화를 시작합니다.

    StopPlaybackRecording_Click 메서드는 앱 상태에 따라 동영상 녹화 또는 동영상 재생을 중지합니다. 동영상을 녹화하는 동안 이 메서드는 StopVideoRecording 메서드를 호출하여 captureSource에서 fileSink를 분리합니다. 동영상을 재생하는 동안 이 메서드는 동영상 재생 개체를 삭제하고 StartVideoPreview 메서드를 호출하여 뷰파인더에 동영상을 표시합니다.

    StartPlayback_Click메서드는 captureSource를 중지하고 VideoPlayer MediaElement 컨트롤을 로컬 폴더 CameraMovie.mp4의 동영상 파일에 연결합니다. VideoPlayerPlay 메서드가 호출되면 동영상이 화면에 표시됩니다. 동영상 재생이 끝나면 MediaEnded 이벤트에 대한 이벤트 처리기가 앱이 미리 보기 상태로 되돌아갔는지 확인합니다.

이 섹션에서는 동영상 재생 및 동영상 녹화 개체를 삭제하는 코드를 추가합니다. 한 번에 하나의 동영상 스트림만 앱 UI에서 실행할 수 있습니다. 이러한 메서드는 다른 스트림을 시작할 수 있도록 한 스트림을 중지하는 데 사용되며, 해당 개체에 대한 이벤트 처리기를 제거하여 이 메서드가 사용되지 않을 때 메모리를 비우는 데 도움을 주기도 합니다.

녹화 및 재생 개체를 삭제하려면

  • MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    private void DisposeVideoPlayer()
    {
        if (VideoPlayer != null)
        {
            // Stop the VideoPlayer MediaElement.
            VideoPlayer.Stop();
    
            // Remove playback objects.
            VideoPlayer.Source = null;
            isoVideoFile = null;
    
            // Remove the event handler.
            VideoPlayer.MediaEnded -= VideoPlayerMediaEnded;
        }
    }
    
    private void DisposeVideoRecorder()
    {
        if (captureSource != null)
        {
            // Stop captureSource if it is running.
            if (captureSource.VideoCaptureDevice != null
                && captureSource.State == CaptureState.Started)
            {
                captureSource.Stop();
            }
    
            // Remove the event handler for captureSource.
            captureSource.CaptureFailed -= OnCaptureFailed;
    
            // Remove the video recording objects.
            captureSource = null;
            videoCaptureDevice = null;
            fileSink = null;
            videoRecorderBrush = null;
        }
    }
    
    

    이러한 개체는 Dispose 메서드를 구현하지 않지만 null로 설정할 경우 가비지 수집기가 이 개체에서 사용하는 메모리를 필요할 때 회수할 수 있습니다.

이 섹션에서는 나머지 코드를 추가하고 앱을 시작합니다.

앱을 완료하려면

  1. MainPage.xaml.cs에서 MainPage 클래스에 다음 코드를 추가합니다.

    // If recording fails, display an error message.
    private void OnCaptureFailed(object sender, ExceptionRoutedEventArgs e)
    {
        this.Dispatcher.BeginInvoke(delegate()
        {
            txtDebug.Text = "ERROR: " + e.ErrorException.Message.ToString();
        });
    }
    
    // Display the viewfinder when playback ends.
    public void VideoPlayerMediaEnded(object sender, RoutedEventArgs e)
    {
        // Remove the playback objects.
        DisposeVideoPlayer();
    
        StartVideoPreview();
    }
    
    

    이 코드는 CaptureSource에서 CaptureFailed 이벤트를 처리하고 MediaPlayer 개체에서 MediaEnded 이벤트를 처리합니다.

  2. 이제 앱을 완료했습니다. F5 키를 눌러 디버깅을 시작하고 앱을 테스트합니다.

표시:
© 2014 Microsoft