tvanc
tvanc

Reputation: 4324

Stream audio directly from browser to server

I'd like to start uploading audio recorded from a mic as soon as the user hits Record, rather than wait until they're done. Is this possible with browser JavaScript?

I tried this just to get started, but the request ends immediately instead of continuing as long as the recorder is recording.

Client (browser) code

navigator.mediaDevices.getUserMedia({ audio: true }).then(
  (stream) => {
    const recorder = new MediaRecorder(stream)

    recorder.onstart = async () => {
      await fetch("/stream/upload", {
        method: "POST",
        headers: { "Content-Type": "multipart/form-data" },
        body: stream,
        allowHTTP1ForStreamingUpload: true,
      })

      console.log("Upload complete!")
    }
  },
  (err) => console.error("Error: " + err)
)

Server code

const app = express()

app.post("/stream/upload", (req, res, next) => {
  res.status(200)

  req.on("data", (chunk) => {
    // only appears once
    console.log("Data received")
    res.write(chunk)
  })

  req.on("end", () => {
    // and then this appears immediately after
    console.log("Stream ended")
    res.send("Ended")
  })
})

Upvotes: 4

Views: 6620

Answers (1)

dontcallmedom
dontcallmedom

Reputation: 2480

onstart is only called when the recording start - you need to instead upload data as part of the dataavailable event - to make that event happen more frequently, use the timeslice parameter of the start method.

That being said, depending on the underlying use case, you may be better served by using WebRTC to stream the audio content to the server.

Upvotes: 2

Related Questions