Upload a file audio as blob to Firebase Storage

Hi community, I am recording an audio using MediaCapture and everything fine, that works perfect, then with the data of the file recorded and saved locally I am trying to save the recorded audio in Firebase Storage, I try to convert with the fullPath of the file in a blob to upload it but the conversion always returns empty or null I’ve also tried with file.readAsArrayBuffer but it always returns null, could someone tell me what I’m doing wrong?
I am using Ionic 5

recordAudio() {
    const options: CaptureAudioOptions = { limit: 1, duration: 5 };
    this.mediaC.captureAudio(options)
      .then(async (data: MediaFile[]) => {
        const metadata = {
          contentType: 'audio/amr',
        };

        this.directory = data[0].fullPath;
        const capturedAudio = data[0];
        const localAudioPath = capturedAudio.fullPath;
        const directoryPath = localAudioPath.substr(0, localAudioPath.lastIndexOf('/'));
        const fileName = localAudioPath.substr(localAudioPath.lastIndexOf('/') + 1);
        // const captureDataUrl = this.utils.dataURItoBlobAudio('data:audio/amr;base64,' + localAudioPath);
        const audioBlob: any = new Blob([localAudioPath], { type: 'audio/amr' });
        alert('audiBlob ' + JSON.stringify(audioBlob));
        const storageRef = firebase.storage().ref();
        const uploadAudio = storageRef.child(`files_audio/${fileName}`)
        .put(audioBlob, metadata).then((sus) => {
          sus.ref.getDownloadURL().then((url) => {
            alert('url => ' + url);
          }).catch((er) => {
            this.utils.presentToastSimple('Error al obtener ruta del audio: ' + er, 5000);
          });
        }).catch((error) => {
          alert('Error al guardar la imagen: ' + error);
        });
         //  const fileBlob = new Blob([this.base64ToArrayBuffer(data[0].fullPath)], { type: 'audio/amr' });
      }).catch((err: CaptureError) => {
        alert('CaptureError: ' + JSON.stringify(err));
      });
  }

Not sure if you are using vanilla JS, Angular, React or Vue. This is how I uploaded audio files to Firebase on an Ionic Vue application.

Get the file content from the input
Pass it to the dispatch function fileUpload in vuex
Create a “human friendly” file name and path then upload

TEMPLATE

          <ion-input
            type="file"
            :value="file"
            @input="fileSelected($event.target.files[0])"
            name="file"
            id="uploader"
          />

SCRIPT

    fileSelected(file) {
      this.$store
        .dispatch("fileUpload", file)
        .then(() => {
          this.$store.commit("loading", false);
        })
        .catch(error => {
          this.showAlert(error.message);
        });
    },

VUEX

    fileUpload(context, data) {
      // onChange create artist folder/song path
      // upload song
      const { artist, artist_, song, file } = data;

      return new Promise((resolve, reject) => {
        const storageRef = firebase.storage().ref(`poll/${artist_}/${artist} - ${song}`);

        const task = storageRef.put(file);

       // progress bar
        task.on("state_changed",
          function progress(snapshot) {
            const percentage = (snapshot.bytesTransferred / snapshot.totalBytes) * 100;
            // eslint-disable-next-line
            console.log("percentage,,", percentage);
            context.commit("uploadPercentage", percentage);
          },

          function error(error) {
            reject(error);
          },

          function complete() {
            context.dispatch("fetchSongUrl", {storageRef, artist, song });
            resolve();
          }
        )
      });
    },

Note: This was written in August 2019, Firebase Storage API could have changed since then.

thanks for your answer, I am using Angular and from an input it works perfectly, I already tried it, but what I want is to upload the audio after recording it,

Ah okay I misunderstood your question

don’t worry, I hope you can help me with this little problem

this is some old code from this old blog post https://dev.to/aaronksaunders/how-to-record-videos-in-reactjs-with-capacitor-and-cordova-plugins-1d36, it is react, but the part for converting the file is just javascript

let resolvedPath: DirectoryEntry;
let path = media.fullPath.substring(0, media.fullPath.lastIndexOf("/"));
if (Capacitor.getPlatform() === "ios") {
  resolvedPath = await File.resolveDirectoryUrl("file://" + path);
} else {
  resolvedPath = await File.resolveDirectoryUrl(path);
}

Once we get the resolved path, we can then read the file into a blob using File.readAsArrayBuffer and upload the blob to firebase.

return File.readAsArrayBuffer(resolvedPath.nativeURL, media.name).then(
  (buffer: any) => {
    // get the buffer and make a blob to be saved
    let imgBlob = new Blob([buffer], {
      type: media.type,
    });
    setFileData(imgBlob);
  },
  (error: any) => console.log(error)
)
1 Like

thanks for you help, but buffer return null
imagen

the truth I can’t find the error

are you running this on android?

Yes, android device, I’m already going crazy

there is an issue with that plugin, it hasnt been updated in awhile, there is a hack to get it to work listed here: https://github.com/aaronksaunders/photo-video-react-cap-file-upload-hook

that works for audio capture too or only with videos?

because I already have the audio file ready, the only thing I need is to convert it into a blob to upload to Storage Firebase