How to trim a video file (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 ]

The MediaTranscoder object can be used to trim a media file.

In this example, two edit points are set, a start point and an end point. These edit points specify the start and end points of the output video. The MediaTranscoder object outputs a file with the same encoding profile as the source file, but trims the video at the two edit points.

This how-to describes how to use the FileOpenPicker class to open a video file from the system, the MediaTranscoder class to trim the file, and finally the FileSavePicker class to save the newly encoded file.

For another example of transcoding in a Windows Runtime app using C++, C#, or Visual Basic, see the Transcoding media sample.

Prerequisites

This topic assumes that you can 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.

Instructions

Step 1: Create new project

Start by creating a blank project in Microsoft Visual Studio.

Step 2: Select a source file and create a destination file

Use the FileOpenPicker class to select a source file and the FileSavePicker class to create the destination file. Set the SuggestedStartLocation and FileTypeFilter properties on the FileOpenPicker. On the FileSavePicker object, set the SuggestedStartLocation, DefaultFileExtension, SuggestedFileName, and FileTypeChoices properties. Note that this method calls a method called TrimFile. This is a user-defined method that performs the transcode operation. We will create this method in the next step.

Windows Phone Store app must use pickSingleFileAndContinue.

async void TrimVideoFile()
{
    Windows.Storage.StorageFile source;
    Windows.Storage.StorageFile destination;

    var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

    openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
    openPicker.FileTypeFilter.Add(".wmv");
    openPicker.FileTypeFilter.Add(".mp4");

    source = await openPicker.PickSingleFileAsync();

    var savePicker = new Windows.Storage.Pickers.FileSavePicker();

    savePicker.SuggestedStartLocation =
        Windows.Storage.Pickers.PickerLocationId.VideosLibrary;

    savePicker.DefaultFileExtension = ".mp4";
    savePicker.SuggestedFileName = "New Video";

    savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });

    destination = await savePicker.PickSaveFileAsync();

    // Method to perform the transcoding.
    TrimFile(source, destination);
}

Step 3: Initialize the MediaTranscoder

Create a MediaEncodingProfile object by calling MediaEncodingProfile.CreateMp4. Then, create a MediaTranscoder object and set the TrimStartTime property to 1 second and TrimStopTime property to 9 seconds.

MediaEncodingProfile profile =
    MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);

MediaTranscoder transcoder = new MediaTranscoder();

// Set the start of the trim.
transcoder.TrimStartTime = new TimeSpan(0, 0, 1);

// Set the end of the trim.
transcoder.TrimStopTime = new TimeSpan(0, 0, 9);

Step 4: Trim the File

To trim the file, call the aysnc method PrepareFileTranscodeAsync and then call the TranscodeAsync method on the PrepareTranscodeResult object.

Be aware that the code in this example calls a method name OutputText. This is a helper method created to output messages to the UI. The code for this method is defined at the end of this topic.

async void TrimFile(StorageFile srcFile, StorageFile destFile)
{
    MediaEncodingProfile profile =
        MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);

    MediaTranscoder transcoder = new MediaTranscoder();

    // Set the start of the trim.
    transcoder.TrimStartTime = new TimeSpan(0, 0, 1);

    // Set the end of the trim.
    transcoder.TrimStopTime = new TimeSpan(0, 0, 9);

    PrepareTranscodeResult prepareOp = await
        transcoder.PrepareFileTranscodeAsync(srcFile, destFile, profile);

    if (prepareOp.CanTranscode)
    {
        var transcodeOp = prepareOp.TranscodeAsync();
        transcodeOp.Progress +=
            new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed +=
            new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
    }
    else
    {
        switch (prepareOp.FailureReason)
        {
            case TranscodeFailureReason.CodecNotFound:
                OutputText("Codec not found.");
                break;
            case TranscodeFailureReason.InvalidProfile:
                OutputText("Invalid profile.");
                break;
            default:
                OutputText("Unknown failure.");
                break;
        }
    }
}

When you trim a media file, you don't have to specify an encoding profile in the PrepareFileTranscodeAsync method. If you omit the profile, the destination file has the same format as the input file.

Step 5: Output Progress to the UI

It can be useful to output progress and status information to the user interface.

    <StackPanel Background="{StaticResource ApplicationPageBackgroundBrush}">
        <TextBlock Name="txtDisplay" Text="Display"></TextBlock>
        <TextBlock Name="txtProgress" Text="Progress"></TextBlock>
    </StackPanel>
void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
    // Display or handle progress info.
}

void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
{
    asyncInfo.GetResults();
    if (asyncInfo.Status == AsyncStatus.Completed)
    {
        // Display or handle complete info.
    }
    else if (asyncInfo.Status == AsyncStatus.Canceled)
    {
        // Display or handle cancel info.
    }
    else
    {
        // Display or handle error info.
    }
}

Complete example

The following code sample shows the complete sequence of calls for a trimming operation.

First, here is the code to open and save the file.

async void TrimVideoFile()
{
    Windows.Storage.StorageFile source;
    Windows.Storage.StorageFile destination;

    var openPicker = new Windows.Storage.Pickers.FileOpenPicker();

    openPicker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.VideosLibrary;
    openPicker.FileTypeFilter.Add(".wmv");
    openPicker.FileTypeFilter.Add(".mp4");

    source = await openPicker.PickSingleFileAsync();

    var savePicker = new Windows.Storage.Pickers.FileSavePicker();

    savePicker.SuggestedStartLocation =
        Windows.Storage.Pickers.PickerLocationId.VideosLibrary;

    savePicker.DefaultFileExtension = ".mp4";
    savePicker.SuggestedFileName = "New Video";

    savePicker.FileTypeChoices.Add("MPEG4", new string[] { ".mp4" });

    destination = await savePicker.PickSaveFileAsync();

    // Method to perform the transcoding.
    TrimFile(source, destination);
}

Next, here is the code to transcode the file.

async void TrimFile(StorageFile srcFile, StorageFile destFile)
{
    MediaEncodingProfile profile =
        MediaEncodingProfile.CreateMp4(VideoEncodingQuality.HD720p);

    MediaTranscoder transcoder = new MediaTranscoder();

    // Set the start of the trim.
    transcoder.TrimStartTime = new TimeSpan(0, 0, 1);

    // Set the end of the trim.
    transcoder.TrimStopTime = new TimeSpan(0, 0, 9);

    PrepareTranscodeResult prepareOp = await
        transcoder.PrepareFileTranscodeAsync(srcFile, destFile, profile);

    if (prepareOp.CanTranscode)
    {
        var transcodeOp = prepareOp.TranscodeAsync();
        transcodeOp.Progress +=
            new AsyncActionProgressHandler<double>(TranscodeProgress);
        transcodeOp.Completed +=
            new AsyncActionWithProgressCompletedHandler<double>(TranscodeComplete);
    }
    else
    {
        switch (prepareOp.FailureReason)
        {
            case TranscodeFailureReason.CodecNotFound:
                OutputText("Codec not found.");
                break;
            case TranscodeFailureReason.InvalidProfile:
                OutputText("Invalid profile.");
                break;
            default:
                OutputText("Unknown failure.");
                break;
        }
    }
}

Next here is the code to handle the transcode progress, error, and completion.

void TranscodeProgress(IAsyncActionWithProgress<double> asyncInfo, double percent)
{
    // Display or handle progress info.
}

void TranscodeComplete(IAsyncActionWithProgress<double> asyncInfo, AsyncStatus status)
{
    asyncInfo.GetResults();
    if (asyncInfo.Status == AsyncStatus.Completed)
    {
        // Display or handle complete info.
    }
    else if (asyncInfo.Status == AsyncStatus.Canceled)
    {
        // Display or handle cancel info.
    }
    else
    {
        // Display or handle error info.
    }
}

Finally the UI objects for displaying progress and status messages.

    <StackPanel Background="{StaticResource ApplicationPageBackgroundBrush}">
        <TextBlock Name="txtDisplay" Text="Display"></TextBlock>
        <TextBlock Name="txtProgress" Text="Progress"></TextBlock>
    </StackPanel>

Roadmaps

Roadmap for Windows Runtime apps using C# and Visual Basic

Roadmap for Windows Runtime apps using C++

Designing UX for apps

Adding multimedia

Samples

Transcoding media sample

Media extension sample

Real-Time communication sample

Tasks

Quickstart: transcoding video files

Reference

Windows.Media

Windows.Media.MediaProperties

Windows.Media.Transcoding

MediaTranscoder

PrepareTranscodeResult

TranscodeAsync

Other resources

Supported audio and video formats

Optimize media resources