メディア ファイルのコード変換

Windows.Media.Transcoding API を使用して、ビデオ ファイルをある形式から別の形式にコード変換できます。

コード変換とは、デジタル メディア ファイル (ビデオ ファイルやオーディオ ファイル) の形式を別の形式に変換することです。 これは通常、ファイルをデコードして再エンコードすることで行われます。 たとえば、Windows Media ファイルを MP4 に変換して、MP4 形式をサポートするポータブル デバイスで再生できます。 または、高解像度のビデオ ファイルを低解像度に変換することもできます。 その場合、再エンコードされたファイルは元のファイルと同じコーデックを使用する可能性がありますが、エンコード プロファイルは異なります。

コード変換用にプロジェクトを設定する

既定のプロジェクト テンプレートによって参照される名前空間に加えて、この記事のコードを使用してメディア ファイルのコード変換をするには、これらの名前空間を参照する必要があります。

using Windows.Storage;
using Windows.Media.MediaProperties;
using Windows.Media.Transcoding;

ソースと変換先のファイルの選択

アプリでコード変換のソースと変換先ファイルを決定する方法は、実装によって異なります。 この例では、FileOpenPickerFileSavePicker を使用して、ユーザーがソースと変換先ファイルを選択できるようにします。

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

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

StorageFile 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" });

StorageFile destination = await savePicker.PickSaveFileAsync();

メディア エンコード プロファイルを作成する

エンコード プロファイルには、変換先ファイルのエンコード方法を決定する設定が含まれています。 これは、ファイルのコード変換をするときに最も多くのオプションがある場所です。

MediaEncodingProfile クラスには、定義済みのエンコード プロファイルを作成するための静的メソッドが用意されています:

オーディオのみのエンコード プロファイルを作成する方法

メソッド プロファイル
CreateAlac Apple Lossless Audio Codec (ALAC) オーディオ
CreateFlac Free Lossless Audio Codec (FLAC) オーディオ。
CreateM4a AAC オーディオ (M4A)
CreateMp3 MP3 オーディオ
CreateWav WAV オーディオ
CreateWmv Windows Media Audio (WMA)

オーディオ/ビデオ エンコード プロファイルを作成するためのメソッド

メソッド プロファイル
CreateAvi AVI
CreateHevc H.265 ビデオとも呼ばれる高効率ビデオ コーディング (HEVC) ビデオ
CreateMp4 MP4 ビデオ (H.264 ビデオと AAC オーディオ)
CreateWmv Windows Media Video (WMV)

次のコードでは、MP4 ビデオのプロファイルを作成します。

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

静的 CreateMp4 メソッドは、MP4 エンコード プロファイルを作成します。 このメソッドのパラメーターは、ビデオのターゲット解像度を指定します。 この場合、VideoEncodingQuality.hd720p は、1 秒あたり 30 フレームで 1280 x 720 ピクセルを意味します。 ("720p" は、プログレッシブ スキャン方式で 1 フレームあたり 720 本を処理することを表します)。あらかじめ定義されたプロファイルを作るその他のメソッドは、すべてこのパターンに従います。

または、MediaEncodingProfile.CreateFromFileAsync メソッドを使用して、既存のメディア ファイルと一致するプロファイルを作成することもできます。 または、必要な正確なエンコード設定がわかっている場合は、新しい MediaEncodingProfile オブジェクトを作成し、プロファイルの詳細を入力します。

ファイルのコード変換

ファイルのコード変換をするには、新しい MediaTranscoder オブジェクトを作成し、MediaTranscoder.PrepareFileTranscodeAsync メソッドを呼び出します。 ソース ファイル、宛先ファイル、およびエンコード プロファイルを渡します。 次に、非同期トランスコード操作から返された PrepareTranscodeResult オブジェクトで、TranscodeAsync メソッドを呼び出します。

MediaTranscoder transcoder = new MediaTranscoder();

PrepareTranscodeResult prepareOp = await
    transcoder.PrepareFileTranscodeAsync(source, destination, 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:
            System.Diagnostics.Debug.WriteLine("Codec not found.");
            break;
        case TranscodeFailureReason.InvalidProfile:
            System.Diagnostics.Debug.WriteLine("Invalid profile.");
            break;
        default:
            System.Diagnostics.Debug.WriteLine("Unknown failure.");
            break;
    }
}

コード変換の進行状況に対応する

非同期 TranscodeAsync の進行状況が変化したときに応答するイベントを登録できます。 これらのイベントは、ユニバーサル Windows プラットフォーム (UWP) アプリの非同期プログラミング フレームワークの一部であり、コード変換 API に固有ではありません。

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.
    }
}