使用multer将音频文件上传到Express JS服务器。

3

我正在尝试使用express js和multer将记录的音频记录并保存在本地目录(上传文件夹)中。第一部分是使用mic-recorder-to-mp3录制音频,已经可以正常工作,但是我在第二部分遇到了困难,即点击按钮时保存音频文件。如果我有错误,请纠正我。

以下是在React JS文件中的代码:

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;

这是我的server.js代码,其中包含一个从客户端发送的POST请求。

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");
});
1个回答

2
您需要上传 blob 而不是 blobUrl。请将 blob 添加到状态中,然后将其附加到表单中(保留用于渲染的 blobUrl)。
 this.state = {
      blob: null
    };
//...

this.setState({ blob});

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

编辑

如果需要向文件添加更多元数据,可以从缓冲区创建文件,然后将其附加:

this.state = {
    buffer: null
};


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


data.append("audio", file);

@SarfarazAhmed,请尝试在编辑下尝试两个新选项。 - traynor
@SarfarazAhmed 也请注意,this.state.blob 没有被设置,请先在此行进行设置:https://gist.github.com/SarfarazAhmed1012/7e863cdebd5455aaba97c2dfcbce6486#file-audiorecord-js-L40 - traynor
1
是的!实际上第一个选项起作用了。我没有仔细检查它。我只需要在 data.append 方法中添加文件名即可。 - Sarfaraz Ahmed
1
@SarfarazAhmed 很好。您可以使用“文件”添加更多元数据。不,您只需要将“blob”添加到上传状态中,“blobUrl”和HTML部分保持不变,就像初始代码一样。 - traynor
谢谢!:) 感谢您的帮助。 - Sarfaraz Ahmed
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接