0

I've got google extension, react frontend app and express server. I use mediaRecorder to record my screen and insert it into frontend page.There is no problem, video works just fine in frontend

const blob = new Blob(chunks, { type: "video/mp4;" });
const savedVideo = document.getElementById("savedVideo");
chunks = [];

const videoURL = window.URL.createObjectURL(blob);
savedVideo.src = videoURL;

var tracks = stream.getTracks();
tracks[0].stop();

let response = await fetch('http://localhost:3001/upload', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/octet-stream',
  },
  body: blob
});

The problem starts when i send blob to server.I want to save video(Only on server side)I suppose problem is in handling blob on the server side, maybe I doing smth wrong, here my server code:

const express = require("express");
const cors = require('cors');
const fs = require('fs');

const app = express();
const port = 3001;

app.use(cors({
  origin: 'http://localhost:3000'
}));

app.post("/upload", (req, res) => {
  console.log('req.body', req.body)
  req.on('readable', function(){
    const data = req.read();
    if(data) {
      fs.createWriteStream('videeoo.mp4').write(data);
      // also i didnt sure about this method to write file
    }
    console.log('data', data);
  });        
});

app.listen(port, () => {
  console.log(`Server started at http://localhost:${port}`);
});

express logs

I'am waiting your best practices)Grasias!

2 Answers 2

1

In order to handle blobs in nodejs app.post() you should introduce express.raw() into it. Then you can create a blob from the buffer:

app.post('/raw/:cmd', express.raw({type: "*/*"}), async (req, res) => {
    const buffer = req.body
    const blob = new Blob([buffer], {type: "application/octet-stream"})
})
Sign up to request clarification or add additional context in comments.

1 Comment

In addition to this, be careful when using express.json() middleware as well. Also you may not need to create Blob object as req.body itself is Blob object
0

well... this is problematic... the req.read() doesn't normally process binary data. There's also a conceptual issue here: a video can potentially be huge, but in your application you're waiting for the whole file to be uploaded before you start writing it. So if you have 10 users, each uploading 10GB files, this is a problem. So you really want to store the file as it arrives, so that you only keep a few bytes in your memory at a time... but then what if you want to limit the size of the file? probably 10GB files is not something you want to deal with?

So... there are really a lot of corner cases and things to consider. In general, you don't want to handle these things manually. Luckily there are libraries like multer that can handle all these issues for you: https://expressjs.com/en/resources/middleware/multer.html you just define the destination directory, the max file size, etc and the library takes care of everything for you

3 Comments

I need to send it to backend and then to s3.So you say that i need to save file in backend folder, am i right?Thanks for reply)
noooooooo! you didn't mention S3 before. This is not how you use S3! AWS S3 (and all object stores for that matter, no matter what cloud you go to) have a very specific way to handle the file upload. The file should not go through your server at all. What you need is 1. user sends a request to your backend saying that he wants to upload a specific file with size A bytes, name B etc, 2. backend generates a pre-signed S3 URL (a special URL that if valid only for this specific file name with this specific size only for the next few minutes) and user uploads the file to that URL

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.