Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need Help Browser support #536

Open
jeromelarman opened this issue Jun 26, 2022 · 3 comments
Open

Need Help Browser support #536

jeromelarman opened this issue Jun 26, 2022 · 3 comments

Comments

@jeromelarman
Copy link

Hello,

I need to implement streaming feature from client side ( angular ) to upload large video file ( = 200Mo ).

Without streaming, all video content must to be loaded before request was post to back end.

Otherwise I try to implement Streaming with FormData client side and Busboy ( NodeJS ) server side.

I Use Browserify to generate bundle of form_data.js biu when I import it, the Native FormData is already available .. and not its from form-data

   <script src="js/core/custom/form-data/lib/form_data.bundle.js"></script>....

The bundle generated from browserify, below :

form_data.bundle.js.zip

I notice, native FormData does not support Streaming from client side ( arraybuffer, readablestream ) , Do yo have alternative if I can't achieve my goal ?

Thanks in advance.

@jimmywarting
Copy link

how do you get the video? a camera recording, a file from the disc?

@AlexMaisiura
Copy link

Without streaming, the entire video content needs to be loaded before it can be sent to the backend, which can cause performance issues for large files. You mentioned that you are trying to implement streaming using FormData on the client-side and Busboy on the server-side.

You also mentioned that you are using Browserify to generate a bundle of form_data.js, but you are encountering issues because the native FormData is already available and not the one from form-data. It seems like the native FormData does not support streaming from the client-side, such as arraybuffer or readablestream.

There are alternative libraries that you can use to achieve your goal of streaming large video files from the client-side to the server-side. One popular library is called axios, which supports streaming using axios.post() with a stream option. Another library is fetch, which also supports streaming using fetch(). You can use these libraries in conjunction with a streaming solution on the server-side, such as Busboy.

Here's an example of how you can use axios to stream a large video file from the client-side to the server-side:

`
// Client-side code
const axios = require('axios');

const file = document.getElementById('file-input').files[0];

axios.post('/upload', file, {
headers: {
'Content-Type': file.type,
'Content-Length': file.size
},
maxContentLength: Infinity,
maxBodyLength: Infinity,
stream: true // enable streaming
}).then(response => {
console.log(response.data);
}).catch(error => {
console.error(error);
});

// Server-side code
const Busboy = require('busboy');

app.post('/upload', (req, res) => {
const busboy = new Busboy({ headers: req.headers });

busboy.on('file', (fieldname, file, filename, encoding, mimetype) => {
console.log(File ${fieldname} started streaming);
file.on('data', (data) => {
// Handle file data
});
file.on('end', () => {
console.log(File ${fieldname} finished streaming);
});
});

busboy.on('finish', () => {
console.log('Busboy finished parsing');
res.sendStatus(200);
});

req.pipe(busboy);
});

`

I using the axios.post() with the stream option to enable streaming, and Busboy on the server-side to handle the streaming. You can modify this code to suit your specific needs, such as adding error handling and progress tracking

@jimmywarting
Copy link

😳 @AlexMaisiura

On the client side you are uploading a file with raw bytes.
you have not encoded the file in any way such as it's in a multipart/form-data (aka formdata)
So busboy will not be able to detect any such payload.

axios don't have any streaming functionality on the client side.
so setting stream: true is pointless? so is setting a content-length and a content-type. why may you ask? b/c when you send a file with either xhr or fetch then it will automatically append content-length + content-type for you when you upload a file or a blob. it dose this for everything that you send, URLSearchParams, FormData, Blob, File, and even strings, TypedArrays and ArrayBuffer unless you explicity need to set custom content-type yourself, which you don't do.

So all you really need is:

const file = document.getElementById('file-input').files[0];
axios.post('/upload', file).then(sucfn, errfn)

but i would not even use axios...
it's better to use fetch instead.

const [file] = document.getElementById('file-input').files
const result = await fetch('/upload', { method: 'POST', body: file }).then(res => res.arrayBuffer())

No dependencies needed...
then the hole req will be the file's stream. so no need for serializer such as busboy is even needed.

app.post('/upload', (req, res) => {
  req.pipe(dest)
})

oh... and fetch have streaming upload support now: https://docs.google.com/document/d/e/2PACX-1vQ26giyHPPhxrgVorNtkVSsJPOWecc6c6wHFLFbbl27r0BIBEgRwahh2b37Uk7HfXvZoW1Cu_ed-bRm/pub

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants