File download with reactjs doesn't work correc

2019-07-29 06:33发布

问题:

I'm implementing a youtube video downloader using ytdl-core with Nodejs backend and Reactjs frontend. However, using ytdl-core library I'm able to send to youtube video file to frontend with this codeblock

app.get('/download', (req, res) => {
    let { url, itag } = req.query;
    let id = ytdl.getURLVideoID(url);

    ytdl.getInfo(id, (err, info) => {
        if (err) {
            console.log(err);
            throw err;
        }
        else{
            let audioandvideo = ytdl.filterFormats(info.formats, 'audioandvideo');       
            let video = audioandvideo.filter(obj => obj.itag === itag);

            video = video[0]

            res.header('Content-Disposition', `attachment; filename="${info.title}.${video.container}"`);
            res.header('Content-Type', 'video/webm');

            ytdl(url, {
                format: video
            }).pipe(res); 
        }             
    })
});

However, the file downloads correctly if I redirect the webpage to the route like this

window.location.href = `http://localhost:5000/download?url=${this.state.url}&itag=${itag}`;

This works fine and the video downloads correctly. But as it's a redirection I can't do that in a hosted site. So, I need to use axios to do this.

I did some research and found out some solutions. I tried with js-file-download library following the accepted answer here. It downloads the file to the client directory but the file won't play. This is the codeblock I used for that

  downloadVideo(itag){

    axios.get(`http://localhost:5000/download`, {
      params: { url: this.state.url, itag },
    })
    .then(response => {
      fileDownload(response.data, `video.mp4`);
    })
    .catch(err => console.log(err));
  }

As it's not working I tried another approach mentioned in the previously mentioned StackOverflow answer as well. It also downloads the file but doesn't work as well.

How can I get this fixed? What may be the reason my axios request doesn't work correctly?

EDIT :

downloadVideo(itag){
    axios.get(`http://localhost:5000/download`, {
      params: { url: this.state.url, itag },
      responseType: Blob
    })
    .then(response => {
      fileDownload(response.data, `video.mp4`);
    })
    .catch(err => console.log(err));

    // window.location.href = `http://localhost:5000/download?url=${this.state.url}&itag=${itag}`;
  }

This is the frontend code. If I use the commented code block (window.location.href) instead of axios.get the file gets downloaded and it works. But if I use axios.get a file gets downloaded but it seems to be a broken file as it's not playing.