react-native-audio-waveform icon indicating copy to clipboard operation
react-native-audio-waveform copied to clipboard

[BUG] Extremely poor audio quality

Open gmantuanrosa opened this issue 1 year ago • 0 comments
trafficstars

I found this library and gave it a try to test on my chat screen. Following the doc I setup the recorder as follows

ref.current?.startRecord({
  encoder: 3,
  updateFrequency: UpdateFrequency.high,
  bitRate: 96000,
  sampleRate: 44100,
});

Looking at the Android implementation the selected values for AudioEncoder and OutputFormat should be

MediaRecorder.AudioEncoder.HE_AAC
MediaRecorder.OutputFormat.MPEG_4 // default values as there is no way to set

Although this was expected the audio quality is extremely poor compared to a native implementation using the same values provided to yours MediaRecorder implementation.

Adding a Log inside the initRecorder function i could assert that the values that I am providing through the startRecord are not entirely being passed down and instead using the default values (or not):

// Default Values
private var encoder: Int = 0
private var outputFormat: Int = 0
private var sampleRate: Int = 44100
private var bitRate: Int? = null

// Log
fun initRecorder(
    path: String,
    recorder: MediaRecorder?,
    encoder: Int,
    outputFormat: Int,
    sampleRate: Int,
    bitRate: Int?,
    promise: Promise
) {
    recorder?.apply {
        setAudioSource(MediaRecorder.AudioSource.MIC)
        setOutputFormat(MediaRecorder.OutputFormat.MPEG_4)
        setAudioEncoder(MediaRecorder.AudioEncoder.HE_AAC)
        setAudioSamplingRate(44100)
        setAudioChannels(1)
        setAudioEncodingBitRate(96000)
        setOutputFile(path)
        try {
            Log.i(Constants.LOG_TAG, getEncoder(encoder).toString())
            Log.i(Constants.LOG_TAG, getOutputFormat(outputFormat).toString())
            Log.i(Constants.LOG_TAG, sampleRate.toString())
            Log.i(Constants.LOG_TAG, bitRate.toString())
            prepare()
            promise.resolve(true)
        } catch (e: IOException) {
            Log.e(Constants.LOG_TAG, "Failed to stop initialize recorder")
        }
    }
}

// AudioWaveforms  I  3 ( MediaRecorder.AudioEncoder.HE_AAC )
// AudioWaveforms  I  2 ( There is no option to pass a value, but is not using the `else ->` that is MPEG_4 )
// AudioWaveforms  I  44100 ( 44100 )
// AudioWaveforms  I  null ( Not setting the correct 96000 value as provided on the `startRecorder` function )
    

Is there anything wrong that I am not passing as parameter? where can I pass the value for outputFormat?

Sidenote: it would be good to update your ExoPlayer lib dependency, I tested also and it worked with no breaking changes

implementation 'androidx.media3:media3-exoplayer:1.3.1'
implementation 'androidx.media3:media3-common:1.3.1'

gmantuanrosa avatar May 23 '24 14:05 gmantuanrosa