使用 nodejs、multer 和 cloudinary 上传大型视频文件

Posted

技术标签:

【中文标题】使用 nodejs、multer 和 cloudinary 上传大型视频文件【英文标题】:Uploading large video file with nodejs, multer and cloudinary 【发布时间】:2021-09-02 02:10:50 【问题描述】:

我的代码适用于高达 50MB 的小视频,但是当视频重量超过 50MB 时,它会上传视频,但我没有得到任何云 URL,因此视频没有加载到我的前端部分。我在后端使用 nodejs 和 multer,并将 cloudinary 作为存储并作为前端做出反应。 有什么建议吗?

云配置

require("dotenv").config();
const cloudinary = require("cloudinary");
cloudinary.config(
  cloud_name: process.env.CLOUD_NAME ,
  api_key: process.env.API_KEY ,
  api_secret: process.env.API_SECRET ,
);
exports.uploads = (file) => 
  return new Promise((resolve) => 
    cloudinary.uploader.upload(
      file,
      (result) => 
        resolve( url: result.url, id: result.public_id );
      ,
       resource_type: "auto" 
    );
  );
;

视频控制器

const Video = require("../models/videoModel"),
  cloud = require("../config/cloudinaryConfig");
module.exports = 
  // Create action for a new video
  create: (req, res, next) => 
    // First check if the file exists in the Database
    let test = 
      name: req.files[0].originalname,
      url: req.files[0].path,
      id: "",
    ;
    console.log(req.files[0].originalname);
    Video.find( name: test.name , (err, cb) => 
      if (err) 
        res.json(
          error: true,
          message: `There was a problem uploading the video because: $err.message`,
        );
       else 
        let file = 
          name: req.files[0].originalname,
          url: req.files[0].path,
          id: "",
        ;
        cloud
          .uploads(file.url)
          .then((result) => 
            Video.create(
              name: req.files[0].originalname,
              url: result.url,
              id: result.id,
            );
          )
          .then((result) => 
            res.json(
              success: true,
              data: result,
            );
          )
          .catch((err) => 
            res.json(
              error: true,
              message: err.message,
            );
          );
      
    );
  ,
;

Multer 配置

const multer = require("multer"),
  path = require("path");
//multer.diskStorage() creates a storage space for storing files.
const imageStorage = multer.diskStorage(
  destination: (req, file, cb) => 
    if (file.mimetype === "image/jpeg" || file.mimetype === "image/png") 
      cb(null, path.join(__dirname, "../files"));
     else 
      cb( message: "This file is not an image file" , false);
    
  ,
  filename: function (req, file, cb) 
    cb(null, file.originalname);
  ,
);

const videoStorage = multer.diskStorage(
  destination: (req, file, cb) => 
    if (file.mimetype === "video/mp4") 
      cb(null, path.join(__dirname, "../files"));
     else 
      cb( message: "This file is not in video format." , false);
    
  ,
  filename: (req, file, cb) => 
    cb(null, file.originalname);
  ,
);
module.exports = 
  imageUpload: multer( storage: imageStorage ),
  videoUpload: multer( storage: videoStorage ),
;

【问题讨论】:

能否分享您从 Cloudinary 收到的完整回复 (result)? 尝试上传大文件时,这是我得到的响应:[错误:消息:'服务器返回意外状态代码 - 413',http_code:413,名称:'UnexpectedResponse' error: Error: write EPIPE at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:94:16) errno: -32, code: 'EPIPE', syscall: 'write' ] 这是文件超过 100MB 时的错误消息,但我不知道如何处理它 【参考方案1】:

上传文件到 Cloudinary 时,请求正文的最大大小可以是 100MB。任何大于此值的请求都会收到您看到的 413 错误。要上传大于 100MB 的文件,需要分块发送。

由于您使用的是 Cloudinary NodeJS SDK,因此您可以更新代码以使用 upload_large 方法进行上传,而不是常规的 upload 方法。

upload_large 方法应用于所有大于 100MB 的文件,因为它会拆分文件并自动为您分段上传。也就是说,您也可以对所有文件使用此uplaod_large 方法,即使它们的文件大小很小并且也可以。

它采用与上传方法完全相同的参数,并且还可以选择接受chunk_size(默认为 20MB)。

【讨论】:

以上是关于使用 nodejs、multer 和 cloudinary 上传大型视频文件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 multer 和 NodeJS 将图像上传到 GCS 存储桶?

如何在 NodeJS 中保存和显示使用 Multer 包保存的图片?

nodejs + multer + angularjs 无需重定向即可上传

NodeJS Multer 不工作

nodejs multer文件上传,路径包含双斜杠

使用 multer-s3 nodejs 将图像上传到亚马逊 s3