次の方法で共有


WinUI 3 アプリで MediaCapture を使用した基本的な写真、ビデオ、オーディオのキャプチャ

この記事では、 MediaCapture クラスを使用して写真やビデオをキャプチャする最も簡単な方法を示します。 MediaCapture クラスは、キャプチャ パイプラインを低レベルで制御し、高度なキャプチャ シナリオを有効にする堅牢な API のセットを公開しますが、この記事は、基本的なメディア キャプチャをアプリに迅速かつ簡単に追加することを目的としています。 MediaCapture で提供される機能の詳細については、「カメラ」を参照してください。

MediaCapture オブジェクトを初期化する

この記事で説明するすべてのキャプチャ メソッドには、 MediaCapture オブジェクトを初期化する最初の手順が必要です。 これには、オブジェクトのインスタンス化、キャプチャ デバイスの選択、初期化パラメーターの設定、 InitializeAsync の呼び出しが含まれます。 通常、カメラ アプリでは 、MediaPlayerElement を使用して UI で写真やビデオをキャプチャするときに、カメラ プレビューが表示されます。 MediaCapture の初期化と XAML UI でのプレビューの表示のチュートリアルについては、「WinUI アプリでカメラのプレビューを表示する」を参照してください。 この記事のコード例では、 MediaCapture の初期化されたインスタンスが既に作成されていることを前提としています。

SoftwareBitmap に写真をキャプチャする

SoftwareBitmap クラスは、複数の機能にわたる画像の一般的な表現を提供します。 写真をキャプチャし、キャプチャした画像をファイルにキャプチャするのではなく、XAML で表示するなど、アプリですぐに使用する場合 は、SoftwareBitmap にキャプチャする必要があります。 後でイメージをディスクに保存することもできます。

LowLagPhotoCapture クラスを使用して SoftwareBitmap に写真をキャプチャします。 PrepareLowLagPhotoCaptureAsync を呼び出し、目的のイメージ形式を指定する ImageEncodingProperties オブジェクトを渡して、このクラスのインスタンスを取得します。 CreateUncompressed は、 指定されたピクセル形式で非圧縮エンコードを作成します。 CaptureAsync を呼び出して写真のキャプチャを開始します。CaptureedPhoto オブジェクトを返します。 Frame プロパティと SoftwareBitmap プロパティにアクセスして、SoftwareBitmap を取得します。

CaptureAsync を繰り返し呼び出すことで、複数の写真をキャプチャできます。 キャプチャが完了したら、 FinishAsync を呼び出して LowLagPhotoCapture セッションをシャットダウンし、関連付けられているリソースを解放します。 FinishAsync を呼び出した後、写真のキャプチャを再度開始するには、CaptureAsync を呼び出す前に、PrepareLowLagPhotoCaptureAsync をもう一度呼び出してキャプチャ セッションを再初期化する必要があります。

// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));

var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;

// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();

メモリ ストリームに写真をキャプチャする

MediaCapture を使用すると、メモリ内ストリームに写真をキャプチャできます。このストリームからディスク上のファイルに写真をトランスコードするために使用できます。

InMemoryRandomAccessStream を作成し、CapturePhotoToStreamAsync を呼び出してストリームに写真をキャプチャし、ストリームと、使用する画像形式を指定する ImageEncodingProperties オブジェクトを渡します。 オブジェクトを自分で初期化することでカスタム エンコード プロパティを作成できますが、クラスには、一般的なエンコード形式の ImageEncodingProperties.CreateJpeg などの静的メソッドが用意されています。

メモリ内ストリームからイメージをデコードする BitmapDecoder を作成します。 CreateForTranscodingAsync を呼び出して、イメージをファイルにエンコードする BitmapEncoder を作成します。

必要に応じて BitmapPropertySet オブジェクトを作成し、イメージ エンコーダーで SetPropertiesAsync を呼び出して、画像ファイルに写真に関するメタデータを含めることができます。 エンコード プロパティの詳細については、「 イメージ メタデータ」を参照してください。

最後に、エンコーダー オブジェクトで FlushAsync を呼び出して、メモリ内ストリームからファイルに写真をトランスコードします。

// Prepare and capture photo
var lowLagCapture = await m_mediaCapture.PrepareLowLagPhotoCaptureAsync(ImageEncodingProperties.CreateUncompressed(MediaPixelFormat.Bgra8));

var capturedPhoto = await lowLagCapture.CaptureAsync();
var softwareBitmap = capturedPhoto.Frame.SoftwareBitmap;

// Capture more photos, if desired.
// Then call FinishAsync to clean up resources
await lowLagCapture.FinishAsync();

ビデオをキャプチャする

LowLagMediaRecording クラスを使用して、ビデオ キャプチャをすばやくアプリに追加します。

まず、ビデオのキャプチャ中に LowLagMediaRecording を 永続化する必要があるため、オブジェクトのクラス変数を宣言します。

LowLagMediaRecording m_mediaRecording;

PrepareLowLagRecordToStorageFileAsync を呼び出してメディア記録を初期化し、ストレージ ファイルと、ビデオのエンコードを指定する MediaEncodingProfile オブジェクトを渡します。 このクラスには、一般的なビデオ エンコード プロファイルを作成するための 静的メソッド (CreateMp4 など) が用意されています。 StartAsync を呼び出してビデオのキャプチャを開始します。

var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("video.mp4", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
        MediaEncodingProfile.CreateMp4(VideoEncodingQuality.Auto), file);

m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;
await m_mediaRecording.StartAsync();

ビデオの録画を停止するには、 StopAsync を呼び出します。

await m_mediaRecording.StopAsync();

引き続き StartAsyncStopAsync を呼び出して、追加のビデオをキャプチャできます。 ビデオのキャプチャが完了したら、 FinishAsync を呼び出してキャプチャ セッションを破棄し、関連するリソースをクリーンアップします。 この呼び出しの後、 PrepareLowLagRecordToStorageFileAsync をもう一度呼び出して、 StartAsync を呼び出す前にキャプチャ セッションを再初期化する必要があります。

await m_mediaRecording.FinishAsync();

ビデオをキャプチャするときは、MediaCapture オブジェクトの RecordLimitationExceeded イベントのハンドラーを登録する必要があります。このイベントは、1 回の記録の制限を超えた場合にオペレーティング システムによって発生します (現在は 3 時間)。 イベントのハンドラーでは、 StopAsync を呼び出して記録を完了する必要があります。

private async void m_mediaCapture_RecordLimitationExceeded(MediaCapture sender)
{
    await m_mediaRecording.StopAsync();
    DispatcherQueue.TryEnqueue(() =>
    {
        tbStatus.Text = "Record limitation exceeded.";
    });
}

PauseAsync を呼び出してから ResumeAsync を呼び出すことで、別の出力ファイルを作成せずにビデオ録画を一時停止し、記録を再開できます。

await m_mediaRecording.PauseAsync(Windows.Media.Devices.MediaCapturePauseBehavior.ReleaseHardwareResources);
await m_mediaRecording.ResumeAsync();

PauseWithResultAsync を呼び出すと、MediaCapturePauseResult オブジェクトが返されます。 LastFrame プロパティは、最後のフレームを表す VideoFrame オブジェクトです。 XAML でフレームを表示するには、ビデオ フレームの SoftwareBitmap 表現を取得します。 現時点では、事前乗算または空のアルファ チャネルを持つ BGRA8 形式のイメージのみがサポートされているため、必要に応じて Convert を呼び出して正しい形式を取得します。 PauseWithResultAsync は、記録された合計時間を追跡する必要がある場合に備えて、前のセグメントで記録されたビデオの再生時間も返します。

StopWithResultAsync を呼び出してビデオを停止すると、結果フレームを取得することもできます。

キャプチャしたビデオ ファイルの再生と編集

ファイルにビデオをキャプチャしたら、ファイルを読み込んで、アプリの UI 内で再生することができます。 これを行うには、 MediaPlayerElement XAML コントロールと関連する MediaPlayer を使用します。 XAML ページでメディアを再生する方法については、「 MediaPlayer でオーディオとビデオを再生する」を参照してください。

CreateFromFileAsync を呼び出して、ビデオ ファイルから MediaClip オブジェクトを作成することもできます。 MediaComposition には、MediaClip オブジェクトのシーケンスの配置、ビデオの長さのトリミング、レイヤーの作成、バックグラウンド ミュージックの追加、ビデオ効果の適用などの基本的なビデオ編集機能が用意されています。 メディアコンポジションの操作の詳細については、「メディアコンポジション と編集」を参照してください。

オーディオのキャプチャ

上で示したビデオキャプチャと同じ手法を使用して、オーディオ キャプチャをすばやくアプリに追加できます。 PrepareLowLagRecordToStorageFileAsync を呼び出してキャプチャ セッションを初期化し、ファイルと、CreateMp3 静的メソッドによってこの例で生成された MediaEncodingProfile を渡します。 記録を開始するには、 StartAsync を呼び出します。

m_mediaCapture.RecordLimitationExceeded += m_mediaCapture_RecordLimitationExceeded;

var myVideos = await Windows.Storage.StorageLibrary.GetLibraryAsync(Windows.Storage.KnownLibraryId.Videos);
StorageFile file = await myVideos.SaveFolder.CreateFileAsync("audio.mp3", CreationCollisionOption.GenerateUniqueName);
m_mediaRecording = await m_mediaCapture.PrepareLowLagRecordToStorageFileAsync(
        MediaEncodingProfile.CreateMp3(AudioEncodingQuality.High), file);
await m_mediaRecording.StartAsync();

StopAsync を呼び出してオーディオ録音を停止します。

await m_mediaRecording.StopAsync();

StartAsyncStopAsync を複数回呼び出して、複数のオーディオ ファイルを記録できます。 オーディオのキャプチャが完了したら、 FinishAsync を呼び出してキャプチャ セッションを破棄し、関連するリソースをクリーンアップします。 この呼び出しの後、 PrepareLowLagRecordToStorageFileAsync をもう一度呼び出して、 StartAsync を呼び出す前にキャプチャ セッションを再初期化する必要があります。

システムがオーディオ キャプチャ ストリームのオーディオ レベルを変更した場合の検出については、「システム によるオーディオ レベルの変更を検出して対応する」を参照してください。