Home > Software engineering >  Uploading an audio file to the express js server using multer
Uploading an audio file to the express js server using multer

Time:11-03

I am trying to record and then save the recorded audio in my local directory(uploads folder) using express js and multer. The first part was recording audio which is working using mic-recorder-to-mp3, but I am stuck in the second part which is saving the audio file on the button click. Please correct me if I am doing something wrong. Here is the code in React JS file:

const Mp3Recorder = new MicRecorder({ bitRate: 128 });

class Record extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      isRecording: false,
      blobURL: "",
      isBlocked: false,
    };
  }

  start = () => {
    if (this.state.isBlocked) {
      console.log("Permission Denied");
    } else {
      Mp3Recorder.start()
        .then(() => {
          this.setState({ isRecording: true });
        })
        .catch((e) => console.error(e));
    }
  };

  stop = () => {
    Mp3Recorder.stop()
      .getMp3()
      .then(([buffer, blob]) => {
        const blobURL = URL.createObjectURL(blob);
        this.setState({ blobURL, isRecording: false });
      })
      .catch((e) => console.log(e));
  };

  componentDidMount() {
    navigator.getUserMedia(
      { audio: true },
      () => {
        console.log("Permission Granted");
        this.setState({ isBlocked: false });
      },
      () => {
        console.log("Permission Denied");
        this.setState({ isBlocked: true });
      }
    );
  }

  // this function being called on save button
  Save = (e) => {
    e.preventDefault();
    const url = "http://localhost:8000/record";
    const data = new FormData();
    data.append("audio", this.state.blobURL);

    axios.post(url, data).then((e) => {
      console.log("success");
    });

    alert("audio uploaded successfully");
  };

  render() {
    return (
      <div className="big-wrapper light">
        <div className="container">
          <Navbar />
          <br />
          <br />
          <br />
          <div className="cont1">
            <h2 style={{ color: "white", marginLeft: "-98px" }}>
              Remove Noise From Your Audio
            </h2>
            <br />
            <Button
              className="bg-transparent border btn record-button rounded-circle shadow-sm text-center"
              id="recordButton"
              onClick={() => {
                this.state.isRecording ? this.stop() : this.start();
              }}
            >
              {this.state.isRecording ? <img src={stop} /> : <img src={mic} />}
            </Button>
            <br />
            <br />
            <audio
              src={this.state.blobURL}
              controls="controls"
              autoPlay
              id="audio-element"
            />
            <br />
            <br />
            <form
              method="post"
              action="#"
              id="#"
              onSubmit={this.Save}
              className="form-group"
            >
              <button className="btn-recordaudio">Save</button>
            </form>
          </div>
        </div>
      </div>
    );
  }
}

export default Record;

And here is my server.js code in which I am having a post request which is being sent from client side.

app.use(cors());
app.use(express.static("uploads"));

const storage = multer.diskStorage({
  destination(req, file, cb) {
    // directory to save the audio
    cb(null, "uploads/");
  },
  filename(req, file, cb) {
    const fileNameArr = file.originalname.split(".");
    // file name
    cb(null, `recording.${fileNameArr[fileNameArr.length - 1]}`);
  },
});

const upload = multer({ storage });

app.post("/record", upload.single("audio"), (req, res) =>
  res.json({
    success: true,
  })
);

app.listen(8000, () => {
  console.log("server is running");
});

CodePudding user response:

You need to upload blob, not blobUrl Try adding blob to the state, and then append it to the form (keep the blobUrl as is for rendering):

 this.state = {
      blob: null
    };
//...

this.setState({ blob});

//...
data.append("audio", this.state.blob, 'mp3.mp3');

edit

you can create a file from buffer and then append it in case you need to add more metadata to the file:

this.state = {
    buffer: null
};


const file = new File(this.state.buffer, 'mp3.mp3', {
    type: this.state.blob.type
});


data.append("audio", file);
  • Related