Quickstart: recording the screen with ScreenCapture (XAML)

[ This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation ]

You can capture the audio and video playing on the device by using the ScreenCapture object and the Windows.Media.Capture API. Note that before the screen can be recorded, the user must give your app permission. Also, recording will be disabled while protected content is displayed.

Important  The ScreenCapture feature is only supported for mobile devices running Windows 8.1. This API is not supported on Windows 10.

 

Roadmap: How does this topic relate to others? See:

Note  You can't use ScreenCapture to record the screen and transcode media files at the same time. For information on transcoding media, see Transcoding.

 

Prerequisites

This topic assumes that you know how to create a basic Windows Runtime app using C++, C#, or Visual Basic. For help creating your first app, see Create your first Windows Store app using C# or Visual Basic.

Set the device capability in the app manifest

To enable webcam access, the app must include the Webcam and the **MicrophoneDeviceCapability in the application manifest.

  1. In Microsoft Visual Studio, in Solution Explorer, open the designer for the application manifest by double-clicking the package.appxmanifest item
  2. Click Capabilities.
  3. Check the box for Webcam and the box for Microphone.

Get an instance of the ScreenCapture class

Get an instance of the ScreenCapture class by calling GetForCurrentView.

// Get instance of the ScreenCapture object
var screenCapture = Windows.Media.Capture.ScreenCapture.GetForCurrentView();

Initialize the MediaCaptureInitializationSettings

Create a new instance of the MediaCaptureInitializationSettings class and set the audio and video source to the AudioSource and VideoSource properties of the ScreenCapture object.

// Set the MediaCaptureInitializationSettings to use the ScreenCapture as the
// audio and video source.
var mcis = new Windows.Media.Capture.MediaCaptureInitializationSettings();
mcis.VideoSource = screenCapture.VideoSource;
mcis.AudioSource = screenCapture.AudioSource;
mcis.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.AudioAndVideo;

Initialize the MediaCapture object

Create a new instance of the MediaCapture object using the MediaCaptureInitializationSettings. Set event handlers for the Failed, RecordLimitationExceeded, and the SourceSuspensionChanged events.

// Initialize the MediaCapture with the initialization settings.
_mediaCapture = new MediaCapture();
await _mediaCapture.InitializeAsync(mcis);

// Set the MediaCapture to a variable in App.xaml.cs to handle suspension.
(App.Current as App).MediaCapture = _mediaCapture;

// Hook up events for the Failed, RecordingLimitationExceeded, and SourceSuspensionChanged events
_mediaCapture.Failed += new Windows.Media.Capture.MediaCaptureFailedEventHandler(RecordingFailed);
_mediaCapture.RecordLimitationExceeded += 
    new Windows.Media.Capture.RecordLimitationExceededEventHandler(RecordingReachedLimit);
screenCapture.SourceSuspensionChanged += 
    new Windows.Foundation.TypedEventHandler<ScreenCapture, SourceSuspensionChangedEventArgs>(SourceSuspensionChanged);

Start recording

Create a new file to which the captured media will be saved and create an encoding profile. Call StartRecordToStorageFileAsync to start recording. The first time your app starts recording, the system will ask the user if they want to allow your app to record the screen. If the user declines, an exception will be thrown.

// Create a file to record to.                 
var videoFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("recording.mp4", CreationCollisionOption.ReplaceExisting);

// Create an encoding profile to use.                  
var profile = Windows.Media.MediaProperties.MediaEncodingProfile.CreateMp4(Windows.Media.MediaProperties.VideoEncodingQuality.HD1080p);

// Start recording
               await _mediaCapture.StartRecordToStorageFileAsync(profile, videoFile);
_recordingStatus = RecordingStatus.recording;


// Set a tracking variable for recording state in App.xaml.cs
(App.Current as App).IsRecording = true;

The entire StartRecording method

This example shows the entire StartRecording method that was defined in the previous steps.

private async void StartRecording()
{

    try
    {
        // Get instance of the ScreenCapture object
        var screenCapture = Windows.Media.Capture.ScreenCapture.GetForCurrentView();

        // Set the MediaCaptureInitializationSettings to use the ScreenCapture as the
        // audio and video source.
        var mcis = new Windows.Media.Capture.MediaCaptureInitializationSettings();
        mcis.VideoSource = screenCapture.VideoSource;
        mcis.AudioSource = screenCapture.AudioSource;
        mcis.StreamingCaptureMode = Windows.Media.Capture.StreamingCaptureMode.AudioAndVideo;

        // Initialize the MediaCapture with the initialization settings.
        _mediaCapture = new MediaCapture();
        await _mediaCapture.InitializeAsync(mcis);

        // Set the MediaCapture to a variable in App.xaml.cs to handle suspension.
        (App.Current as App).MediaCapture = _mediaCapture;

        // Hook up events for the Failed, RecordingLimitationExceeded, and SourceSuspensionChanged events
        _mediaCapture.Failed += new Windows.Media.Capture.MediaCaptureFailedEventHandler(RecordingFailed);
        _mediaCapture.RecordLimitationExceeded += 
            new Windows.Media.Capture.RecordLimitationExceededEventHandler(RecordingReachedLimit);
        screenCapture.SourceSuspensionChanged += 
            new Windows.Foundation.TypedEventHandler<ScreenCapture, SourceSuspensionChangedEventArgs>(SourceSuspensionChanged);

        // Create a file to record to.                 
        var videoFile = await ApplicationData.Current.LocalFolder.CreateFileAsync("recording.mp4", CreationCollisionOption.ReplaceExisting);

        // Create an encoding profile to use.                  
        var profile = Windows.Media.MediaProperties.MediaEncodingProfile.CreateMp4(Windows.Media.MediaProperties.VideoEncodingQuality.HD1080p);

        // Start recording
       await _mediaCapture.StartRecordToStorageFileAsync(profile, videoFile);
        _recordingStatus = RecordingStatus.recording;


        // Set a tracking variable for recording state in App.xaml.cs
        (App.Current as App).IsRecording = true;

    }
    catch (Exception ex)
    {
        NotifyUser("StartRecord Exception: " + ex.Message, NotifyType.ErrorMessage);
    }
}

Stop recording

When you're ready to stop recording, call StopRecordAsync.

private void StopRecording()
{
 
    try
    {
        //Stop Screen Recorder                  
        var stop_action = _mediaCapture.StopRecordAsync();
        stop_action.Completed += CompletedStop;

        // Set a tracking variable for recording state in App.xaml.cs
        (App.Current as App).IsRecording = false;

    }
    catch (Exception ex)
    {
        NotifyUser("StopRecord Exception: " + ex.Message, NotifyType.ErrorMessage);
    }
}

Handling SourceSuspensionChanged

The SourceSuspensionChanged event is raised when sensitive content appears that the system blocks from being recording and when the content goes away, allowing recording to resume. Audio and video may be blocked independently. For example, if background audio is playing, then audio will be blocked but video will still be recorded.

Examples of conditions that would cause recording to be blocked include:

  • An incoming phone call. Both audio and video are blocked.
  • Shell toasts, including email or messaging arrival and app notifications.
  • Background audio is playing. Only audio is blocked.
  • Audio or video content that is protected by DRM is playing, even if the recording app is playing the content.
  • The application is not in the foreground.

In the SourceSuspensionChanged handler, check the IsAudioSuspended and IsVideoSuspended properties to determine if audio, video, or both are currently blocked. You are not required to do anything in the handler for this event. The system will automatically resume recording when the protected content is no longer visible. You may choose to update your UI to inform the user that video or audio recording is blocked, or you may want to allow the user to redo the video capture.

private void SourceSuspensionChanged(ScreenCapture sender, SourceSuspensionChangedEventArgs args)
{
    NotifyUser("SourceSuspensionChanged Event. Args: IsAudioSuspended:" + 
        args.IsAudioSuspended.ToString() + 
        " IsVideoSuspended:" + 
        args.IsVideoSuspended.ToString(),
        NotifyType.ErrorMessage);
}

Cleaning up MediaCapture resources properly

Warning  It is extremely important that you properly shut down and dispose of the MediaCapture object and related objects when your app is suspended. Failure to do so could interfere with other apps accessing the device's camera which will result in a negative user experience for your app.

 

You should cleanup media capture resources when your app is suspended. In order to do this, your App class will need to access your MediaCapture object and its current state. A good way to do this is to declare some public properties in your app.xaml.cs file to store the MediaCapture object and a boolean that indicates whether the app is currently recording video.

public MediaCapture MediaCapture{get; set;}
public bool IsRecording{get; set;}

Create a function in App.xaml.cs that stops recording if it is in progress and then calls Dispose on your MediaCapture object.

public async Task CleanupCaptureResources()
{
    if (IsRecording && MediaCapture != null)
    {
        await MediaCapture.StopRecordAsync();
        IsRecording = false;
    }

    if (MediaCapture != null)
    {
        MediaCapture.Dispose();
    }
}

Finally, add the following code to your OnSuspending event handler. It is very important that you get a deferral before calling your cleanup method. This ensures that the system lets the method complete before suspending your app.

private async void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.SuspendingOperation.GetDeferral();

    //cleanup camera resources
    await CleanupCaptureResources();

    deferral.Complete();
}

Summary and next steps

This topic has given you an overview of capturing audio and video using the ScreenCapture object.