Windows Phone 用のカメラ アプリでビデオを記録する方法

2013/12/05

対象: Windows Phone 8 | Windows Phone OS 7.1

Windows Phone OS 7.1 以降では、プログラムによって電話のカメラにアクセスできます。写真のキャプチャに加えて、電話のカメラを使用してビデオをキャプチャすることができます。このトピックでは、ビデオ レコーダー アプリを作成する方法を説明し、Windows Phone アプリでビデオをキャプチャ、表示、および保存する方法を示します。電話のカメラで画像をキャプチャする方法については、「Windows Phone の基本カメラ アプリを作成する方法」を参照してください。

ヒントヒント:

このトピックでは、System.Windows.Media.CaptureSource クラスおよび FileSink クラスを使用してビデオを録画する方法について説明します。アプリで、このトピックで説明しているよりもさらに細かくカメラ センサーを制御する必要がある場合は、Windows.Phone.Media.Capture.AudioVideoCaptureDevice クラスを使用します。詳細については、「Windows.Phone.Media.Capture.AudioVideoCaptureDevice」を参照してください。

このトピックは、ビデオ レコーダーのサンプルに対応しています。

このトピックでは、次の手順について説明します。

  1. アプリと UI の作成

  2. UI の更新

  3. カメラを初期化する

  4. カメラ状態のプレビューと録画の切り替え

  5. ボタン タップの処理

  6. 録画オブジェクトと再生オブジェクトを破棄する

  7. アプリを完成させる

完成したアプリの例を次の図に示します。

AP_Con_CameraVideoHowTo

このアプリは、録画中に FileSink クラスを使用してビデオを CaptureSource オブジェクトから渡し、IsolatedStorageFileStream オブジェクトを通じて、分離ストレージに保存します。アプリにカメラのビューファインダーを提供するために、同じ CaptureSource が、VideoBrush コントロールのソースとしても使用されます。CaptureSourceFileSink に接続されているとき、または削除されているときは、実行できません。ビデオの録画は、CaptureSourceFileSink にアタッチされている状態で、CaptureSource が実行されたときに行われます。

録画されたビデオの再生の場合は、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. アプリが作成され、Visual Studio のデザイナー ウィンドウに MainPage.xaml が表示されます。

アプリの機能を指定するには

  1. カメラ アプリを作成するには、アプリのマニフェスト ファイルでカメラ機能を宣言する必要があります。ビデオ アプリはサウンドも録音するため、マイク機能を宣言する必要もあります。これらの機能を宣言しないと、アプリは機能しません。WMAppManifest.xml を開き、次の機能要素が存在していることを確認します。

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

    Windows Phone 8 アプリに背面のカメラが必要な場合は、ID_REQ_BACKCAMERA ハードウェア要件を使用します。これにより、背面カメラを持っていないユーザーがアプリをダウンロードできないようにします。機能の詳細については、「Windows Phone のアプリ機能とハードウェア要件」を参照してください。

    重要: 重要:

    CaptureSource クラスを使用する Windows Phone OS 7.1 アプリでは、Microsoft.Devices.CameraMicrosoft.Devices.PhotoCamera、または Microsoft.Xna.Framework.Audio.Microphone クラスを使用して、オーディオ キャプチャと正確な機能の検出を有効にする必要もあります。

    この特定のアプリではこれらのクラスは必要ではありませんが、Windows Phone OS 7.1 アプリは、Windows Phone Store 機能の検出プロセスをプロンプト表示し、取得時に 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 のアプリ機能とハードウェア要件」を参照してください。

アプリで使用するアイコンを追加するには

  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 の基本カメラ アプリを作成する方法」を参照してください。

  2. MainPage.xaml で、次のコードを使用して LayoutRoot という名前の Grid を置き換えます。

        <!--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 という名前の RectangleVideoPlayer という名前の 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>
    
    

    このコードは、recordstopplay、および pause の 4 つのボタンを持つアプリ バーを指定します。このアプリでは、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;
        });
    }
    
    

    このコードは、アプリ バーのボタンおよびアプリの状態を更新します。このコードは、BeginInvoke メソッドを呼び出して、UI スレッドでステートメントを実行できるようにします。コードをさらに簡略化するために、ButtonState という名前の列挙を使用して、アプリの状態を指定します。

このセクションでは、CaptureSource オブジェクトと FileSink オブジェクトを初期化し、アプリの操作方法を示すメッセージを表示します。

カメラを初期化するには

  • メイン ページの分離コード ファイル 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 には接続されません。それまで、ビデオはローカル フォルダーに保存されません。

    静的メソッド GetDefaultVideoCaptureDevice は、captureSource を電話のメイン カメラに接続します。カメラのビューファインダーを提供するために、captureSource が、viewfinderRectangle を描画する 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 をビューファインダーに再接続してから captureSource を開始します。

このセクションでは、アプリ バーのボタン ([record]、[stop]、[play]、および [pause]) 用のコードを追加します。ダブルタップによって、これらのメソッドの呼び出しが重複することを回避するために、各メソッドは直ちに対応するボタンを無効にします。

アプリの UI に表示できるビデオ ストリームは一度に 1 つだけです。ビデオ再生の前に、ビデオ プレビュー コントロールがビジュアル ツリーから削除されます。ビデオ プレビューの前には、ビデオ再生コントロールが削除されます。削除は、後で作成する DisposeVideoPlayer メソッドおよび DisposeVideoRecorder メソッドによって実行されます。

ボタンのタップを処理するには

  • 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 で実行できるビデオ ストリームは一度に 1 つだけです。これらのメソッドを使用して、1 つのストリームを停止して、他のストリームを開始できます。また、対応するオブジェクトのイベント ハンドラーも削除され、使用されていないメモリを解放できます。

録画オブジェクトと再生オブジェクトを破棄するには

  • 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