Search Unity

NatCorder - Video Recording API

Discussion in 'Assets and Asset Store' started by Lanre, Nov 18, 2017.

  1. Bongo_Studios

    Bongo_Studios

    Joined:
    Jan 26, 2019
    Posts:
    33
    SO?
     
  2. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    Update to NatCorder 1.6.6 on the Asset Store and use Vulkan for rendering. The performance is so much better now.
     
  3. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    Try out the NatCorder 1.6.6 upgrade. When rendering with Vulkan, the recording performance is much better.
     
  4. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    You can't change the recording path. Instead, you can move the video to your desired location in the recording callback. You can control the compression of the video by changing the bitrate parameter in the MP4Recorder/HEVCRecorder constructor.
     
  5. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I don't know anything about UTMail, but for the NatCorder certificate, simply delete NatCorder from your project and reimport it from the Asset Store. We fixed one such issue not too long ago.
     
  6. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    There are a few problems with your code. First is that the resolution of the recording MUST match that of the pixel buffer you are committing. The video resolution determines how many pixels NatCorder is expecting to copy from the pixel buffer and send to the encoder. You are hard coding 1280x720 when in fact it should be whatever your `cameraTexture` width and height are. If there is a mismatch, your app will likely crash with a segmentation fault.

    Second, you are using a realtime clock but you aren't recording in realtime. When recording in a loop, you're going much faster than realtime (so your video will look extremely sped up). Use a FixedIntervalClock instead, which generates timestamps that are evenly spaced out.

    Finally, the logs you uploaded show nothing relating to NatCorder. The crashed thread is apparently some events thread whose call stack doesn't seem to have anything pertinent. I'd say to send the crash report to Unity.
     
  7. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    It is impossible to increase the timescale but have the video look realtime. When you increase the timescale, Unity is rendering your game 5x or 10x faster. If you imagine it as a film strip, you are skipping a large number of intermediate motions/frames that would be present when rendering at a unit timescale. It has nothing to do with timestamps or clocks; you simply aren't committing the intermediate frames that would make for realtime motion.
     
  8. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    Ok. I am literally just trying to run the example that you had posted at https://medium.com/@olokobayusuf/natcorder-unity-recording-made-easy-f0fdee0b5055
    Because that example is missing a few lines before it can actually compile / run, I was only adding the necessary lines to compile.


    To verify that there's nothing going wrong with the framework playing well with recording a WebCamTexture, would it be possible for you to post an updated / complete example of your medium.com code, that runs on the current version of Unity, without producing garbled video or crashing?


    Thank you for the support.
     
  9. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    There is already an included example that demonstrates recording a WebCamTexture. See the WebCam example.
     
  10. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    Got it. Thank you - no idea how I missed that.

    More urgent question - I am using this component to record audio from my game's Main Camera, using an AudioListener:
    Code (CSharp):
    1.  
    2. using NatCorder;
    3. using NatCorder.Clocks;
    4. using UnityEngine;
    5.  
    6.  
    7. /**
    8. * When a script that implements `OnAudioFilterRead` is attached to an AudioSource
    9. * or AudioListener, Unity provides the PCM sample data to the function
    10. *
    11. * We can use this to extract the audio data and send to NatCorder for encoding
    12. */
    13. public class AudioCaptureInput : MonoBehaviour
    14. {
    15.  
    16.     public IMediaRecorder recorder;    // Initialize this somewhere
    17.     public IClock clock;               // Also initialize this somewhere
    18.  
    19.     void OnAudioFilterRead(float[] sampleBuffer, int channels)
    20.     {
    21.  
    22.         //Debug.Log(recorder);
    23.         // Send to NatCorder for encoding
    24.         if (recorder != null)
    25.         {
    26.             recorder.CommitSamples(sampleBuffer, clock.Timestamp);
    27.         }
    28.  
    29.     }
    30. }
    The AudioListener is capturing any audio that plays inside of an AudioSource perfectly.

    However, my music app is primarily creating sound with a Bass24 MIDI synthesizer, that does not run through its sound through an AudioSource. I can't find any way to get NatCorder to capture that audio, and its absolutely essential to my app (records piano videos). Is there any way for the AudioListener to capture audio that isn't playing through an AudioSource?

    Thank you.
     
    Last edited: Dec 28, 2019
  11. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    NatCorder can only record data that is provided to it. So no matter what you would have to figure out a way to get the audio data to send to the recorder. AudioListener only picks up audio that plays through AudioSources. You'll need some way to access the PCM audio data from the MIDI synthesizer.

    Also on a minor note, NatCorder already has an AudioInput component--no need to write your own AudioCaptureInput.
     
  12. Biggix

    Biggix

    Joined:
    Dec 8, 2014
    Posts:
    44
    Hey guys, I have migrated from NatCorder 1.3 (which worked fine) to 1.6.1 (because of Android 64-bit requirement) and everything broke. While I'm waiting for Lanre to answer via email, posting this here so that anyone later with the same issue could find a quick answer (or maybe someone already knows the answer)?

    The code I'm using is

    Code (CSharp):
    1. recordingClock = new RealtimeClock();
    2.  
    3.     mediaRecorder = new MP4Recorder(sw, sh, 30, 0, 0, OnVideo, (int) (sw*sh*11.4f),3);
    4.      
    5.     cameraInput = new CameraInput(mediaRecorder, recordingClock, Camera.main);
    6.  
    7. //For stopping the recording:
    8.  
    9.     cameraInput.Dispose();
    10.     mediaRecorder.Dispose();
    11.     mediaRecorder = null;
    12.  
    13. //OnVideo:
    14.  
    15. public void OnVideo (string path) {
    16.     Debug.Log("Saved recording to: "+path);
    17.  
    18.     }
    I have checked that the frame width & height are not odd. Still the recorder doesn't get the file written and just hangs on iOS, without calling the OnVideo callback (on Android, there is some obscure error message)

    Android:
    Code (CSharp):
    1. 12-28 09:34:18.977 10860 11092 V Unity   : NatCorder: MP4 video encoder encountered EOS
    2. 12-28 09:34:19.016 10860 11092 E Unity   : NatCorder Error: Failed to finish writing media
    3. 12-28 09:34:19.016 10860 11092 E Unity   : java.lang.IllegalStateException: Can't stop due to wrong state.
    4. 12-28 09:34:19.016 10860 11092 E Unity   :     at android.media.MediaMuxer.stop(MediaMuxer.java:475)
    5. 12-28 09:34:19.016 10860 11092 E Unity   :     at api.natsuite.natcorder.utility.MediaWriter.finishWriting(MediaWriter.java:57)
    6. 12-28 09:34:19.016 10860 11092 E Unity   :     at api.natsuite.natcorder.MP4Recorder$6.run(MP4Recorder.java:196)
    7. 12-28 09:34:19.016 10860 11092 E Unity   :     at java.lang.Thread.run(Thread.java:764)
    iOS:
    Code (CSharp):
    1. 2019-12-28 11:26:46.337475+0300 puzzle[4320:1119029] NatCorder: Prepared MP4 video encoder at resolution 444x960@30.000000Hz with average bitrate 4859136 and keyframe interval 3s
    2. 2019-12-28 11:26:55.437240+0300 puzzle[4320:1119029] NatCorder: MP4 recorder finishing
     
  13. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I just replied to your email. I need to see the logs. What devices are you testing on?
     
  14. Biggix

    Biggix

    Joined:
    Dec 8, 2014
    Posts:
    44
    Iphone 11 Pro Max and Samsung S8
     
  15. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    Ok, thank you for the response. I'll see if I can find a workaround...
     
    Lanre likes this.
  16. yolon3000

    yolon3000

    Joined:
    Aug 1, 2018
    Posts:
    10
    hi Lanre
    I have got a problem on iPhone 11,iPhone 7s,I used the NatCorder before ,It was worked fine before iOS 13,I can record the camera video more than 3 minutes or more ,but after upgrade to iOS 13 ,the app crashed after only a few seconds .I dont know while the problem is ,so i got the log shot below:
    ---------------------------------------------------------------------------------------------------
    2019-12-30 08:12:10.171088+0800 ARShow[1088:369767] Built from '2019.1/release' branch, Version '2019.1.2f1 (3e18427e571f)', Build type 'Release', Scripting Backend 'il2cpp'
    2019-12-30 08:12:10.175197+0800 ARShow[1088:369767] -> registered mono modules 0x105813880
    -> applicationDidFinishLaunching()
    2019-12-30 08:12:10.241731+0800 ARShow[1088:369767] Metal GPU Frame Capture Enabled
    -> applicationDidBecomeActive()
    GfxDevice: creating device client; threaded=1
    Initializing Metal device caps: Apple A10 GPU
    Initialize engine version: 2019.1.2f1 (3e18427e571f)
    2019-12-30 08:12:10.897807+0800 ARShow[1088:369767] Unbalanced calls to begin/end appearance transitions for <SplashScreenController: 0x145d5c940>.
    UnloadTime: 2.640417 ms
    Setting up 1 worker threads for Enlighten.
    Thread -> id: 16d7eb000 -> priority: 1
    2019-12-30 08:12:14.602673+0800 ARShow[1088:369943] Task <406C7A5A-5C5F-42EB-86B8-0FDDA5350752>.<1> HTTP load failed, 533/281 bytes (error code: -1005 [4:-4])
    2019-12-30 08:12:14.602883+0800 ARShow[1088:369943] Task <406C7A5A-5C5F-42EB-86B8-0FDDA5350752>.<1> HTTP load failed, 533/281 bytes (error code: -1005 [4:-4])
    2019-12-30 08:12:14.608685+0800 ARShow[1088:369947] Task <406C7A5A-5C5F-42EB-86B8-0FDDA5350752>.<1> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x2834386c0 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x281948690 [0x1c66435e0]>{length = 16, capacity = 16, bytes = 0x100201bb23f11a350000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <406C7A5A-5C5F-42EB-86B8-0FDDA5350752>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalUploadTask <406C7A5A-5C5F-42EB-86B8-0FDDA5350752>.<1>"
    ), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=https://config.uca.cloud.unity3d.com/, NSErrorFailingURLKey=https://config.uca.cloud.unity3d.com/, _kCFStreamErrorDomainKey=4}
    2019-12-30 08:12:44.979454+0800 ARShow[1088:369946] Task <F2120C55-4BC5-406B-AA8F-C5382EE86C89>.<1> HTTP load failed, 1289/417 bytes (error code: -1005 [4:-4])
    2019-12-30 08:12:44.979761+0800 ARShow[1088:369946] Task <F2120C55-4BC5-406B-AA8F-C5382EE86C89>.<1> HTTP load failed, 1289/417 bytes (error code: -1005 [4:-4])
    2019-12-30 08:12:44.989428+0800 ARShow[1088:369941] Task <F2120C55-4BC5-406B-AA8F-C5382EE86C89>.<1> finished with error [-1005] Error Domain=NSURLErrorDomain Code=-1005 "The network connection was lost." UserInfo={_kCFStreamErrorCodeKey=-4, NSUnderlyingError=0x2834d2e50 {Error Domain=kCFErrorDomainCFNetwork Code=-1005 "(null)" UserInfo={NSErrorPeerAddressKey=<CFData 0x28197ab20 [0x1c66435e0]>{length = 16, capacity = 16, bytes = 0x100201bb23be58ea0000000000000000}, _kCFStreamErrorCodeKey=-4, _kCFStreamErrorDomainKey=4}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalUploadTask <F2120C55-4BC5-406B-AA8F-C5382EE86C89>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
    "LocalUploadTask <F2120C55-4BC5-406B-AA8F-C5382EE86C89>.<1>"
    ), NSLocalizedDescription=The network connection was lost., NSErrorFailingURLStringKey=https://cdp.cloud.unity3d.com/v1/events, NSErrorFailingURLKey=https://cdp.cloud.unity3d.com/v1/events, _kCFStreamErrorDomainKey=4}
    (x:0.00, y:0.00, width:1.00, height:1.00)
    UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    ReplayCam:StartRecording()
    Davidwang.AppController:StartREC()
    UnityEngine.Events.UnityAction:Invoke()
    UnityEngine.Events.InvokableCall:Invoke()
    UnityEngine.Events.UnityEvent:Invoke()
    UnityEngine.UI.Button:press()
    UnityEngine.UI.Button:OnPointerClick(PointerEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(IPointerClickHandler, BaseEventData)
    UnityEngine.EventSystems.EventFunction`1:Invoke(T1, BaseEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
    UnityEngine.EventSystems.StandaloneInputModule:processTouchPress(PointerEventData, Boolean, Boolean)
    UnityEngine.EventSystems.StandaloneInputModule:processTouchEvents()
    UnityEngine.EventSystems.StandaloneInputModule:process()
    UnityEngine.EventSystems.EventSystem:Update()

    (Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 48)

    NatCorder: Initialized NatCorder 1.1 iOS backend
    UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    NatCorderU.Core.Platforms.NatCorderiOS:.ctor()
    NatCorderU.Core.NatCorder:.cctor()
    NatCorderU.Core.Replay:StartRecording(Camera, Configuration, VideoCallback, IAudioSource)
    ReplayCam:StartRecording()
    Davidwang.AppController:StartREC()
    UnityEngine.Events.UnityAction:Invoke()
    UnityEngine.Events.InvokableCall:Invoke()
    UnityEngine.Events.UnityEvent:Invoke()
    UnityEngine.UI.Button:press()
    UnityEngine.UI.Button:OnPointerClick(PointerEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(IPointerClickHandler, BaseEventData)
    UnityEngine.EventSystems.EventFunction`1:Invoke(T1, BaseEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
    UnityEngine.EventSystems.StandaloneInputModule:processTouchPress(PointerEventData, Boolean, Boolean)
    UnityEngine.EventSystems.StandaloneInputModule:processTouchEvents()
    UnityEngine.EventSystems.StandaloneInputModule:process()
    UnityEngine.EventSystems.EventSystem:Update()

    (Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 48)

    NatCam Dispatch: Initialized main dispatch
    UnityEngine.DebugLogHandler:Internal_Log(LogType, LogOption, String, Object)
    UnityEngine.DebugLogHandler:LogFormat(LogType, Object, String, Object[])
    UnityEngine.Logger:Log(LogType, Object)
    UnityEngine.Debug:Log(Object)
    NatCamU.Dispatch.MainDispatch:.ctor()
    NatCorderU.Core.Platforms.NatCorderiOS:StartRecording(Configuration, VideoCallback, IAudioSource)
    NatCorderU.Core.NatCorder:StartRecording(Configuration, VideoCallback, IAudioSource)
    NatCorderU.Core.Replay:StartRecording(Camera, Configuration, VideoCallback, IAudioSource)
    ReplayCam:StartRecording()
    Davidwang.AppController:StartREC()
    UnityEngine.Events.UnityAction:Invoke()
    UnityEngine.Events.InvokableCall:Invoke()
    UnityEngine.Events.UnityEvent:Invoke()
    UnityEngine.UI.Button:press()
    UnityEngine.UI.Button:OnPointerClick(PointerEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(IPointerClickHandler, BaseEventData)
    UnityEngine.EventSystems.EventFunction`1:Invoke(T1, BaseEventData)
    UnityEngine.EventSystems.ExecuteEvents:Execute(GameObject, BaseEventData, EventFunction`1)
    UnityEngine.EventSystems.StandaloneInputModule:processTouchPress(PointerEventData, Boolean, Boolean)
    UnityEngine.EventSystems.StandaloneInputModule:processTouchEvents()
    UnityEngine.EventSystems.StandaloneInputModule:process()
    UnityEngine.EventSystems.EventSystem:Update()

    (Filename: ./Runtime/Export/Debug/Debug.bindings.h Line: 48)

    2019-12-30 08:12:55.271771+0800 ARShow[1088:369767] NatCorder Logging: Prepared video track at resolution 720x1280@30Hz with average bitrate 5909760 and keyframe interval 3s
    2019-12-30 08:13:04.860576+0800 ARShow[1088:370047] [Technique] World tracking performance is being affected by resource constraints [1]
    2019-12-30 08:13:04.860860+0800 ARShow[1088:370047] [Technique] VIO error callback: 125587.268597, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:05.220679+0800 ARShow[1088:370047] [Technique] VIO error callback: 125587.652163, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:06.063445+0800 ARShow[1088:370047] [Technique] World tracking performance is being affected by resource constraints [1]
    2019-12-30 08:13:06.063554+0800 ARShow[1088:370047] [Technique] VIO error callback: 125588.552708, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:06.118064+0800 ARShow[1088:370047] [Technique] VIO error callback: 125588.652769, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:06.386653+0800 ARShow[1088:370047] [Technique] VIO error callback: 125588.752829, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:06.402585+0800 ARShow[1088:370047] [Technique] VIO error callback: 125588.952951, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:06.525138+0800 ARShow[1088:370047] [Technique] VIO error callback: 125589.053011, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:06.585623+0800 ARShow[1088:370047] [Technique] VIO error callback: 125589.153072, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:07.110586+0800 ARShow[1088:370047] [Technique] World tracking performance is being affected by resource constraints [1]
    2019-12-30 08:13:07.110795+0800 ARShow[1088:370047] [Technique] VIO error callback: 125589.653375, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:07.195525+0800 ARShow[1088:370047] [Technique] VIO error callback: 125589.753435, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:07.648192+0800 ARShow[1088:370047] [Technique] VIO error callback: 125590.153678, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:07.692284+0800 ARShow[1088:370047] [Technique] VIO error callback: 125590.253738, 1, Frame processing rate has fallen below pre-set threshold
    WARNING -> applicationDidReceiveMemoryWarning()
    2019-12-30 08:13:09.132263+0800 ARShow[1088:370047] [Technique] World tracking performance is being affected by resource constraints [1]
    2019-12-30 08:13:09.132383+0800 ARShow[1088:370047] [Technique] VIO error callback: 125590.970839, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.147017+0800 ARShow[1088:370047] [Technique] VIO error callback: 125591.070900, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.175979+0800 ARShow[1088:370047] [Technique] VIO error callback: 125591.204314, 1, Frame processing rate has fallen below pre-set threshold
    WARNING -> applicationDidReceiveMemoryWarning()
    WARNING -> applicationDidReceiveMemoryWarning()
    2019-12-30 08:13:09.336925+0800 ARShow[1088:370047] [Technique] VIO error callback: 125591.437789, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.355985+0800 ARShow[1088:370047] [Technique] VIO error callback: 125591.637910, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.373210+0800 ARShow[1088:370047] [Technique] VIO error callback: 125591.938092, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.502458+0800 ARShow[1088:370047] [Technique] World tracking performance is being affected by resource constraints [1]
    2019-12-30 08:13:09.502625+0800 ARShow[1088:370047] [Technique] VIO error callback: 125592.038153, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.565484+0800 ARShow[1088:370047] [Technique] VIO error callback: 125592.138213, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.667384+0800 ARShow[1088:370047] [Technique] VIO error callback: 125592.238274, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.778626+0800 ARShow[1088:370047] [Technique] VIO error callback: 125592.338334, 1, Frame processing rate has fallen below pre-set threshold
    2019-12-30 08:13:09.879562+0800 ARShow[1088:370047] [Technique] VIO error callback: 125592.438395, 1, Frame processing rate has fallen below pre-set threshold
    (lldb)
    ---------------------------------------------------------------------------
    can you fix it or tell me what happened on iOS 13 ? what should i do to slove this problem ? thank you
     
  17. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    You are using a much older version of NatCorder. Upgrade to the latest version on the Asset Store.
     
  18. yolon3000

    yolon3000

    Joined:
    Aug 1, 2018
    Posts:
    10
    OK,THANK YOU!
     
    Lanre likes this.
  19. Aidan-Wolf

    Aidan-Wolf

    Joined:
    Jan 6, 2014
    Posts:
    59
    I'm having alpha masking issues in the final recording using the default MP4Recorder settings, any idea?
     
  20. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    Can you elaborate? None of the recorders support transparency.
     
  21. Bongo_Studios

    Bongo_Studios

    Joined:
    Jan 26, 2019
    Posts:
    33
    Greetings, we've downloaded the latest version of NatCorder and in some devices there is an improvement on the performance of recording. However, this is because it is using Vulkan, which corresponds to what you specify saying that NatCorder works better taking advantage of Vulkan.
    Thus, this forces us to just support devices using API Level 24 (Android 7), when in the store page it is clearly specified that NatCorder works with devices from API Level 21 (Android 5) and onwards. This clear contradiction forces us to lose a lot of compatible devices which is unacceptable, so we need a solution to this issue as losing such a big user base is out of the question.


    https://developer.android.com/ndk/guides/graphics/getting-started?hl=es
     
  22. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I'm not sure what contradiction you are referring to. NatCorder supports API level 21; there is nothing preventing you from building and recording on Android 21. Using Vulkan however provides a performance improvement. A performance improvement (or lack thereof) doesn't constitute a contradiction, and neither does it prevent you from building or running on Android 21.
     
  23. Bongo_Studios

    Bongo_Studios

    Joined:
    Jan 26, 2019
    Posts:
    33
    There's no purpose in being able to build for Android Level 21 if the performance is going to be greatly reduced (around 10-15 FPS), making the plugin virtually unusable for those devices.
    What is the benefit of being able to build an app with the plugin if it is going to be unusable?
     
  24. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    You seem to be expecting Vulkan-level performance on non-Vulkan devices. First, it is worth noting that some devices will not see a great hit in framerate when recording with OpenGL ES (for instance, apps that run and record at 30FPS which are not GPU-bound). Second, it is worth noting that you can improve the recording performance on OpenGL ES by simply reducing the recording resolution. Third, it is worth noting that this entire conversation only applies to CameraInput, which records by reading back data from the GPU. If you were recording from a pixel buffer, like say a WebCam, Texture2D, NatCam, or OpenCV, this entire conversation doesn't even apply. With all this in mind, you're making quite the reach saying NatCorder has somehow become unusable on API level 21.
     
  25. Bongo_Studios

    Bongo_Studios

    Joined:
    Jan 26, 2019
    Posts:
    33
    We are using CameraInput since our goal is to record the screen while playing a videogame. You claim that there are different options to make it work and record with good performance, therefore we would need an explanation/example on how to do so, since in previous versions of the plugin the recording worked on devices that now it doesn’t.
    Our videogame is completely 2D, there are no complex calculations and when recording it has always been established to use small resolutions as to obtain a minimal resolution with acceptable results. The bitrate is lower than default, generating the lowest size video trying to obtain the best performance.
    However, in devices were in previous versions of the plugin the recording could easily be done while running at 30-50 FPS, now it runs maximum at 10-15 FPS. Because of the nature of the videogame, we only use 2D textures, the CPU is never under stress except when using NatCorder, and still it has low performance, defeating the purpose of the plugin.
    Obviously we aren’t expecting non-Vulkan devices to have an increased performance all of a sudden, what I’m trying to convey is that in devices where it previously worked fine, now performance is low, making us lose support for a big part of the target devices. So, we would like your help explaining how the plugin should be implemented in order to work as expected and how it did in previous versions.
    In our tests, which lead us to say that the performance has been lowered, it was installed in two devices: one with Vulkan support (Xiaomi Redmi Note 4) and one without Vulkan support (Samsung J5 Prime) and it was evidenced that even in the Vulkan supported device the performance is still low. In the attached image it can be seen in the profiler that the use of CPU is very high from NatCorder. Additionally, in the graphics API configuration it was forced to only use Vulkan to ensure that the device was using this API, and still the performance was low when recording.
     

    Attached Files:

  26. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I just profiled the async readback and saw that there's actually a bottleneck in CommitFrame on Android, due to copying the buffer and sending it to a worker thread for encoding. It affects Vulkan and OpenGL ES alike, so this is why OpenGL ES seems to have a much larger performance hit. I'm working on fixing this. I'll have a new build sometime next week, so follow up with me then.
     
  27. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    I'm getting close to finding a way to manually route my MIDI Synthesizer's audio buffer into NatCorder. By calling this code in my main Update() loop while recording, I'm getting the audio - but it seems like it's missing chunks of the buffer (audio sounds correct, but is 'skipping' little bits). This does make some sense, since I've manually set the app to run at 15 FPS while doing the capture (for a lot of necessary reasons).

    Code (CSharp):
    1. if (isCreatingVideo)
    2.         {
    3.             // millisecond window in bytes to be filled with sample data
    4.             int length = (int)Bass.BASS_ChannelSeconds2Bytes(BASS24NETSynth.mixerStream, 1f / 15f);
    5.  
    6.             // first we need a mananged object where the sample data should be placed
    7.             // length is in bytes, so the number of floats to process is length/4
    8.             float[] data = new float[length / 4];
    9.  
    10.             // get the sample data
    11.             Bass.BASS_ChannelGetData(BASS24NETSynth.mixerStream, data, length);
    12.  
    13.             //Debug.Log(data);
    14.  
    15.             if (recorder != null && recordingClock != null && data != null)
    16.             {
    17.                 recorder.CommitSamples(data, recordingClock.Timestamp);
    18.             }
    19.  
    20.         }
    I imagine a normal AudioFilterRead loop probably runs at something like every 30 ms... I know that you're a Unity guru - do you have any suggestions for how I can set up my own fast-running audio buffer capture loop, to run this code as fast as it needs to, to send the complete audio buffer to NatCorder?

    (I tried using an IEnumerator coroutine, but that didn't run any faster than Update(), as far as I could tell.)

    Any assistance would be much appreciated.
     
  28. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    You probably want to spin up a dedicated thread to pull in the samples to C#. That way you can predictably collect the exact number of samples on every loop iteration. All `IMediaRecorder` implementations are thread safe, so you can call `CommitSamples` from any thread.
     
  29. Aidan-Wolf

    Aidan-Wolf

    Joined:
    Jan 6, 2014
    Posts:
    59
    My Unity scene is filled with lots of overlapping objects with transparent textures. Everything looks normal when looking at the renderered scene in the gmae view, but after recording, the transparent textures aren't blending or sorting or masking.
     
  30. edee1337

    edee1337

    Joined:
    Apr 10, 2013
    Posts:
    34
    Don't know if this will help, but if you're drawing to a RenderTexture make sure the RenderTexture is ARGB32 with a depth buffer of 24 bits. For my setup I've got my MainCamera's texture set to a RenderTexture created at runtime, and then in NatCorder's CameraInput.cs OnFrame(), I Blit from the mainCamera.targetTexture to framebuffer.
     
  31. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    This sounds like a bug in Unity, so I'd recommend filing a bug report. CameraInput only renders the camera to a RenderTexture; it doesn't modify the camera settings in any way. You can check out the OnFrame method in CameraInput.cs.
    CameraInput already uses an ARGB32 RenderTexture with a 24-bit depth buffer. But yes, if you are creating your own RenderTexture, this is how you should initialize it.
     
  32. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    Great - do you have any suggestions or hints for how to start the dedicated thread to do this?
    Ok, so after talking to the guys over at the MIDI Synth forum, I finally am successfully getting the samples from the Synth, and sending them over to NatCorder. Very short recordings are working perfectly.

    Unfortunately, about 5-10 seconds into the recording, the NatCorder instance of IMediaRecorder suddenly appears to be null, and is stalling the app, with "NullReferenceException: Object reference not set to an instance of an object"

    Here is the code of my audio sample send to NatCorder. It throws the NullReferenceException when I try to print, or check if the instance of IMediaRecorder is null.

    Code (CSharp):
    1. private void GetBassAudioSamples(int handle, int channel, IntPtr buffer, int length, IntPtr user)
    2.         {
    3.  
    4.             if (SceneSingleton.Instance.isCreatingVideo)
    5.             {
    6.                 int arrayLength = (int)(length / 4);
    7.  
    8.                 if (arrayLength > 0)
    9.                 {
    10.                     float[] data = new float[arrayLength];
    11.  
    12.                     // get the sample data
    13.                     Marshal.Copy(buffer, data, 0, arrayLength);
    14.  
    15.                     if (data.Length > 0)
    16.                     {
    17.  
    18.                         Debug.Log(videoRecorder);
    19.  
    20.  
    21.                         if (videoRecorder != null && recordingClock != null)
    22.                         {
    23.                             videoRecorder.CommitSamples(data, recordingClock.Timestamp);
    24.                         }
    25.                     }
    26.                 }
    27.             }
    28.         }
     
    Last edited: Jan 3, 2020
  33. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    Check out the .NET Thread documentation on how to start a thread.
    What platform does this happen on? I'll need to see logs.
     
  34. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    (Sorry, didn't mean to ask that question about threading - that was left in the reply box somehow from yesterday).

    - This is happening on:
    Unity Editor - Unity 2019.3.0f3
    MacOS Catalina 10.15
    MacBook Pro 2017


    The Editor log is attached - is there a different log I need to send?

    Thank you.


    It looks like the problem starts with this in the log:

    Unloading 455 Unused Serialized files (Serialized files now loaded: 0)
    Loaded scene 'Temp/__Backupscenes/0.backup'
    Deserialize: 109.187 ms
    Integration: 72.466 ms
    Integration of assets: 0.059 ms
    Thread Wait Time: 17.761 ms
    Total Operation Time: 199.474 ms
    System memory in use before: 0.92 GB.
    System memory in use after: 0.92 GB.

    Unloading 486 unused Assets to reduce memory usage. Loaded Objects now: 13363.
    Total: 40.213696 ms (FindLiveObjects: 1.816438 ms CreateObjectMapping: 0.276598 ms MarkObjects: 37.715102 ms DeleteObjects: 0.404663 ms)


    [00:00:00] Enlighten: Precompute started.
    [PathTracer] building lightmap data asset.
    [00:00:00] Enlighten: Finished 1 Layout Systems job (0.00s execute, 0.00s integrate, 0.06s wallclock)
    [00:00:00] Enlighten: Finished 1 Tetrahedralize Probes job (0.00s execute, 0.00s integrate, 0.05s wallclock)
    [00:00:00] Enlighten: Precompute took 0.115591 seconds.
    Enlighten scene contents: 0 geometries. 0 instances. 0 systems. 0 probe groups. 0 cube maps. Scene is up-to-date.
    [PathTracer] building lightmap data asset.
    Start importing Assets/NatCorder/Examples/ReplayCam/ReplayCam.cs using Guid(02641e9e576064f35a2dab995981e691) Importer(-1,)
    Done importing asset: 'Assets/NatCorder/Examples/ReplayCam/ReplayCam.cs' (target hash: 'e36e41c34e8836d7002db5413cbc4393') in 0.030032 seconds


    After that, the log suggests that the whole scene loads again. Do you have any idea what might be triggering that? The memory usage seems to be staying fairly normal.


    Also, just tested running the same recording process, only without committing the audio samples. Everything runs great, and I'm able to record and save a 3 min video perfectly, without any crashes. So it does seem that committing the audio samples to NatCorder is somehow causing the issue...

    Update - I did a post over on the MIDI Synth site to see if anyone can see something obviously wrong with my audio sample callback code. I'm using Marshal.Copy to get the sample buffer into a float[], and I could be doing something wrong there. I don't know why it would trigger a crash in this way, but maybe someone over on the BASS forum will tell me that I'm doing something wrong. (Don't want to insinuate that something's wrong with NatCorder if it isn't)

    Thanks for your awesome support, I'm definitely planning on leaving a 5-star review once I get this figured out.
     

    Attached Files:

    Last edited: Jan 4, 2020
  35. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    The logs show a specific line number where the null reference is coming from. Can you share the full source file?
     
  36. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    I believe the null reference comes from line 320 of my modified version of your ReplayCam.cs example?

    (I'm waiting to hear back from the developers of BASS for a suggestion, but I have a feeling the issue could be with the way I'm converting the unmanaged buffer memory to a float[] using Marshal.Copy, before committing to NatCorder?)
     

    Attached Files:

  37. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    The logs say line 316, but that line is empty in ReplayCam.cs. Check your code and see the logs to know where exactly the null ref is coming from.
     
  38. musicdeveloper

    musicdeveloper

    Joined:
    Oct 16, 2019
    Posts:
    68
    I cleaned up the code a little bit before sending. It is line 318 in the current code:

    if (videoRecorder != null && recordingClock != null) {
     
  39. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    It is impossible for this line to create a null reference exception (it is performing null checks). You might be overlooking something. I'd say to carefully statically analyze your code, then use a debugger or Debug.Logs. As far as I can tell the problem is coming from your code, not Bass or NatCorder code.
     
  40. zikwavestudios

    zikwavestudios

    Joined:
    Jan 27, 2016
    Posts:
    17
    Hi,

    It seems that many users of my app on Android 9 are getting crashes because of Natcorder:

    java.lang.Error: FATAL EXCEPTION [MP4Recorder Video Encoding Thread] Unity version : 2019.2.17f1 Device model : samsung SM-N960F
    Caused by
    at android.media.MediaCodec.native_dequeueOutputBuffer (Native Method)
    at android.media.MediaCodec.dequeueOutputBuffer (MediaCodec.java:2698)
    at api.natsuite.natcorder.MP4Recorder$6.run (MP4Recorder.java:184)
    at java.lang.Thread.run (Thread.java:764)

    or previously:

    java.lang.Error: FATAL EXCEPTION [Thread-53] Unity version : 2019.2.17f1 Device model : samsung SM-G965F Caused by
    at android.media.MediaCodec.native_dequeueOutputBuffer (Native Method)
    at android.media.MediaCodec.dequeueOutputBuffer (MediaCodec.java:2698)
    at com.yusufolokoba.natcorder.MP4Recorder$10.run (MP4Recorder.java:260)
    at java.lang.Thread.run (Thread.java:764)

    We don't use Vulkan as it is not compatible with ARCore.

    Can you help with this?
     
  41. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I'm working on adding exception handling in the next update. You'll need to update to the latest version of NatCorder though.
     
  42. Yode_group

    Yode_group

    Joined:
    Apr 5, 2016
    Posts:
    14
    Hello, is it possible in the NatCoder to record an audio stream from a scene and as simultaneously from a microphone?
     
  43. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    It is up to the client (you) to provide NatCorder with any audio that is to be recorded. That being said, actually mixing game and mic audio is a very hard task, and there is no way out there to accomplish this currently.
     
    SweatyChair likes this.
  44. DerrickBarra

    DerrickBarra

    Joined:
    Nov 19, 2013
    Posts:
    210
    @Lanre :

    Question 1:
    I was going to message you about getting Microphone mixed with an AudioListener's source within a video. I tested it out and it 'works', but the audio comes out glitched in the final video. Sounds like there isn't really a solution for this. Have you ever seen an example of this working before? Your basically the authority on recording in realtime around the forums, so if you say it's basically impossible, I'll take that as a sign to just design around the limitation.

    EDIT: In my research, I found what I believe is your Github user account (or another Natsuite dev) 'olokobayusuf' that makes reference to a 'MixerDevice' class to mux the game and mic audio together, is this something you're aware of? He only seems to have an incomplete code stub about it, but I figured I would bring it up in case it's something you or other Natsuite developers were working on.

    Question 2:
    Is it possible to record from a render texture? Do you have a working example of this? In my testing so far videos that blit frames from a renderTexture end up black (I'm attempting to do this to work around the restriction of not being able to capture Screen space UI, by using a Camera space UI and rendering the UI to a renderTexture, which I want to combine with the other world-space elements).

    Here's how I'm creating a render texture dynamically...
    renderTexture = new RenderTexture( Screen.width, Screen.height, 24, RenderTextureFormat.ARGB32 );


    And I'm capturing the frames on Update()
    videoRecorder.CommitFrame( renderTexture.GetNativeTexturePtr(), clock.Timestamp );
     
    Last edited: Jan 10, 2020
  45. monda

    monda

    Joined:
    May 14, 2015
    Posts:
    35
    Hi, same problem here, I got lots of users running on Android 9 with this problem:


    [B]java.lang.Error[/B]: FATAL EXCEPTION [MP4Recorder Video Encoding Thread] Unity version : 2019.2.17f1 Device model : samsung SM-G973F Device fingerprint: samsung/beyond1lteeea/beyond1:9/PPR1.180610.011/G973FXXS3ASH1:user/release-keys Caused by


    at android.media.MediaCodec.native_dequeueOutputBuffer (Native Method)


    at android.media.MediaCodec.dequeueOutputBuffer (MediaCodec.java:2698)


    at api.natsuite.natcorder.MP4Recorder$6.run (MP4Recorder.java:184)


    at java.lang.Thread.run (Thread.java:764)


    Is there anything I can do to avoid this, my main problem is that the downloads will be huge during the weekend and I would love to push an update today to avoid it.
    Thanks!
     
  46. SweatyChair

    SweatyChair

    Joined:
    Feb 15, 2016
    Posts:
    140
    We want to record replays in mac. It works totally fine in Editor, but in a build, it froze when start recording, but the output file is totally fine.

    Is that intended or any way to fix it? (Players may think game clash when recording....)

    Unity 2018.4.14f1
    macOS Catalina 10.15.1

    Video:
    https://monosnap.com/file/VQU5Id1JOMG6HWXAMKYEclmwqM2gev
     
    Last edited: Jan 13, 2020
  47. SweatyChair

    SweatyChair

    Joined:
    Feb 15, 2016
    Posts:
    140
    Another minor things are:
    1. Example script WebCam has HandHeld which causing error when building in standalone. Do a #if UNITY_ANDROID || UNITY_IOS.
    2. The ReplayCam example is not very straightforward, putting a bouncing ball in background that will greatly helps.
     
  48. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I'm olokobayusuf on GitHub. Mixing mic and game audio is really hard. The MixerDevice was part of NatMic, but it didn't always work properly because we couldn't properly synchronize timestamps from the hardware microphone with those from's Unity audio engine. I'm currently trying to reimplement this feature. But yes it's a pretty difficult problem, except you're an audio engineer.
    NatCorder always expects a pixel buffer to be recorded, so to record from a RenderTexture, you first have to get the pixel data from the RenderTexture then send that pixel data to the recorder. Unity provides the Texture2D.ReadPixels and AsyncGPUReadbackRequest.Request functions for this.
    This code will crash. The CommitFrame overload that takes a pointer expects a native buffer in system memory, not a texture pointer on the GPU.
     
    DerrickBarra likes this.
  49. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I wouldn't be able to get a build ready for this weekend, but I'm already working on this.
     
    monda likes this.
  50. Lanre

    Lanre

    Joined:
    Dec 26, 2013
    Posts:
    3,973
    I've seen this bug on iOS, and it was because of Unity 2018. Unity 2019.2 fixes it.