videokit-ai / natcorder

High performance, cross-platform video recording for Unity Engine.
https://github.com/natmlx/videokit
Apache License 2.0
101 stars 19 forks source link

NatCorder crashes because of not supported AudioSampleRate #25

Closed marvpaul closed 1 year ago

marvpaul commented 1 year ago

I create a new MP4Recorder as suggested in the docs by passing the AudioSettings.outputSampleRate.

recorder = new MP4Recorder(recordingWidth, recordingHeight, framerate, AudioSettings.outputSampleRate, 2, videoBitRate: videoBitRate, keyframeInterval: keyframeInt);

On my machine all works fine but one of my customers got a hard crash when trying to record a video and getting this error:

023-04-12 14:29:53.180 Vythm[71252:1053837] NatCorder: MP4Recorder prepared video encoder at resolution 1280x720@30.000000Hz with average bitrate 27648000 and keyframe interval 1s
2023-04-12 14:29:53.207 Vythm[71252:1053837]  Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: ' -[AVAssetWriterInput initWithMediaType:outputSettings:sourceFormatHint:] 96000 Hz is not a valid sample rate for Format ID 'aac '.  Use kAudioFormatProperty_AvailableEncodeSampleRates (<AudioToolbox/AudioFormat.h>) to enumerate available rates for a given format.'
*** First throw call stack: 

(
    0   CoreFoundation                      0x00007ff815d18be2 __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007ff81584075c objc_exception_throw + 48
    2   AVFCore                             0x00007ff82b24241b -[AVAssetWriterInput dealloc] + 0
    3   AVFCore                             0x00007ff82b241e95 +[AVAssetWriterInput assetWriterInputWithMediaType:outputSettings:] + 40
    4   NatCorder                           0x0000000124e08152 -[NCMP4Recorder initWithPath:width:height:frameRate:sampleRate:channelCount:videoBitRate:keyframeInterval:audioBitRate:] + 1730
    5   NatCorder                           0x0000000124e0594f NCCreateMP4Recorder + 335
    6   ???                                 0x0000000136c4a9c0 0x0 + 5213825472
    7   ???                                 0x0000000136c479f3 0x0 + 5213813235
    8   ???                                 0x0000000136c47903 0x0 + 5213812995
    9   ???                                 0x0000000136c475b3 0x0 + 5213812147
    10  ???                                 0x0000000136c46bfb 0x0 + 5213809659
    11  ???                                 0x0000000136c440cb 0x0 + 5213798603
)
libc++abi: terminating due to uncaught
exception of type NSException
Obtained 256 stack frames.
#0  0x007ff815b8f1f2 in pthread_kill
#1  0x007ff815aedb45 in abort
#2  0x007ff815b81282 in abort_message
#3  0x007ff815b733fb in demangling_terminate_handler()
#4  0x007ff815847a77 in _objc_terminate()
#5  0x007ff815b806db in std::terminate(void ()())
#6  0x007ff815b82fa7 in cxa_get_exception_ptr
#7  0x007ff815b82f6e in cxxabiv1::exception_cleanup_func(_Unwind_Reason_Code, _Unwind_Exception)
#8  0x007ff81584085a in objc_exception_throw
#9  0x007ff82b24241b in -[AVAssetWriterInput dealloc]
#10 0x007ff82b241e95 in +[AVAssetWriterInput assetWriterInputWithMediaType:outputSettings:]
#11 0x00000124e08152 in -[NCMP4Recorder initWithPath:width:height:frameRate:sampleRate:channelCount:videoBitRate:keyframeInterval:audioBitRate:]
#12 0x00000124e0594f in NCCreateMP4Recorder
#13 0x00000136c4a9c0 in  (wrapper managed-to-native) NatML.Recorders.Internal.NatCorder:CreateMP4Recorder (string,int,int,single,int,int,int,int,int,intptr&) [{0x7fd3b708a170} + 0x100]  (0x136c4a8c0 0x136c4aa8d) [0x120157d20 - Unity Root Domain]
#14 0x00000136c479f3 in  NatML.Recorders.MP4Recorder:Create (int,int,single,int,int,int,int,int) [{0x7fd3b7089e10} + 0xd3]  (0x136c47920 0x136c47b53) [0x120157d20 - Unity Root Domain]
#15 0x00000136c47903 in  NatML.Recorders.MP4Recorder:.ctor (int,int,single,int,int,int,int,int) [{0x7fd3b7089aa8} + 0x63]  (0x136c478a0 0x136c4790d) [0x120157d20 - Unity Root Domain]
#16 0x00000136c475b3 in  Recorder:recordingMediaAudio () [{0x7fd3f6138c40} + 0xd3]  (0x136c474e0 0x136c47855) [0x120157d20 - Unity Root Domain]
#17 0x00000136c46bfb in  Recorder:StartRecording () [{0x7fd3f6138bf0} + 0x24b]  (0x136c469b0 0x136c46ca7) [0x120157d20 - Unity Root Domain]
#18 0x00000136c440cb in  UnityEngine.EventSystems.StandaloneInputModule:ReleaseMouse
olokobayusuf commented 1 year ago

I create a new MP4Recorder as suggested in the docs by passing the AudioSettings.outputSampleRate.

The sampleRate and channelCount you pass to the MP4Recorder constructor define the audio format of any audio that you will pass to MP4Recorder.CommitSamples. Our docs state that when recording audio from Unity Engine (i.e. recording an AudioListener's audio), then the sample rate should be AudioSettings.outputSampleRate because that tells the recorder what the sample rate of the audio data coming out of Unity Engine.

This crash is happening because Unity is running at a very high sample rate that isn't supported by iOS' AAC encoder. You have to find a way to limit Unity's audio sample rate to 48KHz or lower.