Audio recording with the native media plugin on android


#1

I’m trying to use the native media plugin on ionic 2 to record and play media, but there are several issues…First, my code:

First thing, I create a directory with the file plugin…

this.File.resolveDirectoryUrl(cordova.file.dataDirectory).then((result) => {
    this.File.getDirectory(result,"temp_audio",{create: true}).then((tempDir) => {
    }, (error) => {});
}, (error) => {});

And then I made a function to begin recording, that first creates a file in a temp directory and then begins recording to it…

record(audio_number: number): Promise<MediaObject>{
    let path = cordova.file.dataDirectory.toString() + "temp_audio/";
    let filename = "L"+ audio_number +".3gp";
    let full_path = path + filename;
    return this.File.createFile(path,filename,true).then((audio_file) => {
        return this.media.create(full_path).then((mediaObj) => {
            mediaObj.startRecord();
            return mediaObj;
        });
    });
}

And then afterwards this function is called to finish the recording.

finishRecord(mediaObj: MediaObject, audio_number: number){
    let path = cordova.file.dataDirectory.toString() + "temp_audio/";
    let filename = "L"+ audio_number +".3gp";
    let full_path = path + filename;
    mediaObj.stopRecord();
    return Promise.resolve(full_path);
}

I do so by having a button that starts recording and creates an alert; dismissing the alert will send the record function’s mediaObj return parameter as an argument for finishRecord, like so:

recordAudio(){
    this.audioService.record(this.audio_no).then((mediaObj) => {
        let btnStop = {
            cssClass: 'alertButtonDanger',
            text: this.translate.instant('record.stop'),
            role: 'cancel',
            handler: () => {
                this.finishRecording(mediaObj);
            }
        };
        let alert = this.alertCtrl.create({
            title: this.translate.instant("record.recording"),
            buttons: [btnStop]
        });
        alert.present();
    });
}

But…what’s actually going on is that on my phone’s root I get a tmprecording.3gp file which keeps recording on and on until I close the app.


#2

So, which of you code actually works and which doesn’t?

Does it create the directory?
Does is create a file in the temp directory?
Does is record audio to that file?
Does it finish the recording when the function is called?


#3

The directory is created.
The file is created inside the temp directory.
It does not record the audio to the file; instead, it creates a new file at the phone’s root named tmprecording<bunch of numbers>.3gp. That’s not the name I gave to the file, either.
It does not finish when the finishRecord function is called; instead, it keeps recording until the app is closed.


#4

we only need a uri :frowning:


#6

Hey, did you found a solution?
I’ve had the same problem but i solved, if you want to khow how, i can explain to you :wink:


#7

I ended up fixing it; the problem at the time is that I was not actually finishing the recording with StopRecord().


#10

2 posts were split to a new topic: Ionic 1 and cordova-media-plugin 3.0.1 - stopping recording on Android doesn’t work


#11

Hi @eltonfaust Could you please share code for recording and playing on android with the latest native media plugin? I’m having troube working out the paths.


#12

After many hours of googling I have come up with this solution. Notice that cordova media plugin on Android does not respect path parameter e.g. new Media(src). In any case recordings will be stored in Android’s root directory storage/emulated/0/ in my case.

So pass only filename as src parameter and when the recording is done move the file to your desired location. Also no need to use cordova files plugin.

function writeAudio() {
  var src = getTempRecordingLocation().fileName;
  mediaRec = new Media(src,
    function () {
      console.log("recordAudio(): Audio Success");
      mediaRec.release();

      window.resolveLocalFileSystemURL(getTempRecordingLocation().dirName + getTempRecordingLocation().fileName, function (e) {
        $scope.currentCard.sound.url = e.toInternalURL();
        $scope.$apply();
      }, function (error) {
        console.error(error)
      });
    },
    function (err) {
      console.log("recordAudio(): Audio Error,", err);
    });

  mediaRec.startRecord();
}

function getTempRecordingLocation() {
  if (device.platform === 'iOS') {
    return {dirName: cordova.file.tempDirectory, fileName: 'upcard_rec.wav'};
  } else if (device.platform === 'Android') {
    return {dirName: cordova.file.externalRootDirectory, fileName: 'upcard_rec.amr'};
  }
}

Then, if you want to attach audio file to pouchdb document run this code

function uploadAudio(card) {
  return fileReader.readFile($scope.currentCard.sound.url)
    .then(function (file) {
      var blob = new Blob([new Uint8Array(file)], {type: 'audio/mpeg'});
      return PouchDBService.getCardsDB().putAttachment(card._id, 'audio_file', card._rev, blob, 'audio/mpeg')
        .then(function (res) {
          if (res) {
            card._rev = res.rev;
          }
          return card;
        });
    })
    .catch(function (err) {
      console.error(JSON.stringify(err));
    });
}

#13

You can check my awnser to @danielle113 in this topic, there i explain why doesn’t working on android and have @danielle113 corrected code


#14

Yes, I saw that thank you.

It appears to be recording OK (I can verify by sharing the recorded file off the device by Bluetooth). However, I can’t work out the paths to play the recorded audio.

I have tried setting media.create(src) to the externalDataDirectory (both with and without file:// in the path). Also tried moving the file into dataDirectory and setting media.create(src) there, but no luck.

What path do you use as the src to play a recorded audio file?

These are the versions…

Ionic Framework: ionic-angular 3.5.3
Cordova Platforms: android 6.1.2
Cordova CLI: 6.5.0
Ionic CLI: 3.5.0
ionic-native/media: ^4.0.1
cordova-plugin-media: ~3.0.1

#15

What path do you use ?