Canardoux / flutter_sound

Flutter plugin for sound. Audio recorder and player.
Mozilla Public License 2.0
869 stars 568 forks source link

File size is too large #26

Closed ukrx-xamd closed 5 years ago

ukrx-xamd commented 5 years ago

Testing in both iOS and Android on emulators and real devices - the file size produced with this plugin is very high. As an example 17 seconds recording gives a file size of 4.3Mb. The plugin audio_recorder gives the same 17 second recording as 59.2k which is a considerable difference - thus , in its current form , this renders the plugin unusable as even if we were to compress recordings and uncompress there is a noticeable lag in application performance when compressing/uncompressing. Is it possible to produce AAC files which are considerably smaller in size or allow a switch to select output format ? If so - this would make this an invaluable plugin.

hyochan commented 5 years ago

I am currently not compressing audio file which will result in extra audio range which human's can't hear. This could be compressed in the audible boundary. Currently, you can do that in your backend.

ukrx-xamd commented 5 years ago

Yes of course submitting the audio as a byte array to a firestore function that could perform a conversion to a smaller sized suitable format will work but opens up a dependency to a backend service and adds further latency to a problem most suitable to the plugin itself

hyochan commented 5 years ago

@ukrx-xamd Yes you are right! I'd love to upgrade this if I am available but currently I am running out of time. Would love to see PR from anyone of you. Also, I may focus on this in 100 days I think.

ukrx-xamd commented 5 years ago

For both of your Android and iOS projects - you can see a big improvement in terms of the size of the audio files generated by simply making small changes to your start recorder methods (NO CODE CHANGE - JUST CHANGE THE SETTINGS).

Have a look at the two attached images which shows the new settings I am recommending - especially for iOS - when I apply these settings , a 17 second audio is no longer approx 5mb but now 26k. Long term you may want to parameterize these methods so that a user can specify the audio encoder/output format for Android and sample rate/number of channels/AvAudioQuality etc for iOS.

Additionally for MIC recordings - these settings do not shown any degradation in terms of sound quality and thus do not require compression , will make this plugin much more usable especially if the recorded sound files are being streamed to a cloud backend.

android - recorder settings ios - recorder settings

hyochan commented 5 years ago

@ukrx-xamd Thank you for the suggestion and your amazing drawing skills. I think this could be provided as parameters rather than just changing the values.

ukrx-xamd commented 5 years ago

@hyochan - 1.2.2 & 1.2.3 has the new sampleRate and numChannels parameters - I can confirm that these settings drastically improve the file size for a 10 second audio in iOS . Previously - 10seconds = 2.6Mb . Now with :

sampleRate = 16,000 numChannels = 1

Size is now 860k.

This is still very large for only 10 seconds.

If you also allow AvFormatIDKey & AvEncoderAudioQualityKey to be set from the current defaults then you can get the 10 second audio from 860k down to 26k & again - you will not see any noticeable audio degradation.

hyochan commented 5 years ago

@ukrx-xamd Hope you could give us PR on that.

ukrx-xamd commented 5 years ago

@hyochan - i'm stretched completely so have absolutely no slack yet - the quickest fix you could do is change your defaults, i.e

default AVFormatIDKey to kAudioFormatMPEG4AAC rather than lossless default AVEncoderAudioQualityKey to AVAudioQuality.min.rawValue rather than AVAudioQualityMedium

doing this quick change you will see the size drop dramatically and again, audio will not be degraded.

hyochan commented 5 years ago

@ukrx-xamd I hope you can give us the PR on that too that would take only about a minute. I've tried your fixes just now and having a problem setting your second config.

default AVEncoderAudioQualityKey to AVAudioQuality.min.rawValue

To prevent this communication loss, I think creating PR would be more productive.

ukrx-xamd commented 5 years ago

This is the swift version which works for me :

private func startRecorder( path: String, maxVolume: String?, _ result: FlutterResult) { let recordSetting: [String: Any] = [ AVSampleRateKey: NSNumber(value: 16000), AVFormatIDKey: (value: kAudioFormatMPEG4AAC), AVNumberOfChannelsKey: NSNumber(value: 1), AVEncoderAudioQualityKey: NSNumber(value: AVAudioQuality.min.rawValue) ]

lastRecordPath = URL(fileURLWithPath: "\(NSTemporaryDirectory())\(path).aac")

let session = AVAudioSession.sharedInstance()

do {
  try? session.setCategory(AVAudioSessionCategoryPlayAndRecord)
  try session.setActive(true)

  if let recordPath = lastRecordPath {
    recorder = try AVAudioRecorder(url: recordPath, settings: recordSetting)
  }
  recorder?.isMeteringEnabled = true
  recorder?.prepareToRecord()
  recorder?.record()

} catch {
  result(FlutterError.init(code: channelName, message: "start record failed", details: error))
}

result(lastRecordPath?.absoluteString)

if maxVolume != nil {
  self.volume = Double(maxVolume!)!
  timer = Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(self.updateVolume), userInfo: nil, repeats: true)
  print(timer!)
}

}

hyochan commented 5 years ago

I think the value should be AVAudioQualityMin according to apple doc.

ukrx-xamd commented 5 years ago

@hyochan - Excellent my friend!!

This is perfect.

10 secs = 56k with 1.2.4

Well done

hyochan commented 5 years ago

@ukrx-xamd Noo. It was your fixes and your work. Hope you can prove that by PRing next time. Also, I'd really like to know what drawing tool you are using. 🤔

ukrx-xamd commented 5 years ago

hey - I wrote here :

https://github.com/dooboolab/flutter_sound/issues/30

about the tool ...

but its here again :

https://www.draw.io/

you will love it - quick and easy ...