夜風のMixedReality

xRと出会って変わった人生と出会った技術を書き残すためのGeekなHoloRangerの居場所

HoloLensでアプリ内から録画を開始する

本日はHoloLensでの録画を調査します。

〇HoloLensのキャプチャ

HoloLensではOSでサポートされている方法のほか、スクリプトからWebCamにアクセスすることで写真、動画をキャプチャすることができます。

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

redhologerbera.hatenablog.com

メリットとして、ホログラムを描画せずにキャプチャを行うことやスクリプトからそのままサーバーに動画や写真をアップロードすることができます。

今回はボタンを押すことでキャプチャが始まり、再びボタンを押すことでキャプチャが停止して指定したファイルに保存される機能を作成しました。

〇実装

今回は次のようなコードを書きました。

using UnityEngine;
using UnityEngine.Windows.WebCam;
using System.Linq;
using UnityEngine.Events;


public class VideoCapturManager : MonoBehaviour
{
    [SerializeField] 
    bool isRecord=true;
 //録画時間
    [SerializeField] 
    float MaxRecordingTime = 5.0f;
 
    VideoCapture m_VideoCapture = null;
    float m_stopRecordingTimer = float.MaxValue;
   //録画開始時のイベント
    [SerializeField] 
    UnityEvent OnStartCaptureEvents;
   //録画終了時のイベント
    [SerializeField] 
    UnityEvent OnStopCaptureEvents;
    // 初期化
    public  void StartRecord()
    {
        isRecord = !isRecord;
        if (isRecord)
        {
            StartVideoCapture();
        }
        else
        {
            m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
        }
    }

    void Update()
    {
        if (m_VideoCapture == null || !m_VideoCapture.IsRecording)
        {
            return;
        }
        //自動的に指定した秒数経過後に録画を終了する場合使用
        if (Time.time > m_stopRecordingTimer)
        {
        //    m_VideoCapture.StopRecordingAsync(OnStoppedRecordingVideo);
        }
    }

    void StartVideoCapture()
    {
       //録画時の設定
        Resolution cameraResolution = VideoCapture.SupportedResolutions.OrderByDescending((res) => res.width * res.height).First();
        Debug.Log(cameraResolution);

        float cameraFramerate = VideoCapture.GetSupportedFrameRatesForResolution(cameraResolution).OrderByDescending((fps) => fps).First();
        Debug.Log(cameraFramerate);

        VideoCapture.CreateAsync(false, delegate (VideoCapture videoCapture)
        {
            if (videoCapture != null)
            {
                m_VideoCapture = videoCapture;
                Debug.Log("Created VideoCapture Instance!");
               
                CameraParameters cameraParameters = new CameraParameters();
               //ホログラムの透過率=α値(0で完全に透過)
                cameraParameters.hologramOpacity = 0.0f;
               //フレームレート
                cameraParameters.frameRate = cameraFramerate;
    //録画時の画面サイズ 
               cameraParameters.cameraResolutionWidth = cameraResolution.width;
                cameraParameters.cameraResolutionHeight = cameraResolution.height;
    //録画フォーマット
                cameraParameters.pixelFormat = CapturePixelFormat.BGRA32;

                m_VideoCapture.StartVideoModeAsync(cameraParameters,
                                                   VideoCapture.AudioState.ApplicationAndMicAudio,
                                                   OnStartedVideoCaptureMode);
            }
            else
            {
                Debug.LogError("Failed to create VideoCapture Instance!");
            }
        });
    }
//キャプチャモードの起動
    void OnStartedVideoCaptureMode(VideoCapture.VideoCaptureResult result)
    {
        Debug.Log("Started Video Capture Mode!");
        string timeStamp = Time.time.ToString().Replace(".", "").Replace(":", "");
       //録画ファイル名
        string filename = string.Format("TestVideo_{0}.mp4", timeStamp);
       //保存場所のパス
        string filepath = System.IO.Path.Combine(Application.persistentDataPath, filename);
        filepath = filepath.Replace("/", @"\");
        Debug.Log(filepath);
        m_VideoCapture.StartRecordingAsync(filepath, OnStartedRecordingVideo);
    }

    void OnStoppedVideoCaptureMode(VideoCapture.VideoCaptureResult result)
    {
        Debug.Log("Stopped Video Capture Mode!");
    }

    void OnStartedRecordingVideo(VideoCapture.VideoCaptureResult result)
    {
        Debug.Log("Started Recording Video!");
        m_stopRecordingTimer = Time.time + MaxRecordingTime;
        OnStartCaptureEvents.Invoke();
    }

    void OnStoppedRecordingVideo(VideoCapture.VideoCaptureResult result)
    {
        Debug.Log("Stopped Recording Video!");
        m_VideoCapture.StopVideoModeAsync(OnStoppedVideoCaptureMode);
        OnStopCaptureEvents.Invoke();
    }
}

 録画された動画はApplication.persistentDataPathすなわちデバイスポータルからアクセスできる[UserFolders/LocalAppdata/アプリ名/LocalState ]に保存されます。

〇アプリ内での実装

MRTKで提供されている[PressableButtonHoloLens 2]をシーンに配置します。

f:id:Holomoto-Sumire:20210111203052j:plain

[PressableButtonHoloLens 2]コンポーネントの[ButtonPressed()]で適当なゲームオブジェクトにアタッチした[VideoCapturManager]コンポーネントの[StartRecord()]メソッドを呼び出します。

f:id:Holomoto-Sumire:20210111203146j:plain

以上で実機でボタンを押すことで録画が始まり、もういちどボタンを押すことで録画が終了します。