如何在JS/React下载MP4视频?

发布于 2025-01-20 22:06:20 字数 767 浏览 3 评论 0原文

这可能是很早就被问到的,但是我无法弄清楚,请帮助我,并提前感谢。

问题:

我有一个链接到mp4视频(ex: https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4

我想从前端下载此视频。

我已经尝试了以下方法:

 const videoHref ='https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4';
 const a = Object.assign(document.createElement('a'), {
 href: videoHref,
 style: 'display: none',
 download: 'video.mp4'
 });
 document.body.appendChild(a);
 a.click();
 a.remove();

但是当我执行此代码时,

下载将立即开始并失败,错误

失败 - 没有文件

请帮助我解决此问题。

This might have been asked early, but I am unable to figure it out, please help me and thanks in advance.

Problem:

I have a link to mp4 video (ex: https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4)

I want to download this video from front end.

I have tried the following method:

 const videoHref ='https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4';
 const a = Object.assign(document.createElement('a'), {
 href: videoHref,
 style: 'display: none',
 download: 'video.mp4'
 });
 document.body.appendChild(a);
 a.click();
 a.remove();

But when I execute this code,

the download will start and fails immediately with error

Failed - No file

Please help me resolve this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

浅浅 2025-01-27 22:06:21

我使用以下代码解决了它,

let xhr = new XMLHttpRequest();
xhr.open('GET', 'path/videoLink', true);
xhr.responseType = 'blob';
xhr.onload = function () {
let urlCreator = window.URL || window.webkitURL;
let videoUrl = urlCreator.createObjectURL(this.response);
let tag = document.createElement('a');
tag.href = videoUrl;
tag.target = '_blank';
tag.download = skillName.includes('.mp4') ? skillName : skillName + '.mp4';
document.body.appendChild(tag);
tag.click();
document.body.removeChild(tag);
};
xhr.onerror = (err) => {};
xhr.send();

I solved it using following code,

let xhr = new XMLHttpRequest();
xhr.open('GET', 'path/videoLink', true);
xhr.responseType = 'blob';
xhr.onload = function () {
let urlCreator = window.URL || window.webkitURL;
let videoUrl = urlCreator.createObjectURL(this.response);
let tag = document.createElement('a');
tag.href = videoUrl;
tag.target = '_blank';
tag.download = skillName.includes('.mp4') ? skillName : skillName + '.mp4';
document.body.appendChild(tag);
tag.click();
document.body.removeChild(tag);
};
xhr.onerror = (err) => {};
xhr.send();
爱已欠费 2025-01-27 22:06:21

高效的解决方案,带有 fetch

const handleDownloadVideo = async () => {
    try {
      const videoUrl = 'https://www.pexels.com/video/1093662/download/';
      const videoRequest = new Request(videoUrl);
      fetch(videoRequest)
        .then(() => {
          const link = document.createElement('a');
          link.href = videoUrl;
          link.setAttribute('download', 'waterfall.mp4');
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        });
    } catch (error) {
      console.error(error);
    }
  };

注意:这个答案类似于上面的一个,但带有 fetch

Efficient solution, with fetch

const handleDownloadVideo = async () => {
    try {
      const videoUrl = 'https://www.pexels.com/video/1093662/download/';
      const videoRequest = new Request(videoUrl);
      fetch(videoRequest)
        .then(() => {
          const link = document.createElement('a');
          link.href = videoUrl;
          link.setAttribute('download', 'waterfall.mp4');
          document.body.appendChild(link);
          link.click();
          document.body.removeChild(link);
        });
    } catch (error) {
      console.error(error);
    }
  };

Note: this answer is similar to one above, but with fetch.

心的憧憬 2025-01-27 22:06:21

将其添加到您的服务器端

import axios from 'axios';

const downloadVideo = async (req, res) => {
  try {
    const videoUrl = req.query.url; // The video URL passed as a query parameter

    const response = await axios({
      url: videoUrl,
      method: 'GET',
      responseType: 'stream',
    });

    // Set the response headers to indicate the video file as an attachment
    res.setHeader('Content-Disposition', `attachment; filename="video.mp4"`);

    // Pipe the video data directly to the response object
    response.data.pipe(res);
  } catch (error) {
    console.error('Error downloading the video:', error);
    res.status(500).json({ success: false, error: 'Failed to download the video.' });
  }
};

export default downloadVideo;

单击按钮即可将此代码添加到您的客户端应用程序中。

                  try {
                    fetch(`/api/download-video?url=${videoUrl}`)
                    .then(response => response.blob())
                      .then((blob) => {
                        const url = window.URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = 'video.mp4'; // Replace with the desired filename for the downloaded file
                        a.click();
                        window.URL.revokeObjectURL(url);
                      });
                  } catch (error) {
                    console.error(error);
                  }

Add this into your server side

import axios from 'axios';

const downloadVideo = async (req, res) => {
  try {
    const videoUrl = req.query.url; // The video URL passed as a query parameter

    const response = await axios({
      url: videoUrl,
      method: 'GET',
      responseType: 'stream',
    });

    // Set the response headers to indicate the video file as an attachment
    res.setHeader('Content-Disposition', `attachment; filename="video.mp4"`);

    // Pipe the video data directly to the response object
    response.data.pipe(res);
  } catch (error) {
    console.error('Error downloading the video:', error);
    res.status(500).json({ success: false, error: 'Failed to download the video.' });
  }
};

export default downloadVideo;

Add add this code into your client side application on the click of your button.

                  try {
                    fetch(`/api/download-video?url=${videoUrl}`)
                    .then(response => response.blob())
                      .then((blob) => {
                        const url = window.URL.createObjectURL(blob);
                        const a = document.createElement('a');
                        a.href = url;
                        a.download = 'video.mp4'; // Replace with the desired filename for the downloaded file
                        a.click();
                        window.URL.revokeObjectURL(url);
                      });
                  } catch (error) {
                    console.error(error);
                  }
吾家有女初长成 2025-01-27 22:06:21
fetch('https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4', {
    method: 'GET',
    headers: {
      'Content-Type': 'application/mp4',
    },
  })
  .then((response) => response.blob())
  .then((blob) => {
    const url = window.URL.createObjectURL(
      new Blob([blob]),
    );
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute(
      'download',
      `FileName.pdf`,
    );
    document.body.appendChild(link);
    link.click();
    link.parentNode.removeChild(link);
  });

让我知道它是否有效
谢谢

fetch('https://www.learningcontainer.com/wp-content/uploads/2020/05/sample-mp4-file.mp4', {
    method: 'GET',
    headers: {
      'Content-Type': 'application/mp4',
    },
  })
  .then((response) => response.blob())
  .then((blob) => {
    const url = window.URL.createObjectURL(
      new Blob([blob]),
    );
    const link = document.createElement('a');
    link.href = url;
    link.setAttribute(
      'download',
      `FileName.pdf`,
    );
    document.body.appendChild(link);
    link.click();
    link.parentNode.removeChild(link);
  });

let me know if it worked
thanks

浪荡不羁 2025-01-27 22:06:21

这样的功能对我有用,但有一个问题:

使用这种方法,你的浏览器将首先将视频存储在 RAM 中,当视频太大时,它会崩溃。我们在这里创建一个 blob,因为 a 标签下载属性需要源是您的域,当您在本地主机上测试它并尝试从另一个源下载时,它会抛出错误。

const downloadVideo = (urls: string) => {
  axios({
    url,
    method: 'GET',
    responseType: 'blob',
  }).then((response) => {
    const urlObject = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = urlObject;
    link.setAttribute('download', 'recording.mp4');
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  });
};

要下载视频而不创建 blob,它需要来自您的源,或者提供它的服务器需要附加 Content-Disposition 和允许源标头,然后您可以使用 atarget 来下载它="_blank" 属性

Such function work for me, but there's a catch:

with that approach ur browser will first store the video in the RAM and when the video is too big it will crash. We're creating a blob here, because a tag download attribute needs the origin to be ur domain, when u test it on localhost and you try to download from another origin it would throw an error.

const downloadVideo = (urls: string) => {
  axios({
    url,
    method: 'GET',
    responseType: 'blob',
  }).then((response) => {
    const urlObject = window.URL.createObjectURL(new Blob([response.data]));
    const link = document.createElement('a');
    link.href = urlObject;
    link.setAttribute('download', 'recording.mp4');
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
  });
};

To download video without creating a blob it needs to be from ur origin or the server serving it needs to append Content-Disposition and Allow Origin headers, then u can just download it with a with target="_blank" property

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文