Seeking Assistance with Video Preview and Recording in Magic Leap

Dear Community,

I'm currently working on a project where I'm implementing video preview and recording capabilities within a Magic Leap application using Unity. The project is primarily based on the example provided in the following link:

Versions:

  • Unity Editor version: 2022.2.0b16
  • ML2 OS version: Version 1.2.0, Build B3E.230330.11-R.044
  • MLSDK version: v1.6.1
  • Host OS: Windows 11

However, I've run into some issues that I'm hoping this wonderful community can help me resolve.

So far, I've created a script that does the following:

  1. Requests user permissions for both the microphone and the camera.
  2. Connects to the Magic Leap device camera.
  3. Starts a preview on a canvas.
  4. Initiates video capturing.
  5. Records video for a duration of 10 seconds.
  6. Stops the video recording.

Additionally, I've included event handling. Specifically, I've subscribed to the MediaPlayerOnOnPrepared and MediaPlayerOnCompletion events in both the StartRecording and StartPreview methods.

I have implemented a component TestCameraRecording.cs with Canvas_Record such as;


using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using MagicLeap.Core;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.XR.MagicLeap;


namespace MagicLeap.Examples
{

    /// <summary>
    /// This class handles video recording and image capturing based on controller
    /// input.
    /// </summary>
    /// 


    public class TestCameraRecording : MonoBehaviour
    {
        private MLCamera.CaptureFrameRate FrameRate = MLCamera.CaptureFrameRate._30FPS;
        private MLCamera.OutputFormat OutputFormat = MLCamera.OutputFormat.RGBA_8888;
        private MLCamera captureCamera;
        private bool isCapturingVideo = false;

        [SerializeField, Tooltip("Button that starts the Capture")]
        private Button recordButton;
        private bool skipFrame = false;


        [SerializeField, Tooltip("Reference to media player behavior used in camera capture playback")]
        private MLMediaPlayerBehavior mediaPlayerBehavior;

        private readonly CameraRecorder cameraRecorder = new CameraRecorder();


        private const string validFileFormat = ".mp4";

        private bool isCapturingPreview = false;
        private bool RecordToFile = true;

        private string recordedFilePath;
        private MLCamera.CaptureType CaptureType = MLCamera.CaptureType.Video;


        private List<MLCamera.StreamCapability> streamCapabilities;

        [SerializeField, Tooltip("Button that starts the Capture")]
        private readonly MLPermissions.Callbacks permissionCallbacks = new MLPermissions.Callbacks();

        private bool cameraDeviceAvailable;

        [SerializeField, Tooltip("Refrence to the Raw Video Capture Visualizer gameobject for YUV frames")]
        private CameraCaptureVisualizer cameraCaptureVisualizer = null;


        private void Awake()
        {
            permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
            permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
            permissionCallbacks.OnPermissionDeniedAndDontAskAgain += OnPermissionDenied;

            //connectionFlagDropdown.AddOptions(
            //    MLCamera.ConnectFlag.CamOnly,
            //    MLCamera.ConnectFlag.MR,
            //    MLCamera.ConnectFlag.VirtualOnly);

            recordButton.onClick.AddListener(StartVideoCapture);
            //connectButton.onClick.AddListener(ConnectCamera);
            //disconnectButton.onClick.AddListener(DisconnectCamera);
            //connectionFlagDropdown.onValueChanged.AddListener(v => RefreshUI());
            //streamCapabilitiesDropdown.onValueChanged.AddListener(v => RefreshUI());
            //qualityDropDown.onValueChanged.AddListener(v => RefreshUI());
            //captureTypeDropDown.onValueChanged.AddListener(v => RefreshUI());
            //frameRateDropDown.onValueChanged.AddListener(v => RefreshUI());

            //RefreshUI();
        }

        // Start is called before the first frame update

        private void Start()
        {
            Debug.Log("Start");
            MLPermissions.RequestPermission(MLPermission.Camera, permissionCallbacks);
            MLPermissions.RequestPermission(MLPermission.RecordAudio, permissionCallbacks);

            TryEnableMLCamera();
        }

        private void TryEnableMLCamera()
        {
            if (!MLPermissions.CheckPermission(MLPermission.Camera).IsOk)
                return;

            StartCoroutine(EnableMLCamera());
        }

        private IEnumerator EnableMLCamera()
        {
            while (!cameraDeviceAvailable)
            {
                MLResult result =
                    MLCamera.GetDeviceAvailabilityStatus(MLCamera.Identifier.Main, out cameraDeviceAvailable);
                if (!(result.IsOk && cameraDeviceAvailable))
                {
                    // Wait until camera device is available
                    yield return new WaitForSeconds(1.0f);
                }
                else
                {
                    ConnectCamera();

                    // Camera device is available, start video capture here
                }
            }

            Debug.Log("Camera device available");
        }

        // Update is called once per frame
        void Update()
        {
        }


        private void OnPermissionDenied(string permission)
        {
            if (permission == MLPermission.Camera)
            {
                MLPluginLog.Error($"{permission} denied, example won't function.");
            }
            else if (permission == MLPermission.RecordAudio)
            {
                MLPluginLog.Error($"{permission} denied, audio wont be recorded in the file.");
            }

            //RefreshUI();
        }



        private void OnPermissionGranted(string permission)
        {
            MLPluginLog.Debug($"Granted {permission}.");
            TryEnableMLCamera();

            //RefreshUI();
        }

        private void StartVideoCapture()
        {
            // recordedFilePath = string.Empty;
            // skipFrame = false;

            var result = MLPermissions.CheckPermission(MLPermission.Camera);
            MLResult.DidNativeCallSucceed(result.Result, nameof(MLPermissions.RequestPermission));
            Debug.Log($"CLPermissions.CheckPermission {result}");
            if (!result.IsOk)
            {
                Debug.LogError($"{MLPermission.Camera} permission denied. Video will not be recorded.");
                return;
            }

            if (!RecordToFile)
                StartRecording();
            else
                StartPreview();
        }

        private void StartRecording()
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.MediaPlayer.OnPrepared += MediaPlayerOnOnPrepared;
            mediaPlayerBehavior.MediaPlayer.OnCompletion += MediaPlayerOnCompletion;
#endif
            string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + validFileFormat;
            recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);

            CameraRecorderConfig config = CameraRecorderConfig.CreateDefault();
            config.Width = streamCapabilities[0].Width;
            config.Height = streamCapabilities[0].Height;
            config.FrameRate = MapFrameRate(MLCamera.CaptureFrameRate._30FPS);

            cameraRecorder.StartRecording(recordedFilePath, config);

            int MapFrameRate(MLCamera.CaptureFrameRate frameRate)
            {
                switch (frameRate)
                {
                    case MLCamera.CaptureFrameRate.None: return 0;
                    case MLCamera.CaptureFrameRate._15FPS: return 15;
                    case MLCamera.CaptureFrameRate._30FPS: return 30;
                    case MLCamera.CaptureFrameRate._60FPS: return 60;
                    default: return 0;
                }
            }

            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
            captureConfig.CaptureFrameRate = FrameRate;
            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[0];
            captureConfig.StreamConfigs[0] = MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], OutputFormat);
            captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;

            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            Debug.Log($"Check Camera is ready for capture {MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture))}");

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                captureCamera.PreCaptureAEAWB();

                if (CaptureType == MLCamera.CaptureType.Video)
                {
                    result = captureCamera.CaptureVideoStart();
                    isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));

                    Debug.LogError($"isCapturingVideo {isCapturingVideo} ");

                    if (isCapturingVideo)
                    {
                        cameraCaptureVisualizer.DisplayCapture(captureConfig.StreamConfigs[0].OutputFormat, RecordToFile);
                    }
                }

                if (CaptureType == MLCamera.CaptureType.Preview)
                {
                    result = captureCamera.CapturePreviewStart();
                    isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
                    if (isCapturingPreview)
                    {
                        cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, RecordToFile);
                    }
                }
            }
        }
        private void StartPreview()
        {
            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
            captureConfig.CaptureFrameRate = MLCamera.CaptureFrameRate._30FPS;
            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[0];
            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], OutputFormat);

            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                captureCamera.PreCaptureAEAWB();

                if (CaptureType == MLCamera.CaptureType.Video)
                {
                    result = captureCamera.CaptureVideoStart();
                    isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));

                    Debug.LogError($"isCapturingVideo {isCapturingVideo} ");
                    if (isCapturingVideo)
                    {
                        cameraCaptureVisualizer.DisplayCapture(captureConfig.StreamConfigs[0].OutputFormat, true);
                    }
                }

                if (CaptureType == MLCamera.CaptureType.Preview)
                {
                    result = captureCamera.CapturePreviewStart();
                    isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
                    Debug.LogError($"isCapturingPreview {isCapturingPreview} ");
                    if (isCapturingPreview)
                    {

                        cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, true);
                    }
                }
            }
        }

        private void ConnectCamera()
        {
            MLCamera.ConnectContext context = MLCamera.ConnectContext.Create();
            context.Flags = MLCamera.ConnectFlag.CamOnly;
            context.EnableVideoStabilization = true;

            if (context.Flags != MLCamera.ConnectFlag.CamOnly)
            {
                context.MixedRealityConnectInfo = MLCamera.MRConnectInfo.Create();
                context.MixedRealityConnectInfo.MRQuality = MLCamera.MRQuality._960x720;
                context.MixedRealityConnectInfo.MRBlendType = MLCamera.MRBlendType.Additive;
                context.MixedRealityConnectInfo.FrameRate = MLCamera.CaptureFrameRate._30FPS;
            }

            captureCamera = MLCamera.CreateAndConnect(context);

            if (captureCamera != null)
            {
                Debug.Log("Camera device connected");
                if (GetImageStreamCapabilities())
                {
                    ShowToast("Camera device connected");
                    Debug.Log("Camera device received stream caps");
                    captureCamera.OnRawVideoFrameAvailable += OnCaptureRawVideoFrameAvailable;
                    captureCamera.OnRawImageAvailable += OnCaptureRawImageComplete;

                }
            }

        }

        private bool GetImageStreamCapabilities()
        {
            var result =
                captureCamera.GetStreamCapabilities(out MLCamera.StreamCapabilitiesInfo[] streamCapabilitiesInfo);

            if (!result.IsOk)
            {
                Debug.Log("Could not get Stream capabilities Info.");
                return false;
            }

            streamCapabilities = new List<MLCamera.StreamCapability>();

            for (int i = 0; i < streamCapabilitiesInfo.Length; i++)
            {
                foreach (var streamCap in streamCapabilitiesInfo[i].StreamCapabilities)
                {
                    streamCapabilities.Add(streamCap);
                }
            }

            return streamCapabilities.Count > 0;
        }

        private void MediaPlayerOnOnPrepared(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.Play();
#endif
        }

        private void MediaPlayerOnCompletion(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.StopMLMediaPlayer();
#endif
            mediaPlayerBehavior.gameObject.SetActive(false);
            mediaPlayerBehavior.Reset();
        }

        private void OnCaptureRawVideoFrameAvailable(MLCamera.CameraOutput capturedFrame, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            // if (string.IsNullOrEmpty(captureInfoText.text) && isCapturingVideo)
            // {
            // captureInfoText.text = capturedFrame.ToString();
            // }



            if (OutputFormat == MLCamera.OutputFormat.RGBA_8888 && FrameRate == MLCamera.CaptureFrameRate._30FPS && streamCapabilities[0].Width >= 4096)
            {
                // cameraCaptureVisualizer cannot handle throughput of RGBA_8888 4096x3072 at 30 fps 
                skipFrame = !skipFrame;
                if (skipFrame)
                {
                    return;
                }
            }
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedFrame);
        }

        /// <summary>
        /// Handles the event of a new image getting captured.
        /// </summary>
        /// <param name="capturedImage">Captured frame.</param>
        /// <param name="resultExtras">Results Extras.</param>
        private void OnCaptureRawImageComplete(MLCamera.CameraOutput capturedImage, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {

            // isDisplayingImage = true;
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedImage);

            if (RecordToFile)
            {
                if (capturedImage.Format != MLCamera.OutputFormat.YUV_420_888)
                {
                    string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + ".jpg";
                    recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);
                    try
                    {
                        File.WriteAllBytes(recordedFilePath, capturedImage.Planes[0].Data);
                        // captureInfoText.text += $"\nSaved to {recordedFilePath}";
                    }
                    catch (Exception e)
                    {
                        Debug.LogError(e.Message);
                    }
                }
            }
        }
        public void ShowToast(string message)
        {
            if (Application.platform == RuntimePlatform.Android)
            {
                // Retrieve the UnityPlayer class
                AndroidJavaClass unityPlayerClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");

                // Retrieve the current activity from the UnityPlayer class
                AndroidJavaObject currentActivity = unityPlayerClass.GetStatic<AndroidJavaObject>("currentActivity");

                // Show the toast message
                currentActivity.Call("runOnUiThread", new AndroidJavaRunnable(() =>
                {
                    // Retrieve the Toast class
                    AndroidJavaClass toastClass = new AndroidJavaClass("android.widget.Toast");

                    // Create the Toast object
                    AndroidJavaObject toastObject = toastClass.CallStatic<AndroidJavaObject>("makeText", currentActivity, message, 0);

                    // Show the Toast
                    toastObject.Call("show");
                }));
            }
            else
            {
                Debug.Log("Toast message: " + message);
            }
        }


    }

}

Everything seemed to be in order, and I was able to confirm a successful connection to the Magic Leap camera through both Android Logcat and the camera indicator on Magic Leap 2 Device. Unfortunately, when it came to capturing, previewing, or recording, nothing worked as expected. I'm currently facing errors that I'm struggling to understand and resolve.

I'm seeking assistance to troubleshoot these issues. Any guidance on how to handle potential crashes and perform necessary checks to ensure smooth operation would be greatly appreciated. Additionally, the example I'm following has extra UI elements such as buttons and drop-down menus that I don't require for my project. Any tips on how to streamline this would also be beneficial.

I'm looking forward to your insights and expertise on these matters. Your assistance will greatly contribute to the progression of my project.

Thank you in advance for your help.

Best regards,

Muhammad Usman Bashir

Thank you @usman.bashir We are working with our engineering team for assistance and will report back shortly.

Hi @usman.bashir Our team recommends two things:

  1. Update to the latest SDK and OS through Magic Leap Hub.
  2. Run our sample project first. Then isolate each step in your project and compare to the sample to determine what may be incorrectly implemented.

The samples are the best resource to understand how the API's work.

Okay. Let me update the SDK and OS using Magic Leap hub. I will share feedback by today.

Dear Team,

I have updated Magic Leap SDK to 1.7.0 as well as the unity editor for both MagicLeapExamples and for our project:

Magic Leap SDK - 1.7.0:

For references, I am posting the following screenshots;

Loading tarball package.

Unity Editor - 2022-2.0f1:

After properly inserting the logs inside my project;

I am facing issue on the following line of code:

MagicLeapExamples | CameraCaptureExamples.cs File:

            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(GetStreamCapability(), OutputFormat);

Our Project | CameraRecording.cs File:


        private List<MLCamera.StreamCapability> streamCapabilities;

        Debug.Log($"StartPreview 3 {streamCapabilities[0]}");
            
        captureConfig.StreamConfigs[0] =
            MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], OutputFormat);

         Debug.Log("StartPreview 4 ");

Here are the logs of our project:

2023/06/01 16:34:50.976 6801 6925 Info ml_camera_client Camonly OnUnavailable CamId = 0
2023/06/01 16:34:50.980 6801 6827 Info Unity Camera device connected
2023/06/01 16:34:50.986 6801 6827 Info Unity Camera device received stream caps
2023/06/01 16:34:50.987 6801 6827 Info Unity CLPermissions.CheckPermission MLResult_Ok
2023/06/01 16:34:50.987 6801 6827 Info Unity Configurartions _30FPS UnityEngine.XR.MagicLeap.MLCameraBase+CaptureStreamConfig[] YUV_420_888 CaptureType : Video, Width : 640, Height : 480
2023/06/01 16:34:50.987 6801 6827 Info Unity StartPreview 1 
2023/06/01 16:34:50.987 6801 6827 Info Unity StartPreview 2 
2023/06/01 16:34:50.987 6801 6827 Info Unity StartPreview 3 CaptureType : Video, Width : 640, Height : 480
2023/06/01 16:34:50.989 6801 6827 Error Unity IndexOutOfRangeException: Index was outside the bounds of the array.
2023/06/01 16:34:50.989 6801 6827 Error Unity   at MagicLeap.Examples.TestCameraRecording.StartPreview () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/01 16:34:50.989 6801 6827 Error Unity   at MagicLeap.Examples.TestCameraRecording.StartVideoCapture () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/01 16:34:50.989 6801 6827 Error Unity   at MagicLeap.Examples.TestCameraRecording.ConnectCamera () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/01 16:34:50.989 6801 6827 Error Unity   at MagicLeap.Examples.TestCameraRecording+<EnableMLCamera>d__19.MoveNext () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/01 16:34:50.989 6801 6827 Error Unity   at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0 
2023/06/01 16:34:50.989 6801 6827 Error Unity   at MagicLeap.Examples.TestCameraRecording.TryEnableMLCamera () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/01 16:34:50.989 6801 6827 Error Unity   at UnityEngine.XR.MagicLeap.MLPermissions.RequestPermissionInternal (System.String permission, UnityEngine.XR.MagicLeap.MLPermissions+Callbacks callbacks) [0x00000] in <00000000000000000000000
2023/06/01 16:34:50.990 6801 6827 Info Unity Camera device available
2023/06/01 16:34:50.990 6801 6827 Info Unity Camera device available

I found some information that might help you understand the problem better. I want to let you know that I have opened the projects in different windows of a software called VS Code.

In my project, there is a part called captureConfig.StreamConfigs[0]. This part is located in a file called MLCameraBaseStructs.cs. However, in the MagicLeapExamples project, the same part is found in a file called MLCameraBase.cs. This is a bit confusing and challenging for me too.

I hope this research may direct you towards the exact problem.

Kind regards,

Dear Magic Leap Developer Community,

I hope this message finds you all well. I'm writing to express my gratitude for your previous guidance and contributions to my project; your expertise has been invaluable especially @etucker .

However, I've encountered a couple of issues recently and would appreciate your insights:

  1. I've been running a portion of the code that you provided and have been consistently getting a pink color preview on the screen. This suggests there might be an issue with the video output or preview format, but I'm not entirely sure how to address it.

Your provided code example | Updated version of my CameraRecording File.

using System.Collections;
using System.Collections.Generic;
using MagicLeap.Core;
using UnityEngine;
using UnityEngine.XR.MagicLeap;


namespace MagicLeap.Examples
{

    /// <summary>
    /// This class handles video recording and image capturing based on controller
    /// input.
    /// </summary>
    /// 


    public class CameraRecording : MonoBehaviour
    {
        private MLCamera.CaptureFrameRate FrameRate = MLCamera.CaptureFrameRate._60FPS;
        private MLCamera.OutputFormat OutputFormat = MLCamera.OutputFormat.YUV_420_888;
        private MLCamera captureCamera;
        private bool isCapturingVideo = false;

        private bool skipFrame = false;


        [SerializeField, Tooltip("Reference to media player behavior used in camera capture playback")]
        private MLMediaPlayerBehavior mediaPlayerBehavior;




        private bool isCapturingPreview;

        private MLCamera.CaptureType CaptureType = MLCamera.CaptureType.Preview;


        private List<MLCamera.StreamCapability> streamCapabilities;

        private readonly MLPermissions.Callbacks permissionCallbacks = new MLPermissions.Callbacks();

        private bool cameraDeviceAvailable;

        [SerializeField, Tooltip("Refrence to the Raw Video Capture Visualizer gameobject for YUV frames")]
        private CameraCaptureVisualizer cameraCaptureVisualizer = null;


        private void Awake()
        {
            permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
            permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
            permissionCallbacks.OnPermissionDeniedAndDontAskAgain += OnPermissionDenied;
        }

        // Start is called before the first frame update

        private void Start()
        {
            MLPermissions.RequestPermission(MLPermission.Camera, permissionCallbacks);
            MLPermissions.RequestPermission(MLPermission.RecordAudio, permissionCallbacks);
            TryEnableMLCamera();
        }

        private void TryEnableMLCamera()
        {
            if (!MLPermissions.CheckPermission(MLPermission.Camera).IsOk)
                return;

            StartCoroutine(EnableMLCamera());
        }

        private IEnumerator EnableMLCamera()
        {
            while (!cameraDeviceAvailable)
            {
                MLResult result =
                    MLCamera.GetDeviceAvailabilityStatus(MLCamera.Identifier.Main, out cameraDeviceAvailable);
                if (!(result.IsOk && cameraDeviceAvailable))
                {
                    // Wait until camera device is available
                    yield return new WaitForSeconds(1.0f);
                }
            }

            yield return new WaitForEndOfFrame();
            ConnectCamera();
            Debug.Log("Camera device available");
        }

        private void OnPermissionDenied(string permission)
        {
            if (permission == MLPermission.Camera)
            {
                MLPluginLog.Error($"{permission} denied, example won't function.");
            }
            else if (permission == MLPermission.RecordAudio)
            {
                MLPluginLog.Error($"{permission} denied, audio wont be recorded in the file.");
            }
        }

        private void OnPermissionGranted(string permission)
        {
            MLPluginLog.Debug($"Granted {permission}.");
        }

        private void StartVideoCapture()
        {
            skipFrame = false;
            var result = MLPermissions.CheckPermission(MLPermission.Camera);
            MLResult.DidNativeCallSucceed(result.Result, nameof(MLPermissions.RequestPermission));
            MLPluginLog.Debug($"CLPermissions.CheckPermission {result}");
            if (!result.IsOk)
            {
                Debug.LogError($"{MLPermission.Camera} permission denied. Video will not be recorded.");
                return;
            }
            StartPreview();
        }
        
        private void StartPreview()
        {
            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
            captureConfig.CaptureFrameRate = FrameRate;
            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[1];
            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[3], MLCameraBase.OutputFormat.YUV_420_888);

            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                result = captureCamera.CapturePreviewStart();
                isCapturingPreview =
                    MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
                if (isCapturingPreview)
                {
                    cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, false);
                }
            }
        }

        private void ConnectCamera()
        {
            MLCamera.ConnectContext context = MLCamera.ConnectContext.Create();
            context.Flags = MLCamera.ConnectFlag.CamOnly;
            context.EnableVideoStabilization = true;

            captureCamera = MLCamera.CreateAndConnect(context);

            if (captureCamera != null)
            {
                print("Camera device connected");
                if (GetImageStreamCapabilities())
                {
                    print("Camera device received stream caps");
                    captureCamera.OnRawVideoFrameAvailable += OnCaptureRawVideoFrameAvailable;
                    captureCamera.OnRawImageAvailable += OnCaptureRawImageComplete;

                    StartVideoCapture();
                }
            }

        }
        private bool GetImageStreamCapabilities()
        {
            var result =
                captureCamera.GetStreamCapabilities(out MLCamera.StreamCapabilitiesInfo[] streamCapabilitiesInfo);

            if (!result.IsOk)
            {
                Debug.Log("Could not get Stream capabilities Info.");
                return false;
            }

            streamCapabilities = new List<MLCamera.StreamCapability>();

            for (int i = 0; i < streamCapabilitiesInfo.Length; i++)
            {
                foreach (var streamCap in streamCapabilitiesInfo[i].StreamCapabilities)
                {
                    streamCapabilities.Add(streamCap);
                }
            }

            return streamCapabilities.Count > 0;
        }
        private void OnCaptureRawVideoFrameAvailable(MLCamera.CameraOutput capturedFrame, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedFrame);
        }

        /// <summary>
        /// Handles the event of a new image getting captured.
        /// </summary>
        /// <param name="capturedImage">Captured frame.</param>
        /// <param name="resultExtras">Results Extras.</param>
        private void OnCaptureRawImageComplete(MLCamera.CameraOutput capturedImage, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedImage);
        }
    }

}

Results:

  1. Additionally, I've expanded the code stack to include video recording. This feature is working well in that it's recording and saving videos to my local directory. However, the preview isn't showing while recording.

Upgraded Version of My code with Video recording capability:

using System.Collections;
using System.Collections.Generic;
using MagicLeap.Core;
using UnityEngine;
using UnityEngine.XR.MagicLeap;
using System;


namespace MagicLeap.Examples
{

    /// <summary>
    /// This class handles video recording and image capturing based on controller
    /// input.
    /// </summary>
    /// 


    public class TestCameraRecording : MonoBehaviour
    {
        private MLCamera.CaptureFrameRate FrameRate = MLCamera.CaptureFrameRate._60FPS;
        private MLCamera.OutputFormat OutputFormat = MLCamera.OutputFormat.YUV_420_888;
        private MLCamera captureCamera;
        private bool isCapturingVideo = true;

        private bool skipFrame = false;

        private string recordedFilePath;
        private readonly CameraRecorder cameraRecorder = new CameraRecorder();


        [SerializeField, Tooltip("Reference to media player behavior used in camera capture playback")]
        private MLMediaPlayerBehavior mediaPlayerBehavior;
        private const string validFileFormat = ".mp4";

        private bool RecordToFile = true;

        private bool isCapturingPreview;

        private MLCamera.CaptureType CaptureType = MLCamera.CaptureType.Video;


        private List<MLCamera.StreamCapability> streamCapabilities;

        private readonly MLPermissions.Callbacks permissionCallbacks = new MLPermissions.Callbacks();

        private bool cameraDeviceAvailable;

        [SerializeField, Tooltip("Refrence to the Raw Video Capture Visualizer gameobject for YUV frames")]
        private CameraCaptureVisualizer cameraCaptureVisualizer = null;


        private void Awake()
        {
            permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
            permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
            permissionCallbacks.OnPermissionDeniedAndDontAskAgain += OnPermissionDenied;
        }

        // Start is called before the first frame update

        private void Start()
        {
            MLPermissions.RequestPermission(MLPermission.Camera, permissionCallbacks);
            MLPermissions.RequestPermission(MLPermission.RecordAudio, permissionCallbacks);
            TryEnableMLCamera();
        }

        private void TryEnableMLCamera()
        {
            if (!MLPermissions.CheckPermission(MLPermission.Camera).IsOk)
                return;

            StartCoroutine(EnableMLCamera());
        }

        private IEnumerator EnableMLCamera()
        {
            while (!cameraDeviceAvailable)
            {
                MLResult result =
                    MLCamera.GetDeviceAvailabilityStatus(MLCamera.Identifier.Main, out cameraDeviceAvailable);
                if (!(result.IsOk && cameraDeviceAvailable))
                {
                    // Wait until camera device is available
                    yield return new WaitForSeconds(1.0f);
                }
            }

            yield return new WaitForEndOfFrame();
            ConnectCamera();
            Debug.Log("Camera device available");
        }

        private void OnPermissionDenied(string permission)
        {
            if (permission == MLPermission.Camera)
            {
                MLPluginLog.Error($"{permission} denied, example won't function.");
            }
            else if (permission == MLPermission.RecordAudio)
            {
                MLPluginLog.Error($"{permission} denied, audio wont be recorded in the file.");
            }
        }

        private void OnPermissionGranted(string permission)
        {
            MLPluginLog.Debug($"Granted {permission}.");
        }

        private void StartVideoCapture()
        {
            skipFrame = false;
            var result = MLPermissions.CheckPermission(MLPermission.Camera);
            MLResult.DidNativeCallSucceed(result.Result, nameof(MLPermissions.RequestPermission));
            MLPluginLog.Debug($"CLPermissions.CheckPermission {result}");
            if (!result.IsOk)
            {
                Debug.LogError($"{MLPermission.Camera} permission denied. Video will not be recorded.");
                return;
            }


            StartPreview();
            StartCoroutine(StopVideo());

        }

        private void StartPreview()
        {



#if !UNITY_EDITOR
            mediaPlayerBehavior.MediaPlayer.OnPrepared += MediaPlayerOnOnPrepared;
            mediaPlayerBehavior.MediaPlayer.OnCompletion += MediaPlayerOnCompletion;
#endif
            string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + validFileFormat;
            recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);

            CameraRecorderConfig config = CameraRecorderConfig.CreateDefault();
            config.Width = streamCapabilities[0].Width;
            config.Height = streamCapabilities[0].Height;
            config.FrameRate = MapFrameRate(FrameRate);

            cameraRecorder.StartRecording(recordedFilePath, config);

            int MapFrameRate(MLCamera.CaptureFrameRate frameRate)
            {
                switch (frameRate)
                {
                    case MLCamera.CaptureFrameRate.None: return 0;
                    case MLCamera.CaptureFrameRate._15FPS: return 15;
                    case MLCamera.CaptureFrameRate._30FPS: return 30;
                    case MLCamera.CaptureFrameRate._60FPS: return 60;
                    default: return 0;
                }
            }




            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
            captureConfig.CaptureFrameRate = FrameRate;
            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[1];
            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], MLCameraBase.OutputFormat.YUV_420_888);

            captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;


            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                captureCamera.PreCaptureAEAWB();

                if (CaptureType == MLCamera.CaptureType.Video)
                {
                    result = captureCamera.CaptureVideoStart();
                    isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));
                    if (isCapturingVideo)
                    {
                        cameraCaptureVisualizer.DisplayCapture(captureConfig.StreamConfigs[0].OutputFormat, RecordToFile);
                    }
                }

                if (CaptureType == MLCamera.CaptureType.Preview)
                {
                    result = captureCamera.CapturePreviewStart();
                    isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
                    if (isCapturingPreview)
                    {
                        cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, RecordToFile);
                    }
                }
            }
        }

        private void ConnectCamera()
        {
            MLCamera.ConnectContext context = MLCamera.ConnectContext.Create();
            context.Flags = MLCamera.ConnectFlag.CamOnly;
            context.EnableVideoStabilization = true;

            captureCamera = MLCamera.CreateAndConnect(context);

            if (captureCamera != null)
            {
                print("Camera device connected");
                if (GetImageStreamCapabilities())
                {
                    print("Camera device received stream caps");
                    captureCamera.OnRawVideoFrameAvailable += OnCaptureRawVideoFrameAvailable;
                    captureCamera.OnRawImageAvailable += OnCaptureRawImageComplete;

                    StartVideoCapture();
                }
            }

        }
        private bool GetImageStreamCapabilities()
        {
            var result =
                captureCamera.GetStreamCapabilities(out MLCamera.StreamCapabilitiesInfo[] streamCapabilitiesInfo);

            if (!result.IsOk)
            {
                Debug.Log("Could not get Stream capabilities Info.");
                return false;
            }

            streamCapabilities = new List<MLCamera.StreamCapability>();

            for (int i = 0; i < streamCapabilitiesInfo.Length; i++)
            {
                foreach (var streamCap in streamCapabilitiesInfo[i].StreamCapabilities)
                {
                    streamCapabilities.Add(streamCap);
                }
            }

            return streamCapabilities.Count > 0;
        }
        private void OnCaptureRawVideoFrameAvailable(MLCamera.CameraOutput capturedFrame, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedFrame);
        }

        /// <summary>
        /// Handles the event of a new image getting captured.
        /// </summary>
        /// <param name="capturedImage">Captured frame.</param>
        /// <param name="resultExtras">Results Extras.</param>
        private void OnCaptureRawImageComplete(MLCamera.CameraOutput capturedImage, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedImage);
        }

        /// <summary>
        /// Stops recording.
        /// </summary>
        private void StopRecording()
        {
            MLResult result = cameraRecorder.EndRecording();
            if (!result.IsOk)
            {
                Debug.Log("Saving Recording failed, reason:" + result);
                recordedFilePath = string.Empty;
            }
            else
            {
                Debug.Log("Recording saved at path: " + recordedFilePath);
            }
        }

        private IEnumerator StopVideo()
        {
            float startTimestamp = Time.realtimeSinceStartup;
            while (Time.realtimeSinceStartup - startTimestamp < 10)
            {
                yield return null;
            }

            StopVideoCapture();
        }

        private void StopVideoCapture()
        {


            if (isCapturingVideo)
            {
                captureCamera.CaptureVideoStop();
            }
            else if (isCapturingPreview)
            {
                captureCamera.CapturePreviewStop();
            }

            cameraCaptureVisualizer.HideRenderer();

            if (RecordToFile)
            {
                StopRecording();
                // DisplayPlayback();
            }

            isCapturingVideo = false;
            isCapturingPreview = false;
        }

    private void MediaPlayerOnOnPrepared(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.Play();
#endif
        }

        private void MediaPlayerOnCompletion(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.StopMLMediaPlayer();
#endif
            mediaPlayerBehavior.gameObject.SetActive(false);
            mediaPlayerBehavior.Reset();
        }
    }
}

I'm wondering if I need to run these processes concurrently using multi-threading, or if there might be something else I'm overlooking.

Any assistance or guidance you could provide would be greatly appreciated.

Best regards,

Muhammad Usman Bashir

Hi @usman.bashir I am one of the engineers that has been looking into this, and I am wondering if you could provide a bit more context on what you are trying to achieve with this script, that way we could offer help more specifically tailored to your goals, as opposed to simply reacting to error logs. Thank you.

I am currently working on developing a new feature for our application that allows users to record videos. To achieve this, we need to display a video preview on a canvas, and provide controls to start and stop video recording. The recorded videos will be saved in the MP4 file format.

I hope this helps you better understand problem statement.

Kind regards,

@usman.bashir Just to be sure. Your intention is to hide the preview while the video is recording? Correct?

Following up on my previous reply in this thread;

I would like to emphasize that our objective is to display the front view of the camera on the Canvas. Further, we also aim to record the displayed front view from the Canvas.

I'd like to draw your attention to the 'CameraCaptureExample.cs' from the 'MagicLeapExamples' directory. This script does allow us to preview a still picture of the front view and perform the recording function.

However, our requirement is a bit more specific. We need to simultaneously display the live front view on the Canvas while recording the same. This is where we are encountering challenges.

I have attached the code (Video Recording is happening successfully) we are currently working with for your reference;

using System.Collections;
using System.Collections.Generic;
using MagicLeap.Core;
using UnityEngine;
using UnityEngine.XR.MagicLeap;
using System;


namespace MagicLeap.Examples
{

    /// <summary>
    /// This class handles video recording and image capturing based on controller
    /// input.
    /// </summary>
    /// 


    public class TestCameraRecording : MonoBehaviour
    {
        private MLCamera.CaptureFrameRate FrameRate = MLCamera.CaptureFrameRate._60FPS;
        private MLCamera.OutputFormat OutputFormat = MLCamera.OutputFormat.YUV_420_888;
        private MLCamera captureCamera;
        private bool isCapturingVideo = true;

        private bool skipFrame = false;

        private string recordedFilePath;
        private readonly CameraRecorder cameraRecorder = new CameraRecorder();


        [SerializeField, Tooltip("Reference to media player behavior used in camera capture playback")]
        private MLMediaPlayerBehavior mediaPlayerBehavior;
        private const string validFileFormat = ".mp4";

        private bool RecordToFile = true;

        private bool isCapturingPreview;

        private MLCamera.CaptureType CaptureType = MLCamera.CaptureType.Video;


        private List<MLCamera.StreamCapability> streamCapabilities;

        private readonly MLPermissions.Callbacks permissionCallbacks = new MLPermissions.Callbacks();

        private bool cameraDeviceAvailable;

        [SerializeField, Tooltip("Refrence to the Raw Video Capture Visualizer gameobject for YUV frames")]
        private CameraCaptureVisualizer cameraCaptureVisualizer = null;


        private void Awake()
        {
            permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
            permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
            permissionCallbacks.OnPermissionDeniedAndDontAskAgain += OnPermissionDenied;
        }

        // Start is called before the first frame update

        private void Start()
        {
            MLPermissions.RequestPermission(MLPermission.Camera, permissionCallbacks);
            MLPermissions.RequestPermission(MLPermission.RecordAudio, permissionCallbacks);
            TryEnableMLCamera();
        }

        private void TryEnableMLCamera()
        {
            if (!MLPermissions.CheckPermission(MLPermission.Camera).IsOk)
                return;

            StartCoroutine(EnableMLCamera());
        }

        private IEnumerator EnableMLCamera()
        {
            while (!cameraDeviceAvailable)
            {
                MLResult result =
                    MLCamera.GetDeviceAvailabilityStatus(MLCamera.Identifier.Main, out cameraDeviceAvailable);
                if (!(result.IsOk && cameraDeviceAvailable))
                {
                    // Wait until camera device is available
                    yield return new WaitForSeconds(1.0f);
                }
            }

            yield return new WaitForEndOfFrame();
            ConnectCamera();
            Debug.Log("Camera device available");
        }

        private void OnPermissionDenied(string permission)
        {
            if (permission == MLPermission.Camera)
            {
                MLPluginLog.Error($"{permission} denied, example won't function.");
            }
            else if (permission == MLPermission.RecordAudio)
            {
                MLPluginLog.Error($"{permission} denied, audio wont be recorded in the file.");
            }
        }

        private void OnPermissionGranted(string permission)
        {
            MLPluginLog.Debug($"Granted {permission}.");
        }

        private void StartVideoCapture()
        {
            skipFrame = false;
            var result = MLPermissions.CheckPermission(MLPermission.Camera);
            MLResult.DidNativeCallSucceed(result.Result, nameof(MLPermissions.RequestPermission));
            MLPluginLog.Debug($"CLPermissions.CheckPermission {result}");
            if (!result.IsOk)
            {
                Debug.LogError($"{MLPermission.Camera} permission denied. Video will not be recorded.");
                return;
            }


            StartPreview();
            StartCoroutine(StopVideo());

        }

        private void StartPreview()
        {



#if !UNITY_EDITOR
            mediaPlayerBehavior.MediaPlayer.OnPrepared += MediaPlayerOnOnPrepared;
            mediaPlayerBehavior.MediaPlayer.OnCompletion += MediaPlayerOnCompletion;
#endif
            string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + validFileFormat;
            recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);

            CameraRecorderConfig config = CameraRecorderConfig.CreateDefault();
            config.Width = streamCapabilities[0].Width;
            config.Height = streamCapabilities[0].Height;
            config.FrameRate = MapFrameRate(FrameRate);

            cameraRecorder.StartRecording(recordedFilePath, config);

            int MapFrameRate(MLCamera.CaptureFrameRate frameRate)
            {
                switch (frameRate)
                {
                    case MLCamera.CaptureFrameRate.None: return 0;
                    case MLCamera.CaptureFrameRate._15FPS: return 15;
                    case MLCamera.CaptureFrameRate._30FPS: return 30;
                    case MLCamera.CaptureFrameRate._60FPS: return 60;
                    default: return 0;
                }
            }




            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
            captureConfig.CaptureFrameRate = FrameRate;
            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[1];
            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], MLCameraBase.OutputFormat.YUV_420_888);

            captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;


            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                captureCamera.PreCaptureAEAWB();

                if (CaptureType == MLCamera.CaptureType.Video)
                {
                    result = captureCamera.CaptureVideoStart();
                    isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));
                    if (isCapturingVideo)
                    {
                        cameraCaptureVisualizer.DisplayCapture(captureConfig.StreamConfigs[0].OutputFormat, RecordToFile);
                    }
                }

                if (CaptureType == MLCamera.CaptureType.Preview)
                {
                    result = captureCamera.CapturePreviewStart();
                    isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
                    if (isCapturingPreview)
                    {
                        cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, RecordToFile);
                    }
                }
            }
        }

        private void ConnectCamera()
        {
            MLCamera.ConnectContext context = MLCamera.ConnectContext.Create();
            context.Flags = MLCamera.ConnectFlag.CamOnly;
            context.EnableVideoStabilization = true;

            captureCamera = MLCamera.CreateAndConnect(context);

            if (captureCamera != null)
            {
                print("Camera device connected");
                if (GetImageStreamCapabilities())
                {
                    print("Camera device received stream caps");
                    captureCamera.OnRawVideoFrameAvailable += OnCaptureRawVideoFrameAvailable;
                    captureCamera.OnRawImageAvailable += OnCaptureRawImageComplete;

                    StartVideoCapture();
                }
            }

        }
        private bool GetImageStreamCapabilities()
        {
            var result =
                captureCamera.GetStreamCapabilities(out MLCamera.StreamCapabilitiesInfo[] streamCapabilitiesInfo);

            if (!result.IsOk)
            {
                Debug.Log("Could not get Stream capabilities Info.");
                return false;
            }

            streamCapabilities = new List<MLCamera.StreamCapability>();

            for (int i = 0; i < streamCapabilitiesInfo.Length; i++)
            {
                foreach (var streamCap in streamCapabilitiesInfo[i].StreamCapabilities)
                {
                    streamCapabilities.Add(streamCap);
                }
            }

            return streamCapabilities.Count > 0;
        }
        private void OnCaptureRawVideoFrameAvailable(MLCamera.CameraOutput capturedFrame, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedFrame);
        }

        /// <summary>
        /// Handles the event of a new image getting captured.
        /// </summary>
        /// <param name="capturedImage">Captured frame.</param>
        /// <param name="resultExtras">Results Extras.</param>
        private void OnCaptureRawImageComplete(MLCamera.CameraOutput capturedImage, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedImage);
        }

        /// <summary>
        /// Stops recording.
        /// </summary>
        private void StopRecording()
        {
            MLResult result = cameraRecorder.EndRecording();
            if (!result.IsOk)
            {
                Debug.Log("Saving Recording failed, reason:" + result);
                recordedFilePath = string.Empty;
            }
            else
            {
                Debug.Log("Recording saved at path: " + recordedFilePath);
            }
        }

        private IEnumerator StopVideo()
        {
            float startTimestamp = Time.realtimeSinceStartup;
            while (Time.realtimeSinceStartup - startTimestamp < 10)
            {
                yield return null;
            }

            StopVideoCapture();
        }

        private void StopVideoCapture()
        {


            if (isCapturingVideo)
            {
                captureCamera.CaptureVideoStop();
            }
            else if (isCapturingPreview)
            {
                captureCamera.CapturePreviewStop();
            }

            cameraCaptureVisualizer.HideRenderer();

            if (RecordToFile)
            {
                StopRecording();
                // DisplayPlayback();
            }

            isCapturingVideo = false;
            isCapturingPreview = false;
        }

    private void MediaPlayerOnOnPrepared(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.Play();
#endif
        }

        private void MediaPlayerOnCompletion(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.StopMLMediaPlayer();
#endif
            mediaPlayerBehavior.gameObject.SetActive(false);
            mediaPlayerBehavior.Reset();
        }
    }
}

Any guidance or advice on how to achieve this simultaneous display and recording would be greatly appreciated.

Looking forward to your expert insights.

Best regards,

@sfernandez Hope you are doing well. Following up regarding any update about discussed issues during meeting. Did you make any changes to existing code?

Kind regards,

Hi @usman.bashir I am currently working to update our examples to include your use case, since it was missing. I am wrapping up my work on it and will post a modified script here as soon as I can. Thank you for your patience

Hi @usman.bashir
in order to both record and preview from the main camera, you need to get that second stream started like we talked about in the call. If you modify the StartPreview function just a little bit you can achieve this.
you will want to modify the code around line 166 similar to the snippet below, but basically you are adding a second StreamConfig to the captureConfig and then forcing the result of PrepareCapture to do both recording and previewing. Also in the DisplayPreviewCapture we are passing false instead of RecordToFile so that it displays the preview capture even though we are recording to file. Hope this helps. I am leaving commented out code so you can see the changes more easily.

captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[2];
            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], MLCameraBase.OutputFormat.YUV_420_888);
            captureConfig.StreamConfigs[1] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[1], MLCameraBase.OutputFormat.YUV_420_888);

            captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;


            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                captureCamera.PreCaptureAEAWB();

                // if (CaptureType == MLCamera.CaptureType.Video)
                // {
                    result = captureCamera.CaptureVideoStart();
                    isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));
                    // if (isCapturingVideo)
                    // {
                    //     cameraCaptureVisualizer.DisplayCapture(captureConfig.StreamConfigs[0].OutputFormat, RecordToFile);
                    // }
                // }
                //
                // if (CaptureType == MLCamera.CaptureType.Preview)
                // {
                    result = captureCamera.CapturePreviewStart();
                    isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
                    if (isCapturingPreview)
                    {
                        cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, false);
                    }
                //}
            }
1 Like

Thank you so much, @sfernandez . Let me go through this, I will get back to you shortly.

Thanks once again.

I have updated the function as per your instructions @sfernandez . I will inform you after testing it properly.

private void StartPreview()
{
#if !UNITY_EDITOR
    mediaPlayerBehavior.MediaPlayer.OnPrepared += MediaPlayerOnOnPrepared;
    mediaPlayerBehavior.MediaPlayer.OnCompletion += MediaPlayerOnCompletion;
#endif
    string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + validFileFormat;
    recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);

    CameraRecorderConfig config = CameraRecorderConfig.CreateDefault();
    config.Width = streamCapabilities[0].Width;
    config.Height = streamCapabilities[0].Height;
    config.FrameRate = MapFrameRate(FrameRate);

    cameraRecorder.StartRecording(recordedFilePath, config);

    int MapFrameRate(MLCamera.CaptureFrameRate frameRate)
    {
        switch (frameRate)
        {
            case MLCamera.CaptureFrameRate.None: return 0;
            case MLCamera.CaptureFrameRate._15FPS: return 15;
            case MLCamera.CaptureFrameRate._30FPS: return 30;
            case MLCamera.CaptureFrameRate._60FPS: return 60;
            default: return 0;
        }
    }

    MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
    captureConfig.CaptureFrameRate = FrameRate;
    captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[2];
    captureConfig.StreamConfigs[0] =
        MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], MLCameraBase.OutputFormat.YUV_420_888);
    captureConfig.StreamConfigs[1] =
        MLCamera.CaptureStreamConfig.Create(streamCapabilities[1], MLCameraBase.OutputFormat.YUV_420_888);

    captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;

    MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

    if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
    {
        captureCamera.PreCaptureAEAWB();

        result = captureCamera.CaptureVideoStart();
        isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));

        result = captureCamera.CapturePreviewStart();
        isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
        if (isCapturingPreview)
        {
            cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, false);
        }
    }
}

Dear @sfernandez ,

I trust you are doing well. I am still unbale to get Camera Preview on front screen of app. After making your changes, I am getting these logs;

2023/06/21 18:16:20.752 17971 21984 Debug ml_camera_client  released preview buffer 1877 timestamp = 1858423510016
2023/06/21 18:16:20.768 17971 17988 Debug ml_camera_client capturecompletecount = 1850 timestamp = 1858440570971
2023/06/21 18:16:20.768 17971 17988 Debug ml_camera_client capture complete for 1858440570971
2023/06/21 18:16:20.769 17971 17987 Debug ml_camera_client  got preview buffer 1842 timestamp = 1858440570971
2023/06/21 18:16:20.769 17971 21986 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.769 17971 21986 Debug ml_camera_client  released preview buffer 1878 timestamp = 1858440570971
2023/06/21 18:16:20.785 17971 17987 Debug ml_camera_client capturecompletecount = 1851 timestamp = 1858456985143
2023/06/21 18:16:20.785 17971 17987 Debug ml_camera_client capture complete for 1858456985143
2023/06/21 18:16:20.785 17971 17988 Debug ml_camera_client  got preview buffer 1843 timestamp = 1858456985143
2023/06/21 18:16:20.785 17971 21988 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.785 17971 21988 Debug ml_camera_client  released preview buffer 1879 timestamp = 1858456985143
2023/06/21 18:16:20.801 17971 17988 Debug ml_camera_client capturecompletecount = 1852 timestamp = 1858473788215
2023/06/21 18:16:20.801 17971 17988 Debug ml_camera_client capture complete for 1858473788215
2023/06/21 18:16:20.802 17971 17988 Debug ml_camera_client  got preview buffer 1844 timestamp = 1858473788215
2023/06/21 18:16:20.802 17971 21990 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.802 17971 21990 Debug ml_camera_client  released preview buffer 1880 timestamp = 1858473788215
2023/06/21 18:16:20.818 17971 17988 Debug ml_camera_client capturecompletecount = 1853 timestamp = 1858490386092
2023/06/21 18:16:20.818 17971 17988 Debug ml_camera_client capture complete for 1858490386092
2023/06/21 18:16:20.818 17971 17987 Debug ml_camera_client  got preview buffer 1845 timestamp = 1858490386092
2023/06/21 18:16:20.818 17971 21992 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.819 17971 21992 Debug ml_camera_client  released preview buffer 1881 timestamp = 1858490386092
2023/06/21 18:16:20.835 17971 17987 Debug ml_camera_client capturecompletecount = 1854 timestamp = 1858507046216
2023/06/21 18:16:20.835 17971 17987 Debug ml_camera_client capture complete for 1858507046216
2023/06/21 18:16:20.835 17971 17988 Debug ml_camera_client  got preview buffer 1846 timestamp = 1858507046216
2023/06/21 18:16:20.835 17971 21994 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.835 17971 21994 Debug ml_camera_client  released preview buffer 1882 timestamp = 1858507046216
2023/06/21 18:16:20.852 17971 17988 Debug ml_camera_client capturecompletecount = 1855 timestamp = 1858523890425
2023/06/21 18:16:20.852 17971 17988 Debug ml_camera_client capture complete for 1858523890425
2023/06/21 18:16:20.852 17971 17987 Debug ml_camera_client  got preview buffer 1847 timestamp = 1858523890425
2023/06/21 18:16:20.852 17971 21996 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.852 17971 21996 Debug ml_camera_client  released preview buffer 1883 timestamp = 1858523890425
2023/06/21 18:16:20.868 17971 17987 Debug ml_camera_client capturecompletecount = 1856 timestamp = 1858540606303
2023/06/21 18:16:20.868 17971 17987 Debug ml_camera_client capture complete for 1858540606303
2023/06/21 18:16:20.868 17971 17988 Debug ml_camera_client  got preview buffer 1848 timestamp = 1858540606303
2023/06/21 18:16:20.868 17971 21998 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.869 17971 21998 Debug ml_camera_client  released preview buffer 1884 timestamp = 1858540606303
2023/06/21 18:16:20.885 17971 17988 Debug ml_camera_client capturecompletecount = 1857 timestamp = 1858557250757
2023/06/21 18:16:20.885 17971 17987 Debug ml_camera_client  got preview buffer 1849 timestamp = 1858557250757
2023/06/21 18:16:20.885 17971 17988 Debug ml_camera_client capture complete for 1858557250757
2023/06/21 18:16:20.885 17971 22000 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.885 17971 22001 Info ml_camera_client Dropping packet because of missing graphics resource
2023/06/21 18:16:20.885 17971 22001 Debug ml_camera_client  released preview buffer 1885 timestamp = 1858557250757
2023/06/21 18:16:20.885 17971 22000 Debug ml_camera_client  released preview buffer 1886 timestamp = 1858557250757
2023/06/21 18:16:20.901 17971 17987 Debug ml_camera_client capturecompletecount = 1858 timestamp = 1858573848183
2023/06/21 18:16:20.901 17971 17987 Debug ml_camera_client capture complete for 1858573848183
2023/06/21 18:16:20.902 17971 17987 Debug ml_camera_client  got preview buffer 1850 timestamp = 1858573848183
2023/06/21 18:16:20.902 17971 22003 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.902 17971 22003 Debug ml_camera_client  released preview buffer 1887 timestamp = 1858573848183
2023/06/21 18:16:20.918 17971 17987 Debug ml_camera_client capturecompletecount = 1859 timestamp = 1858590491045
2023/06/21 18:16:20.918 17971 17987 Debug ml_camera_client capture complete for 1858590491045
2023/06/21 18:16:20.919 17971 17988 Debug ml_camera_client  got preview buffer 1851 timestamp = 1858590491045
2023/06/21 18:16:20.919 17971 22005 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.919 17971 22005 Debug ml_camera_client  released preview buffer 1888 timestamp = 1858590491045
2023/06/21 18:16:20.934 17971 17988 Debug ml_camera_client capturecompletecount = 1860 timestamp = 1858607037495
2023/06/21 18:16:20.935 17971 17988 Debug ml_camera_client capture complete for 1858607037495
2023/06/21 18:16:20.935 17971 17987 Debug ml_camera_client  got preview buffer 1852 timestamp = 1858607037495
2023/06/21 18:16:20.935 17971 22007 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.935 17971 22007 Debug ml_camera_client  released preview buffer 1889 timestamp = 1858607037495
2023/06/21 18:16:20.951 17971 17987 Debug ml_camera_client capturecompletecount = 1861 timestamp = 1858623622939
2023/06/21 18:16:20.951 17971 17987 Debug ml_camera_client capture complete for 1858623622939
2023/06/21 18:16:20.951 17971 17988 Debug ml_camera_client  got preview buffer 1853 timestamp = 1858623622939
2023/06/21 18:16:20.951 17971 22009 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.952 17971 22009 Debug ml_camera_client  released preview buffer 1890 timestamp = 1858623622939
2023/06/21 18:16:20.968 17971 17988 Debug ml_camera_client capturecompletecount = 1862 timestamp = 1858640272583
2023/06/21 18:16:20.968 17971 17988 Debug ml_camera_client capture complete for 1858640272583
2023/06/21 18:16:20.968 17971 17987 Debug ml_camera_client  got preview buffer 1854 timestamp = 1858640272583
2023/06/21 18:16:20.968 17971 22011 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.968 17971 22011 Debug ml_camera_client  released preview buffer 1891 timestamp = 1858640272583
2023/06/21 18:16:20.984 17971 17987 Debug ml_camera_client capturecompletecount = 1863 timestamp = 1858656808834
2023/06/21 18:16:20.984 17971 17987 Debug ml_camera_client capture complete for 1858656808834
2023/06/21 18:16:20.985 17971 17988 Debug ml_camera_client  got preview buffer 1855 timestamp = 1858656808834
2023/06/21 18:16:20.985 17971 22013 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:20.985 17971 22013 Debug ml_camera_client  released preview buffer 1892 timestamp = 1858656808834
2023/06/21 18:16:21.001 17971 17988 Debug ml_camera_client capturecompletecount = 1864 timestamp = 1858673871373
2023/06/21 18:16:21.002 17971 17988 Debug ml_camera_client capture complete for 1858673871373
2023/06/21 18:16:21.002 17971 17987 Debug ml_camera_client  got preview buffer 1856 timestamp = 1858673871373
2023/06/21 18:16:21.002 17971 22015 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.002 17971 22015 Debug ml_camera_client  released preview buffer 1893 timestamp = 1858673871373
2023/06/21 18:16:21.018 17971 17987 Debug ml_camera_client capturecompletecount = 1865 timestamp = 1858690350126
2023/06/21 18:16:21.018 17971 17987 Debug ml_camera_client capture complete for 1858690350126
2023/06/21 18:16:21.018 17971 17987 Debug ml_camera_client  got preview buffer 1857 timestamp = 1858690350126
2023/06/21 18:16:21.018 17971 22017 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.018 17971 22017 Debug ml_camera_client  released preview buffer 1894 timestamp = 1858690350126
2023/06/21 18:16:21.034 17971 17987 Debug ml_camera_client capturecompletecount = 1866 timestamp = 1858706992256
2023/06/21 18:16:21.034 17971 17987 Debug ml_camera_client capture complete for 1858706992256
2023/06/21 18:16:21.035 17971 17988 Debug ml_camera_client  got preview buffer 1858 timestamp = 1858706992256
2023/06/21 18:16:21.035 17971 22019 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.035 17971 22019 Debug ml_camera_client  released preview buffer 1895 timestamp = 1858706992256
2023/06/21 18:16:21.051 17971 17988 Debug ml_camera_client capturecompletecount = 1867 timestamp = 1858723474556
2023/06/21 18:16:21.051 17971 17988 Debug ml_camera_client capture complete for 1858723474556
2023/06/21 18:16:21.051 17971 17987 Debug ml_camera_client  got preview buffer 1859 timestamp = 1858723474556
2023/06/21 18:16:21.051 17971 22021 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.051 17971 22021 Debug ml_camera_client  released preview buffer 1896 timestamp = 1858723474556
2023/06/21 18:16:21.068 17971 17987 Debug ml_camera_client capturecompletecount = 1868 timestamp = 1858740284712
2023/06/21 18:16:21.068 17971 17987 Debug ml_camera_client capture complete for 1858740284712
2023/06/21 18:16:21.068 17971 17987 Debug ml_camera_client  got preview buffer 1860 timestamp = 1858740284712
2023/06/21 18:16:21.068 17971 22023 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.068 17971 22023 Debug ml_camera_client  released preview buffer 1897 timestamp = 1858740284712
2023/06/21 18:16:21.084 17971 17987 Debug ml_camera_client capturecompletecount = 1869 timestamp = 1858756932352
2023/06/21 18:16:21.084 17971 17987 Debug ml_camera_client capture complete for 1858756932352
2023/06/21 18:16:21.085 17971 17988 Debug ml_camera_client  got preview buffer 1861 timestamp = 1858756932352
2023/06/21 18:16:21.085 17971 22025 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.085 17971 22025 Debug ml_camera_client  released preview buffer 1898 timestamp = 1858756932352
2023/06/21 18:16:21.101 17971 17988 Debug ml_camera_client capturecompletecount = 1870 timestamp = 1858773834059
2023/06/21 18:16:21.101 17971 17988 Debug ml_camera_client capture complete for 1858773834059
2023/06/21 18:16:21.102 17971 17987 Debug ml_camera_client  got preview buffer 1862 timestamp = 1858773834059
2023/06/21 18:16:21.102 17971 22027 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.102 17971 22027 Debug ml_camera_client  released preview buffer 1899 timestamp = 1858773834059
2023/06/21 18:16:21.118 17971 17987 Debug ml_camera_client capturecompletecount = 1871 timestamp = 1858790447785
2023/06/21 18:16:21.118 17971 17987 Debug ml_camera_client capture complete for 1858790447785
2023/06/21 18:16:21.118 17971 17988 Debug ml_camera_client  got preview buffer 1863 timestamp = 1858790447785
2023/06/21 18:16:21.118 17971 22029 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.118 17971 22029 Debug ml_camera_client  released preview buffer 1900 timestamp = 1858790447785
2023/06/21 18:16:21.136 17971 17989 Debug ml_camera_client capturecompletecount = 1872 timestamp = 1858808093397
2023/06/21 18:16:21.136 17971 17987 Debug ml_camera_client  got preview buffer 1864 timestamp = 1858808093397
2023/06/21 18:16:21.151 17971 17992 Info ml_camera_client stopRepeatingCaptureVideo device state = STreaming numStreamConfigs = 2 
2023/06/21 18:16:21.151 17971 17992 Info ml_camera_client  Stream 0 type = Video resolution = 480P state = Streaming 
2023/06/21 18:16:21.151 17971 17992 Info ml_camera_client Stream 1 type = Preview resiolution = 480P state = Streaming 
2023/06/21 18:16:21.182 17971 17989 Debug ml_camera_client capture complete for 1858808093397
2023/06/21 18:16:21.182 17971 22033 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.182 17971 22033 Debug ml_camera_client  released preview buffer 1901 timestamp = 1858808093397
2023/06/21 18:16:21.182 17971 22032 Info ml_camera_client Dropping packet because of missing graphics resource
2023/06/21 18:16:21.182 17971 22032 Debug ml_camera_client  released preview buffer 1902 timestamp = 1858808093397
2023/06/21 18:16:21.184 17971 17987 Debug ml_camera_client capturecompletecount = 1873 timestamp = 1858856156763
2023/06/21 18:16:21.184 17971 17987 Debug ml_camera_client capture complete for 1858856156763
2023/06/21 18:16:21.184 17971 22030 Debug ml_camera_client  got preview buffer 1865 timestamp = 1858856156763
2023/06/21 18:16:21.184 17971 22035 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.184 17971 22035 Debug ml_camera_client  released preview buffer 1903 timestamp = 1858856156763
2023/06/21 18:16:21.185 17971 22030 Debug ml_camera_client capturecompletecount = 1874 timestamp = 1858857980263
2023/06/21 18:16:21.185 17971 22030 Debug ml_camera_client capture complete for 1858857980263
2023/06/21 18:16:21.186 17971 17987 Debug ml_camera_client  got preview buffer 1866 timestamp = 1858857980263
2023/06/21 18:16:21.186 17971 22037 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.186 17971 22037 Debug ml_camera_client  released preview buffer 1904 timestamp = 1858857980263
2023/06/21 18:16:21.187 17971 17987 Debug ml_camera_client capturecompletecount = 1875 timestamp = 1858859728972
2023/06/21 18:16:21.187 17971 17987 Debug ml_camera_client capture complete for 1858859728972
2023/06/21 18:16:21.187 17971 17987 Debug ml_camera_client  got preview buffer 1867 timestamp = 1858859728972
2023/06/21 18:16:21.188 17971 22039 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.188 17971 22039 Debug ml_camera_client  released preview buffer 1905 timestamp = 1858859728972
2023/06/21 18:16:21.201 17971 17987 Debug ml_camera_client capturecompletecount = 1876 timestamp = 1858873468018
2023/06/21 18:16:21.201 17971 17987 Debug ml_camera_client capture complete for 1858873468018
2023/06/21 18:16:21.201 17971 22030 Debug ml_camera_client  got preview buffer 1868 timestamp = 1858873468018
2023/06/21 18:16:21.201 17971 22041 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.201 17971 22041 Debug ml_camera_client  released preview buffer 1906 timestamp = 1858873468018
2023/06/21 18:16:21.217 17971 22030 Debug ml_camera_client capturecompletecount = 1877 timestamp = 1858890212790
2023/06/21 18:16:21.218 17971 22030 Debug ml_camera_client capture complete for 1858890212790
2023/06/21 18:16:21.218 17971 17987 Debug ml_camera_client  got preview buffer 1869 timestamp = 1858890212790
2023/06/21 18:16:21.218 17971 22043 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.218 17971 22043 Debug ml_camera_client  released preview buffer 1907 timestamp = 1858890212790
2023/06/21 18:16:21.234 17971 17987 Debug ml_camera_client capturecompletecount = 1878 timestamp = 1858907055356
2023/06/21 18:16:21.234 17971 17987 Debug ml_camera_client capture complete for 1858907055356
2023/06/21 18:16:21.235 17971 22030 Debug ml_camera_client  got preview buffer 1870 timestamp = 1858907055356
2023/06/21 18:16:21.235 17971 22045 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.235 17971 22045 Debug ml_camera_client  released preview buffer 1908 timestamp = 1858907055356
2023/06/21 18:16:21.267 17971 22030 Debug ml_camera_client  got preview buffer 1871 timestamp = 1858939867090
2023/06/21 18:16:21.267 17971 17987 Debug ml_camera_client capturecompletecount = 1879 timestamp = 1858939867090
2023/06/21 18:16:21.267 17971 17987 Debug ml_camera_client capture complete for 1858939867090
2023/06/21 18:16:21.267 17971 22047 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.267 17971 22047 Debug ml_camera_client  released preview buffer 1909 timestamp = 1858939867090
2023/06/21 18:16:21.269 17971 17992 Info ml_camera_client stopRepeatingCapturePreview device state = STreaming numStreamConfigs = 2 
2023/06/21 18:16:21.269 17971 17992 Info ml_camera_client  Stream 0 type = Video resolution = 480P state = Configured 
2023/06/21 18:16:21.269 17971 17992 Info ml_camera_client Stream 1 type = Preview resiolution = 480P state = Streaming 
2023/06/21 18:16:21.284 17971 17987 Debug ml_camera_client  got preview buffer 1872 timestamp = 1858956852904
2023/06/21 18:16:21.284 17971 17987 Debug ml_camera_client capturecompletecount = 1880 timestamp = 1858956852904
2023/06/21 18:16:21.284 17971 17987 Debug ml_camera_client capture complete for 1858956852904
2023/06/21 18:16:21.285 17971 22049 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.285 17971 22049 Debug ml_camera_client  released preview buffer 1910 timestamp = 1858956852904
2023/06/21 18:16:21.301 17971 17987 Debug ml_camera_client  got preview buffer 1873 timestamp = 1858973462213
2023/06/21 18:16:21.301 17971 17987 Debug ml_camera_client capturecompletecount = 1881 timestamp = 1858973462213
2023/06/21 18:16:21.301 17971 17987 Debug ml_camera_client capture complete for 1858973462213
2023/06/21 18:16:21.301 17971 22051 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.301 17971 22051 Debug ml_camera_client  released preview buffer 1911 timestamp = 1858973462213
2023/06/21 18:16:21.317 17971 17987 Debug ml_camera_client  got preview buffer 1874 timestamp = 1858990140531
2023/06/21 18:16:21.317 17971 17987 Debug ml_camera_client capturecompletecount = 1882 timestamp = 1858990140531
2023/06/21 18:16:21.318 17971 17987 Debug ml_camera_client capture complete for 1858990140531
2023/06/21 18:16:21.318 17971 22053 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.318 17971 22053 Debug ml_camera_client  released preview buffer 1912 timestamp = 1858990140531
2023/06/21 18:16:21.334 17971 17987 Debug ml_camera_client  got preview buffer 1875 timestamp = 1859007206275
2023/06/21 18:16:21.335 17971 17987 Debug ml_camera_client capturecompletecount = 1883 timestamp = 1859007206275
2023/06/21 18:16:21.335 17971 17987 Debug ml_camera_client capture complete for 1859007206275
2023/06/21 18:16:21.335 17971 22055 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.335 17971 22055 Debug ml_camera_client  released preview buffer 1913 timestamp = 1859007206275
2023/06/21 18:16:21.351 17971 17987 Debug ml_camera_client  got preview buffer 1876 timestamp = 1859023449427
2023/06/21 18:16:21.351 17971 17987 Debug ml_camera_client capturecompletecount = 1884 timestamp = 1859023449427
2023/06/21 18:16:21.351 17971 17987 Debug ml_camera_client capture complete for 1859023449427
2023/06/21 18:16:21.351 17971 22057 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.351 17971 22057 Debug ml_camera_client  released preview buffer 1914 timestamp = 1859023449427
2023/06/21 18:16:21.367 17971 17987 Debug ml_camera_client  got preview buffer 1877 timestamp = 1859039986309
2023/06/21 18:16:21.367 17971 17987 Debug ml_camera_client capturecompletecount = 1885 timestamp = 1859039986309
2023/06/21 18:16:21.367 17971 17987 Debug ml_camera_client capture complete for 1859039986309
2023/06/21 18:16:21.368 17971 22059 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.368 17971 22059 Debug ml_camera_client  released preview buffer 1915 timestamp = 1859039986309
2023/06/21 18:16:21.384 17971 17987 Debug ml_camera_client  got preview buffer 1878 timestamp = 1859056572454
2023/06/21 18:16:21.384 17971 22030 Debug ml_camera_client capturecompletecount = 1886 timestamp = 1859056572454
2023/06/21 18:16:21.384 17971 22030 Debug ml_camera_client capture complete for 1859056572454
2023/06/21 18:16:21.384 17971 22061 Debug ml_camera_client Ready for preview frame callback callback
2023/06/21 18:16:21.384 17971 22061 Debug ml_camera_client  released preview buffer 1916 timestamp = 1859056572454
2023/06/21 18:16:21.389 17971 17992 Error Camera-Device endConfigure fail Status(-8, EX_SERVICE_SPECIFIC): '3: endConfigure:739: Camera 0: Unsupported set of inputs/outputs provided'
2023/06/21 18:16:21.396 17971 22065 Info ml_camera_client Camonly OnAvailable CamId = 0
2023/06/21 18:16:21.398 17971 17992 Debug MediaPlayer isPlaying: no active player
2023/06/21 18:16:21.398 17971 17992 Debug MediaPlayer isPlaying: no active player
2023/06/21 18:16:21.478 17971 18041 Debug AudioTrack stop(42): called with 912384 frames delivered


May be it can help you understand the issue.

Best,

Muhammad Usman Bashir

I am posting further testing results:

Here are some additional logs:

2023/06/21 19:04:15.592 5771 5771 Info chatty uid=10125(com.DefaultCompany.FeatureConsult) identical 4 lines
2023/06/21 19:04:15.592 5771 5771 Warn UnityMain type=1400 audit(0.0:56765): avc: denied { search } for name="traces" dev="nvme0n1p37" ino=4980739 scontext=u:r:untrusted_app:s0:c125,c256,c512,c768 tcontext=u:object_r:trace_data_file:s0 tclass=dir permissive=0
2023/06/21 19:04:15.609 5771 5794 Error vulkan internal vkGetInstanceProcAddr called for vkEnumerateInstanceExtensionProperties with an instance
2023/06/21 19:04:15.609 5771 5794 Info Unity [XR] [XRPreInit]: Telling EGL/Vulkan to use the offscreen swapchain!
2023/06/21 19:04:15.610 5771 5794 Info vulkan Loaded layer VK_LAYER_MAGICLEAP_dirty_tile_map
2023/06/21 19:04:15.621 5771 5794 Error vulkan internal vkGetInstanceProcAddr called for vkEnumerateInstanceExtensionProperties with an instance
2023/06/21 19:04:15.657 5771 5794 Warn Android_FMOD_MLAudio OutputMLAudio::getDescriptionEx, ...
2023/06/21 19:04:15.663 5771 5912 Warn AudioTrack Use of stream types is deprecated for operations other than volume control
2023/06/21 19:04:15.663 5771 5912 Warn AudioTrack See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2023/06/21 19:04:15.756 5771 5794 Warn Unity The referenced script (Unknown) on this Behaviour is missing!
2023/06/21 19:04:15.756 5771 5794 Warn Unity The referenced script on this Behaviour (Game Object '<null>') is missing!
2023/06/21 19:04:15.763 5771 5794 Info Unity XRGeneral Settings awakening...
2023/06/21 19:04:15.763 5771 5794 Info Unity UnityEngine.XR.Management.XRGeneralSettings:Awake()
2023/06/21 19:04:15.763 5771 5794 Info Unity 
2023/06/21 19:04:15.767 5771 5794 Info IL2CPP Locale en-US
2023/06/21 19:04:15.803 5771 5794 Info Unity Setting loading lib path in xr package
2023/06/21 19:04:15.812 5771 5794 Warn Unity [XR] Adding ptr for typeid 127597114426840
2023/06/21 19:04:15.812 5771 5794 Info Unity [XR] Loading dll from path libperception.magicleap.so
2023/06/21 19:04:15.918 5771 5794 Warn Unity [XR] Adding ptr for typeid 127597114426904
2023/06/21 19:04:15.918 5771 5794 Info Unity [XR] Loading dll from path libgraphics.magicleap.so
2023/06/21 19:04:15.921 5771 5794 Verbose OpenXR-Loader Verbose [GENERAL | xrCreateInstance | OpenXR-Loader] : Entering loader trampoline
2023/06/21 19:04:15.921 5771 5794 Info OpenXR-Loader Info [GENERAL |  | OpenXR-Loader] : RuntimeManifestFile::FindManifestFiles - using global runtime file /system/etc/openxr/1/active_runtime.json
2023/06/21 19:04:15.921 5771 5794 Info OpenXR-Loader Info [GENERAL |  | OpenXR-Loader] : RuntimeManifestFile::CreateIfValid - attempting to load /system/etc/openxr/1/active_runtime.json
2023/06/21 19:04:15.923 5771 5794 Info OpenXR-Loader Info [GENERAL | xrCreateInstance | OpenXR-Loader] : RuntimeInterface::LoadRuntime succeeded loading runtime defined in manifest file /system/etc/openxr/1/active_runtime.json using interface version 1 and OpenXR API version 1.0
2023/06/21 19:04:15.923 5771 5794 Verbose OpenXR-Loader Verbose [GENERAL | xrCreateInstance | OpenXR-Loader] : Entering LoaderInstance::CreateInstance
2023/06/21 19:04:15.923 5771 5794 Verbose OpenXR-Loader Verbose [GENERAL | xrCreateInstance | OpenXR-Loader] : Entering loader terminator
2023/06/21 19:04:15.924 5771 5794 Verbose OpenXR-Loader Verbose [GENERAL | xrCreateInstance | OpenXR-Loader] : Completed loader terminator
2023/06/21 19:04:15.925 5771 5794 Info OpenXR-Loader Info [GENERAL | xrCreateInstance | OpenXR-Loader] : LoaderInstance::CreateInstance succeeded with 0 layers enabled and runtime interface - created instance = 0x0000740c85cad000
2023/06/21 19:04:15.925 5771 5794 Verbose OpenXR-Loader Verbose [GENERAL | xrCreateInstance | OpenXR-Loader] : Completed loader trampoline
2023/06/21 19:04:16.193 5771 5794 Info Unity [XR] [XR::Display] Initializing RenderTextures with yflip blit set to 'true'
2023/06/21 19:04:16.204 5771 5794 Verbose MediaRouter Selecting route: RouteInfo{ name=Phone, description=null, status=null, category=RouteCategory{ name=System types=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO  groupable=false }, supportedTypes=ROUTE_TYPE_LIVE_AUDIO ROUTE_TYPE_LIVE_VIDEO , presentationDisplay=null }
2023/06/21 19:04:16.217 5771 5794 Info Input6DofFilter input_6dof_filter.cpp:92: Input6DofFilter was created
2023/06/21 19:04:16.217 5771 5794 Info Input6DofFilter input_6dof_filter.cpp:92: Input6DofFilter was created
2023/06/21 19:04:16.218 5771 5794 Warn Unity [XR] Adding ptr for typeid 127597114427032
2023/06/21 19:04:16.218 5771 5794 Info Unity [XR] Loading dll from path libinput.magicleap.so
2023/06/21 19:04:16.219 5771 5794 Info ml_input ml_input.cpp:1386: At application start, found controller device 257, type 1, registered as index 0
2023/06/21 19:04:16.279 5771 5907 Info Unity [XR] [XR::Display] singlePassRendering: true 
2023/06/21 19:04:16.296 5771 5794 Warn Unity [XR] Adding ptr for typeid 127597114428248
2023/06/21 19:04:16.296 5771 5794 Info Unity [XR] Loading dll from path libUnityMagicLeap.so
2023/06/21 19:04:20.790 5771 5794 Info Unity cameraDeviceAvailable False
2023/06/21 19:04:20.796 5771 5971 Info ml_camera_client Camonly OnAvailable CamId = 0
2023/06/21 19:04:20.796 5771 5971 Info ml_camera_client Camonly OnAvailable CamId = 1
2023/06/21 19:04:20.797 5771 5973 Info ml_camera_client MixedRealityCamera OnAvailable
2023/06/21 19:04:20.799 5771 5794 Error Unity Error: RawVideoCaptureVisualizer._screenRendererYUV is not set, disabling script.
2023/06/21 19:04:20.804 5771 5771 Warn UnityGfxDeviceW type=1400 audit(0.0:57045): avc: denied { search } for name="traces" dev="nvme0n1p37" ino=4980739 scontext=u:r:untrusted_app:s0:c125,c256,c512,c768 tcontext=u:object_r:trace_data_file:s0 tclass=dir permissive=0
2023/06/21 19:04:20.812 5771 5771 Info chatty uid=10125(com.DefaultCompany.FeatureConsult) identical 3 lines
2023/06/21 19:04:20.812 5771 5771 Warn UnityGfxDeviceW type=1400 audit(0.0:57049): avc: denied { search } for name="traces" dev="nvme0n1p37" ino=4980739 scontext=u:r:untrusted_app:s0:c125,c256,c512,c768 tcontext=u:object_r:trace_data_file:s0 tclass=dir permissive=0
2023/06/21 19:04:20.865 5771 5794 Warn Unity A Canvas named "CameraRecording" with a render mode of ScreenSpaceOverlay is being used while VR is also enabled. This Canvas will continue to incur a rendering cost, but will not be visible while in VR. Is this intentional?
2023/06/21 19:04:20.872 5771 6052 Info ml_camera_client Camonly OnUnavailable CamId = 0
2023/06/21 19:04:20.877 5771 5794 Info Unity Camera device connected
2023/06/21 19:04:20.881 5771 5794 Info Unity Camera device received stream caps
2023/06/21 19:04:21.012 5771 5794 Debug MediaDeathNotifier MediaDeathNotifier Constructor
2023/06/21 19:04:21.023 5771 5794 Warn Unity [XR] Adding ptr for typeid 127597114427672
2023/06/21 19:04:21.023 5771 5794 Info Unity [XR] Loading dll from path libmedia_format.magicleap.so
2023/06/21 19:04:21.176 5771 5794 Info ml_camera_client  prepareCapture captureFrameRate = 60fps numStreamConfigs = 1 
2023/06/21 19:04:21.176 5771 5794 Info ml_camera_client  Stream 0 type = Video resolution = 480P 
2023/06/21 19:04:21.176 5771 5794 Info ml_camera_client Stream 1 type = Image resolution =  
2023/06/21 19:04:21.176 5771 5794 Info ml_camera_client  prepareCapture device state = Idle numStreamConfigs = 1 
2023/06/21 19:04:21.176 5771 5794 Info ml_camera_client  Stream 0 type = Video resolution = 480P state = Configured 
2023/06/21 19:04:21.176 5771 5794 Info ml_camera_client Stream 1 type =  resiolution =  state = Invalid 
2023/06/21 19:04:21.177 5771 5794 Debug ml_camera_client  PreCaptureAEAWB ++
2023/06/21 19:04:21.944 5771 5795 Warn Gralloc3 mapper 3.x is not supported
2023/06/21 19:04:21.945 5771 5795 Warn Gralloc3 allocator 3.x is not supported
2023/06/21 19:04:21.944 5771 5771 Warn Binder:5771_3 type=1400 audit(0.0:57110): avc: denied { search } for name="traces" dev="nvme0n1p37" ino=4980739 scontext=u:r:untrusted_app:s0:c125,c256,c512,c768 tcontext=u:object_r:trace_data_file:s0 tclass=dir permissive=0
2023/06/21 19:04:22.081 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.082 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.098 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.098 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.114 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.115 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.131 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.131 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.148 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.148 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.164 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.164 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.181 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.181 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.197 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.198 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.214 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.215 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.231 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.231 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.248 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.248 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.264 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.264 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.281 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.281 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.298 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.298 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.314 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.315 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.331 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.331 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.347 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.348 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.364 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.364 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.381 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.381 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.381 5771 5790 Debug ml_camera_client aeawb convergence signaled
2023/06/21 19:04:22.399 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.399 5771 5790 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.414 5771 5790 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.415 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.431 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.431 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.448 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.448 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.464 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.464 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.481 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.481 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.498 5771 5795 Info ml_camera_client aeawb frame listener
2023/06/21 19:04:22.498 5771 5795 Debug ml_camera_client aeawb session capturecompleted
2023/06/21 19:04:22.499 5771 5794 Error Camera-Device endConfigure fail Status(-8, EX_SERVICE_SPECIFIC): '3: endConfigure:739: Camera 0: Unsupported set of inputs/outputs provided'
2023/06/21 19:04:22.504 5771 5794 Info ml_camera_client startRepeatingCapturePreview device state = Idle numStreamConfigs = 1 
2023/06/21 19:04:22.504 5771 5794 Info ml_camera_client  Stream 0 type = Video resolution = 480P state = Configured 
2023/06/21 19:04:22.504 5771 5794 Info ml_camera_client Stream 1 type =  resiolution =  state = Invalid 
2023/06/21 19:04:22.504 5771 5794 Error ml_camera_client No stream configured for preview
2023/06/21 19:04:22.504 5771 5794 Error Unity Error: MLCameraCapturePreviewStart in the Magic Leap API failed. Reason: InvalidOperation 
2023/06/21 19:04:22.504 5771 5794 Error Unity Error: CapturePreviewStart in the Magic Leap API failed. Reason: InvalidOperation 
2023/06/21 19:04:22.504 5771 5794 Info Unity Camera device available
2023/06/21 19:04:25.517 5771 5817 Debug RefBase RefBase: Explicit destruction, weak count = 0 (in 0x740d27f85d68)
2023/06/21 19:04:25.517 5771 5817 Warn RefBase CallStack::getCurrentInternal not linked, returning null
2023/06/21 19:04:25.517 5771 5817 Warn RefBase CallStack::logStackInternal not linked
2023/06/21 19:04:27.700 5771 5771 Warn UnityGfxDeviceW type=1400 audit(0.0:57156): avc: denied { search } for name="traces" dev="nvme0n1p37" ino=4980739 scontext=u:r:untrusted_app:s0:c125,c256,c512,c768 tcontext=u:object_r:trace_data_file:s0 tclass=dir permissive=0
2023/06/21 19:04:32.513 5771 5794 Info ml_camera_client stopRepeatingCaptureVideo device state = Idle numStreamConfigs = 1 
2023/06/21 19:04:32.513 5771 5794 Info ml_camera_client  Stream 0 type = Video resolution = 480P state = Configured 
2023/06/21 19:04:32.513 5771 5794 Info ml_camera_client Stream 1 type =  resiolution =  state = Invalid 
2023/06/21 19:04:32.513 5771 5794 Error ml_camera_client stop video called when device not streaming
2023/06/21 19:04:32.513 5771 5794 Error Unity Error: MLCameraCaptureVideoStop in the Magic Leap API failed. Reason: InvalidOperation 
2023/06/21 19:04:32.514 5771 5794 Error Unity NullReferenceException: Object reference not set to an instance of an object.
2023/06/21 19:04:32.514 5771 5794 Error Unity   at MagicLeap.Examples.CameraCaptureVisualizer.HideRenderer () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/21 19:04:32.514 5771 5794 Error Unity   at MagicLeap.Examples.TestCameraRecording.StopVideoCapture () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/21 19:04:32.514 5771 5794 Error Unity   at MagicLeap.Examples.TestCameraRecording+<StopVideo>d__29.MoveNext () [0x00000] in <00000000000000000000000000000000>:0 
2023/06/21 19:04:32.514 5771 5794 Error Unity   at UnityEngine.SetupCoroutine.InvokeMoveNext (System.Collections.IEnumerator enumerator, System.IntPtr returnValueAddress) [0x00000] in <00000000000000000000000000000000>:0 


Hi @usman.bashir could you please post your whole script, because I cannot see where the error is originating in the snippet. Thank you

Here is the latest updated code stack:

using System.Collections;
using System.Collections.Generic;
using MagicLeap.Core;
using UnityEngine;
using UnityEngine.XR.MagicLeap;
using System;


namespace MagicLeap.Examples
{

    /// <summary>
    /// This class handles video recording and image capturing based on controller
    /// input.
    /// </summary>
    /// 


    public class TestCameraRecording : MonoBehaviour
    {
        private MLCamera.CaptureFrameRate FrameRate = MLCamera.CaptureFrameRate._60FPS;
        private MLCamera.OutputFormat OutputFormat = MLCamera.OutputFormat.YUV_420_888;
        private MLCamera captureCamera;
        private bool isCapturingVideo = true;

        private bool skipFrame = false;

        private string recordedFilePath;
        private readonly CameraRecorder cameraRecorder = new CameraRecorder();


        [SerializeField, Tooltip("Reference to media player behavior used in camera capture playback")]
        private MLMediaPlayerBehavior mediaPlayerBehavior;
        private const string validFileFormat = ".mp4";

        private bool RecordToFile = true;

        private bool isCapturingPreview;

        private MLCamera.CaptureType CaptureType = MLCamera.CaptureType.Video;


        private List<MLCamera.StreamCapability> streamCapabilities;

        private readonly MLPermissions.Callbacks permissionCallbacks = new MLPermissions.Callbacks();

        private bool cameraDeviceAvailable;

        [SerializeField, Tooltip("Refrence to the Raw Video Capture Visualizer gameobject for YUV frames")]
        private CameraCaptureVisualizer cameraCaptureVisualizer = null;


        private void Awake()
        {
            permissionCallbacks.OnPermissionGranted += OnPermissionGranted;
            permissionCallbacks.OnPermissionDenied += OnPermissionDenied;
            permissionCallbacks.OnPermissionDeniedAndDontAskAgain += OnPermissionDenied;
        }

        // Start is called before the first frame update

        private void Start()
        {
            MLPermissions.RequestPermission(MLPermission.Camera, permissionCallbacks);
            MLPermissions.RequestPermission(MLPermission.RecordAudio, permissionCallbacks);
            TryEnableMLCamera();
        }

        private void TryEnableMLCamera()
        {
            if (!MLPermissions.CheckPermission(MLPermission.Camera).IsOk)
                return;

            StartCoroutine(EnableMLCamera());
        }

        private IEnumerator EnableMLCamera()
        {
            Debug.Log($"cameraDeviceAvailable {cameraDeviceAvailable}");
            while (!cameraDeviceAvailable)
            {
                MLResult result =
                    MLCamera.GetDeviceAvailabilityStatus(MLCamera.Identifier.Main, out cameraDeviceAvailable);
                if (!(result.IsOk && cameraDeviceAvailable))
                {
                    // Wait until camera device is available
                    yield return new WaitForSeconds(1.0f);
                }
            }

            yield return new WaitForEndOfFrame();
            ConnectCamera();
            Debug.Log("Camera device available");
        }

        private void OnPermissionDenied(string permission)
        {
            if (permission == MLPermission.Camera)
            {
                MLPluginLog.Error($"{permission} denied, example won't function.");
            }
            else if (permission == MLPermission.RecordAudio)
            {
                MLPluginLog.Error($"{permission} denied, audio wont be recorded in the file.");
            }
        }

        private void OnPermissionGranted(string permission)
        {
            MLPluginLog.Debug($"Granted {permission}.");
        }

        private void StartVideoCapture()
        {
            skipFrame = false;
            var result = MLPermissions.CheckPermission(MLPermission.Camera);
            MLResult.DidNativeCallSucceed(result.Result, nameof(MLPermissions.RequestPermission));
            MLPluginLog.Debug($"CLPermissions.CheckPermission {result}");
            if (!result.IsOk)
            {
                Debug.LogError($"{MLPermission.Camera} permission denied. Video will not be recorded.");
                return;
            }


            StartPreview();
            StartCoroutine(StopVideo());

        }

//        private void StartPreview()
//        {

//#if !UNITY_EDITOR
//                    mediaPlayerBehavior.MediaPlayer.OnPrepared += MediaPlayerOnOnPrepared;
//                    mediaPlayerBehavior.MediaPlayer.OnCompletion += MediaPlayerOnCompletion;
//#endif
//            string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + validFileFormat;
//            recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);

//            CameraRecorderConfig config = CameraRecorderConfig.CreateDefault();
//            config.Width = streamCapabilities[0].Width;
//            config.Height = streamCapabilities[0].Height;
//            config.FrameRate = MapFrameRate(FrameRate);

//            cameraRecorder.StartRecording(recordedFilePath, config);

//            int MapFrameRate(MLCamera.CaptureFrameRate frameRate)
//            {
//                switch (frameRate)
//                {
//                    case MLCamera.CaptureFrameRate.None: return 0;
//                    case MLCamera.CaptureFrameRate._15FPS: return 15;
//                    case MLCamera.CaptureFrameRate._30FPS: return 30;
//                    case MLCamera.CaptureFrameRate._60FPS: return 60;
//                    default: return 0;
//                }
//            }




//            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
//            captureConfig.CaptureFrameRate = FrameRate;
//            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[1];
//            captureConfig.StreamConfigs[0] =
//                MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], MLCameraBase.OutputFormat.YUV_420_888);

//            captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;


//            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

//            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
//            {
//                captureCamera.PreCaptureAEAWB();

//                if (CaptureType == MLCamera.CaptureType.Video)
//                {
//                    result = captureCamera.CaptureVideoStart();
//                    isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));
//                    if (isCapturingVideo)
//                    {
//                        cameraCaptureVisualizer.DisplayCapture(captureConfig.StreamConfigs[0].OutputFormat, RecordToFile);
//                    }
//                }

//                if (CaptureType == MLCamera.CaptureType.Preview)
//                {
//                    result = captureCamera.CapturePreviewStart();
//                    isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));
//                    if (isCapturingPreview)
//                    {
//                        cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, RecordToFile);
//                    }
//                }
//            }
//        }

        private void StartPreview()
        {
#if !UNITY_EDITOR
                    mediaPlayerBehavior.MediaPlayer.OnPrepared += MediaPlayerOnOnPrepared;
                    mediaPlayerBehavior.MediaPlayer.OnCompletion += MediaPlayerOnCompletion;
#endif
            string fileName = DateTime.Now.ToString("MM_dd_yyyy__HH_mm_ss") + validFileFormat;
            recordedFilePath = System.IO.Path.Combine(Application.persistentDataPath, fileName);

            CameraRecorderConfig config = CameraRecorderConfig.CreateDefault();
            config.Width = streamCapabilities[0].Width;
            config.Height = streamCapabilities[0].Height;
            config.FrameRate = MapFrameRate(FrameRate);

            cameraRecorder.StartRecording(recordedFilePath, config);

            int MapFrameRate(MLCamera.CaptureFrameRate frameRate)
            {
                switch (frameRate)
                {
                    case MLCamera.CaptureFrameRate.None: return 0;
                    case MLCamera.CaptureFrameRate._15FPS: return 15;
                    case MLCamera.CaptureFrameRate._30FPS: return 30;
                    case MLCamera.CaptureFrameRate._60FPS: return 60;
                    default: return 0;
                }
            }

            MLCamera.CaptureConfig captureConfig = new MLCamera.CaptureConfig();
            captureConfig.CaptureFrameRate = FrameRate;
            captureConfig.StreamConfigs = new MLCamera.CaptureStreamConfig[2];
            captureConfig.StreamConfigs[0] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[0], MLCameraBase.OutputFormat.YUV_420_888);
            captureConfig.StreamConfigs[1] =
                MLCamera.CaptureStreamConfig.Create(streamCapabilities[1], MLCameraBase.OutputFormat.YUV_420_888);

            captureConfig.StreamConfigs[0].Surface = cameraRecorder.MediaRecorder.InputSurface;

            MLResult result = captureCamera.PrepareCapture(captureConfig, out MLCamera.Metadata _);

            if (MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.PrepareCapture)))
            {
                captureCamera.PreCaptureAEAWB();

                result = captureCamera.CaptureVideoStart();
                isCapturingVideo = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CaptureVideoStart));

                result = captureCamera.CapturePreviewStart();
               
                isCapturingPreview = MLResult.DidNativeCallSucceed(result.Result, nameof(captureCamera.CapturePreviewStart));

                Debug.Log($"Start_Preview {isCapturingPreview}, {isCapturingVideo}");

                if (isCapturingPreview)
                {
                    cameraCaptureVisualizer.DisplayPreviewCapture(captureCamera.PreviewTexture, true);
                }
            }
        }

        private void ConnectCamera()
        {
            MLCamera.ConnectContext context = MLCamera.ConnectContext.Create();
            context.Flags = MLCamera.ConnectFlag.CamOnly;
            context.EnableVideoStabilization = true;

            captureCamera = MLCamera.CreateAndConnect(context);

            if (captureCamera != null)
            {
                print("Camera device connected");
                if (GetImageStreamCapabilities())
                {
                    print("Camera device received stream caps");
                    captureCamera.OnRawVideoFrameAvailable += OnCaptureRawVideoFrameAvailable;
                    captureCamera.OnRawImageAvailable += OnCaptureRawImageComplete;

                    StartVideoCapture();
                }
            }

        }
        private bool GetImageStreamCapabilities()
        {
            var result =
                captureCamera.GetStreamCapabilities(out MLCamera.StreamCapabilitiesInfo[] streamCapabilitiesInfo);

            if (!result.IsOk)
            {
                Debug.Log("Could not get Stream capabilities Info.");
                return false;
            }

            streamCapabilities = new List<MLCamera.StreamCapability>();

            for (int i = 0; i < streamCapabilitiesInfo.Length; i++)
            {
                foreach (var streamCap in streamCapabilitiesInfo[i].StreamCapabilities)
                {
                    streamCapabilities.Add(streamCap);
                }
            }

            return streamCapabilities.Count > 0;
        }
        private void OnCaptureRawVideoFrameAvailable(MLCamera.CameraOutput capturedFrame, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedFrame);
        }

        /// <summary>
        /// Handles the event of a new image getting captured.
        /// </summary>
        /// <param name="capturedImage">Captured frame.</param>
        /// <param name="resultExtras">Results Extras.</param>
        private void OnCaptureRawImageComplete(MLCamera.CameraOutput capturedImage, MLCamera.ResultExtras resultExtras, MLCamera.Metadata metadataHandle)
        {
            cameraCaptureVisualizer.OnCaptureDataReceived(resultExtras, capturedImage);
        }

        /// <summary>
        /// Stops recording.
        /// </summary>
        private void StopRecording()
        {
            MLResult result = cameraRecorder.EndRecording();
            if (!result.IsOk)
            {
                Debug.Log("Saving Recording failed, reason:" + result);
                recordedFilePath = string.Empty;
            }
            else
            {
                Debug.Log("Recording saved at path: " + recordedFilePath);
            }
        }

        private IEnumerator StopVideo()
        {
            float startTimestamp = Time.realtimeSinceStartup;
            while (Time.realtimeSinceStartup - startTimestamp < 10)
            {
                yield return null;
            }

            StopVideoCapture();
        }

        private void StopVideoCapture()
        {


            if (isCapturingVideo)
            {
                captureCamera.CaptureVideoStop();
            }
            else if (isCapturingPreview)
            {
                captureCamera.CapturePreviewStop();
            }

            cameraCaptureVisualizer.HideRenderer();

            if (RecordToFile)
            {
                StopRecording();
                // DisplayPlayback();
            }

            isCapturingVideo = false;
            isCapturingPreview = false;
        }

        private void MediaPlayerOnOnPrepared(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.Play();
#endif
        }

        private void MediaPlayerOnCompletion(MLMedia.Player mediaplayer)
        {
            // media player not supported in Magic Leap App Simulator
#if !UNITY_EDITOR
            mediaPlayerBehavior.StopMLMediaPlayer();
#endif
            mediaPlayerBehavior.gameObject.SetActive(false);
            mediaPlayerBehavior.Reset();
        }
    }
}

Apart from the code stack, I want to share some more details;

Project Hierarchy:

image

CamerRecording Scene:

VideoYUVRender:

VideoRGBRender:

PreviewRender:

I have compared all the assets, objects, references, shaders, and prefabs from the MagicLeap_Examples. Everything is matching perfectly.

I am getting these logs:

2023/06/22 19:17:30.945 10792 10815 Debug ml_camera_client capture complete for 1316935283003
2023/06/22 19:17:30.945 10792 10810 Debug ml_camera_client  got preview buffer 68 timestamp = 1316935283003
2023/06/22 19:17:30.945 10792 11161 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:30.945 10792 11161 Debug ml_camera_client  released preview buffer 69 timestamp = 1316935283003
2023/06/22 19:17:30.962 10792 10810 Debug ml_camera_client capturecompletecount = 77 timestamp = 1316952145366
2023/06/22 19:17:30.962 10792 10810 Debug ml_camera_client capture complete for 1316952145366
2023/06/22 19:17:30.962 10792 10815 Debug ml_camera_client  got preview buffer 69 timestamp = 1316952145366
2023/06/22 19:17:30.962 10792 11163 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:30.962 10792 11163 Debug ml_camera_client  released preview buffer 70 timestamp = 1316952145366
2023/06/22 19:17:30.978 10792 10815 Debug ml_camera_client capturecompletecount = 78 timestamp = 1316968610775
2023/06/22 19:17:30.978 10792 10815 Debug ml_camera_client capture complete for 1316968610775
2023/06/22 19:17:30.978 10792 10810 Debug ml_camera_client  got preview buffer 70 timestamp = 1316968610775
2023/06/22 19:17:30.979 10792 11165 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:30.979 10792 11165 Debug ml_camera_client  released preview buffer 71 timestamp = 1316968610775
2023/06/22 19:17:30.995 10792 10810 Debug ml_camera_client capturecompletecount = 79 timestamp = 1316985073689
2023/06/22 19:17:30.995 10792 10810 Debug ml_camera_client capture complete for 1316985073689
2023/06/22 19:17:30.995 10792 10815 Debug ml_camera_client  got preview buffer 71 timestamp = 1316985073689
2023/06/22 19:17:30.995 10792 11167 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:30.995 10792 11167 Debug ml_camera_client  released preview buffer 72 timestamp = 1316985073689
2023/06/22 19:17:31.011 10792 10815 Debug ml_camera_client capturecompletecount = 80 timestamp = 1317001940340
2023/06/22 19:17:31.012 10792 10815 Debug ml_camera_client capture complete for 1317001940340
2023/06/22 19:17:31.012 10792 10810 Debug ml_camera_client  got preview buffer 72 timestamp = 1317001940340
2023/06/22 19:17:31.012 10792 11169 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:31.012 10792 11169 Debug ml_camera_client  released preview buffer 73 timestamp = 1317001940340
2023/06/22 19:17:31.028 10792 10810 Debug ml_camera_client capturecompletecount = 81 timestamp = 1317018689240
2023/06/22 19:17:31.028 10792 10810 Debug ml_camera_client capture complete for 1317018689240
2023/06/22 19:17:31.028 10792 10815 Debug ml_camera_client  got preview buffer 73 timestamp = 1317018689240
2023/06/22 19:17:31.029 10792 11171 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:31.029 10792 11171 Debug ml_camera_client  released preview buffer 74 timestamp = 1317018689240
2023/06/22 19:17:31.045 10792 10815 Debug ml_camera_client capturecompletecount = 82 timestamp = 1317035208890
2023/06/22 19:17:31.045 10792 10815 Debug ml_camera_client capture complete for 1317035208890
2023/06/22 19:17:31.045 10792 10810 Debug ml_camera_client  got preview buffer 74 timestamp = 1317035208890
2023/06/22 19:17:31.045 10792 11173 Debug ml_camera_client Ready for preview frame callback callback
2023/06/22 19:17:31.045 10792 11173 Debug ml_camera_client  released preview buffer 75 timestamp = 1317035208890


Logs says, Ready for Preview, but it is not previewing anything. I can even see Camera Indicator on my Sample Application screen.

I have converted Shaders to URP. Here are the updated shaders as well;

VideoRGBRender:

PreviewRenderer: