llfbandit / record

Audio recorder from microphone to a given file path. No external dependencies, MediaRecorder is used for Android an AVAudioRecorder for iOS.
https://pub.dev/packages/record
241 stars 202 forks source link

Calling `stop` too quickly after `start` generates an empty (0 byte) file #266

Open andrewkolos opened 10 months ago

andrewkolos commented 10 months ago

Package version: 5.0.4

Environment Windows 11 Pro Version 22H2 (OS Build 22621.2861)

Starting a recording and quickly stopping it (within a small fraction of a second) risks creating a completely empty file.

To Reproduce

Repro project: https://github.com/andrewkolos/_repro_start_and_stop_record/tree/main/start_and_stop_empty_file

If using this project:

Logs from me using this app to generate a zero-length recording ``` flutter: Started recording with a duration of 0:00:00.000000 flutter: Stopping recording at 35 milliseconds... flutter: Finished stopping at 293 milliseconds. flutter: You can find your audio file at C:\Users\Jozz\Documents\record_start_stop_empty_file_repro\599614901.m4a flutter: Duration between .start() being called and .stop() being called was 0:00:00.035000 flutter: Duration between .start() being called and .start() finishing was 0:00:00.035000 flutter: Duration between .start() finishing and .stop() being called was 0:00:00.000000 flutter: Duration between .start() finishing and .stop() finishing was 0:00:00.258000 flutter: Duration between .start() being called and .stop() finishing was 0:00:00.293000 flutter: Running ffprobe: ffprobe -i C:\Users\Jozz\Documents\record_start_stop_empty_file_repro\599614901.m4a -show_entries format=duration -sexagesimal -v quiet -of csv=p=0 flutter: ffprobe failed to run. Is the file empty? flutter: ```

If not using the provided repro project, code similar to this will probably repro the issue:

recorder
    .start(
      const RecordConfig(encoder: AudioEncoder.aacLc),
      path: audioPath,
    )
    .then((_) => recorder.stop()); // Calls stop as soon as start is done.

Workaround

Since the audio file is empty, it's easy to determine that the file is not valid audio. Personally, I just check the audio file is empty before trying to process it.

andrewkolos commented 10 months ago

Something I forgot to add is that this can happen even with non-zero-length recording sessions, as long as the duration is short enough. For example, calling stop ~50ms after start will still produce an empty file. I wonder if audio data is being lost?

Feel free to tweak the provided repro code to try this with different durations.

llfbandit commented 10 months ago

@andrewkolos I suppose the callback to fill audio data had no chance to be called before you stopped the recording so soon. From here, internally there's a Finalize method called to fill headers and properly place end marker. In such case, I guess the writer doesn't know what to do and so does nothing...? Well, in short, I need to investigate.

@AkshatBaranwal Please a proper separated issue, this has nothing related with the current one.

atoka93 commented 8 months ago

It is happening on iOS as well.