Reputation: 15
I want to copy data from one stream to another in Java i do in below way
ByteStreams.copy( inputStream, outputStream );
In Node JS i am trying to find out how to do that
// Making an ajax call to get the Video file
const getVideo = async (req, res) => {
try {
axios.get('Video URL')
.then(function (videoResponse) {
res.setHeader("Content-Type", "video/mp4");
// copy the inputStram of videoResponse
//to the output stram of res
// copy the videoResponse to res
})
} catch (error) {
console.log(error);
}
};
Can anyone suggest how to do that, Thank you for your help
Upvotes: 0
Views: 2430
Reputation: 2909
You need to set the responseType
from axios to 'stream'
, then you can pipe data from the input stream to the response stream using .pipe()
.
// Making an ajax call to get the video file
const getVideo = async (req, res) => {
try {
axios({
method: 'get',
url: 'Video URL',
responseType: 'stream'
}).then((videoResponse) => {
res.setHeader("Content-Type", "video/mp4");
videoResponse.data.pipe(res);
});
} catch (err) {
console.log(err);
}
}
For more information about the .pipe()
function, please read the Node.js docs.
For more information about axios request configuration options, please read the axios docs.
Upvotes: 2
Reputation: 1897
The most simple example for reading and writing to File System would be:
const fs = require('fs')
const input = fs.createReadStream('input_file')
const output = fs.createWriteStream('output_file')
input.pipe(output)
Check the File System docs for Node.js.
The input and output stream can be any ReadStream and WriteStream, like an HTTP response or S3 for example.
From the Axios Github README you have the example which looks very similar to what you are trying to do (please use the original one, I had to change the URL here)
// GET request for remote image in node.js
axios({
method: 'get',
url: 'https://lh3.googleusercontent.com/iXm....',
responseType: 'stream'
})
.then(function (response) {
response.data.pipe(fs.createWriteStream('ada_lovelace.jpg'))
});
Upvotes: 1
Reputation: 6809
The example below streams video outpu. I am assuming you need something similar. Can you try something like this and based on this example modify your code
const express = require('express')
const fs = require('fs')
const path = require('path')
const app = express()
app.get('/', function(req, res) {
res.sendFile(path.join(__dirname + '/index.html'))
})
app.get('/video', function(req, res) {
const path = 'assets/sample.mp4' //This can be replaced by axios.get('Video URL')
const stat = fs.statSync(path)
const fileSize = stat.size
const range = req.headers.range
if (range) {
const parts = range.replace(/bytes=/, "").split("-")
const start = parseInt(parts[0], 10)
const end = parts[1]
? parseInt(parts[1], 10)
: fileSize-1
const chunksize = (end-start)+1
const file = fs.createReadStream(path, {start, end})
const head = {
'Content-Range': `bytes ${start}-${end}/${fileSize}`,
'Accept-Ranges': 'bytes',
'Content-Length': chunksize,
'Content-Type': 'video/mp4',
}
res.writeHead(206, head)
file.pipe(res)
} else {
const head = {
'Content-Length': fileSize,
'Content-Type': 'video/mp4',
}
res.writeHead(200, head)
fs.createReadStream(path).pipe(res)
}
})
app.listen(3000, function () {
console.log('App is running on port 3000')
In the above code:
At the top I have included needed NPM packages. After that we have a get method served on route '/' for serving the html file. Then there is a get method with route '/video' which is being called from html file. In this method at first the filesize is detected with statSync
method of fs
. after that with stream video is downloaded to client in chunks. With every new request from client the value of start and end is changing to get the next chunk of video. 206 is set in response header to send only newly made stream(chunk of video).
Credit - Example source
Upvotes: 0