Record user audio success with undefined


#1

(original stackoverflow issue)

I am using Ionic, and would like to record audio to a file, then do something with the file.

So first, I create the file:

await this.file.createFile(this.getFileDirectory(), this.getFileName(), true);

When it is ready, I create a new Media instance:

this.currentRecording = this.media.create(this.getFilePath());

Attach a success and error listeners:

    this.currentRecording.onSuccess.subscribe((e) => {
      console.log(this.currentRecording.getDuration());
      console.log(e);
    });
    this.currentRecording.onError.subscribe((err) => console.error(err));

Then I start recording:
this.currentRecording.startRecord();

After a few seconds, I stop recording, this.currentRecording.stopRecord(), and the success callback is executed.

In the console, I now see

-1 // console.log(this.currentRecording.getDuration());

undefined // console.log(e);

Am I doing something wrong? How come it resolves to success, but with undefined, and no duration?

EDIT: These are my path functions

  private getFileDirectory() {
    return this.file.documentsDirectory || this.file.dataDirectory;
  }

  private getFileName() {
    return 'file.wav';
  }

  private getFilePath() {
    return this.getFileDirectory() + this.getFileName();
  }

#2

The example in Ionic Native has no returned valued for onSuccess as well: https://ionicframework.com/docs/native/media/#Usage

I remember the duration being unreliable in earlier post about Media.

Is the file created with the content you want?


#3

Thanks.
The file is of size 0 bytes as well, so while it does create it (the other plugin), it does not record to it.

EDIT:
this.currentRecording.play() throws {code: 1}
Also tried mp3 to clear that option, same errors


#4

I remember there being several topic on this in the past… As I have no personal experience I only helped to debug and didn’t “internalize” the solution, you could maybe search for and read them - maybe you find something.


#5

Reproducing my answer from SO here:

@Amit, I have cloned your repo and got the same results as you did. I fiddled with it for some time, there’s definetly some weird sh*t going on with the media plugin. I will try and spend some time sending some pull requests to add a few features and fix a few bad behaviours, just like with the getDuration().

Turns out the getDuration() function does not ask the native part of the plugin what was the duration, it returns with the saved value in the javascript, and this value only gets updated when the native code sends a message. So you won’t get the fresh current duration value. You could change the plugin to have it go get the duration in the native code using the cordova exec().

About the file, I started using the file plugin, but ended up tossing it out. Tried only with the media plugin, passing the file name only, no path. The file was stored in /storage/emulated/0/file.3gp. It was recorded, had content, and was playable. My guess is that using the file plugin and passing the full path string will have it create the file where you want it. But when you pass the same path to the media plugin it is not honoring that, because when I used it the file was allocated but after the recording it had 0 bytes, but still I could play the recording, so it must have stored it somewhere else.

If using the media plugin alone solves your problem like it did for me, great! If it doesn’t and you still would like to keep working on this, I suggest you use android monitor in Android Studio to monitor native messages and look at the plugin’s code. This is how I found out about theses things.

FYI to those looking for an alternative to the media plugin, @AmitMY ended up using cordova-plugin-audioinput instead.