ARあるある言いたい

VR・ARについて書いていきます

HoloLensのアプリがバックグラウンドになるときにMediaCaptureを止める

HoloLensで、アプリ内の機能としてMixed Reality Captureのような録画機能を実装するためにはMediaCaptureというUWPのクラスを使用します。

参考 : HoloLensでMediaCaptureを使おう | D.YAMA Blog

ありがたいことにMediaCaptureを使って録画をしている間、自分で何もコード書かなくてもアプリの視界ではこんな感じ↓のカメラのアイコンが点滅してユーザーに録画中であることを伝えてくれます。

f:id:mojo_nobu:20180729164300p:plain

こんな便利なMediaCaptureですが、録画中にブルームしてアプリから抜けた(アプリをバックグラウンドにした)場合、カメラのアイコンが点滅したまま残ってしまいます。またアプリを抜けた後の視界の表示も、録画中と同じ30fpsのままになってしまっているようです。アプリウィンドウを閉じるなどしてアプリを終了させるとこの状態は解除されます。
ちなみに録画中だった映像はファイルストリームが閉じられておらず、再度アプリをフォアグラウンドにして録画停止処理をするまで保存されません。録画停止処理をした場合、保存されるのはブルーム前までです。つらいですね。

これを避けるために、UWPのライフサイクルを制御するCoreApplicationクラスに、MediaCaptureの録画停止処理をしてもらうようにします。

参考 : Windows 10 UWP アプリのライフサイクル - UWP app developer | Microsoft Docs

こんな感じで書けばOK。

using Windows.ApplicationModel.Core;
using Windows.ApplicationModel;

public class MediaCaptureManager
{
    private MediaCapture _mediaCapture;

    void Initialize()
    {
        // MediaCaptureの初期化
        _mediaCapture = new MediaCapture();
        try
        {
            await _mediaCapture.InitializeAsync();
        }
        catch (UnauthorizedAccessException)
        {
            Debug.Log("The app was denied access to the camera");
        }

        //  バックグラウンドになるときCoreApplication.EnteredBackgroundイベントが呼ばれる
        CoreApplication.EnteredBackground += app_EnteredBackground;
    }

//// 略

    // アプリがバックグラウンドになるときに行う処理
    private void app_EnteredBackground(object sender, EnteredBackgroundEventArgs e)
    {
        Task.Run(async () =>
        {
            // 録画を終了
            await _mediaCapture.StopRecordAsync();
            // 明示的な終了。アプリはバックグラウンドになりこれより後ろにコード書いても実行されない
            e.GetDeferral().Complete();
        });
    }
}

開発環境はUnity2017.4.5f1。HoloLensのOS buildは10.0.17134.165です。
そのうちアップデートで勝手に終了してくれるようになる気もする。