【问题标题】:s3 file upload - not working for video - React/Meteor - aws-sdks3 文件上传 - 不适用于视频 - React/Meteor - aws-sdk
【发布时间】:2021-01-07 10:13:22
【问题描述】:

我在我的 react/meteor 项目中将 mp4 文件上传到我的 s3 存储桶时遇到问题。它适用于其他类型的文件(mp3、图像),但不适用于视频。我没有收到任何错误,但是当我尝试读取上传的文件时它不起作用。

这是我的客户端代码:

import React from "react";
import { Meteor } from "meteor/meteor";
import PropTypes from "prop-types";
import { types } from "../../../utils/constants/types";

const FileUpload = ({ fileType, type, typeId, subtype, setFileName }) => {
  const handleUpload = event => {
    event.preventDefault();
    const file = event.target.files[0];
    const fileExtension = file.type;
    var reader = new FileReader();
    reader.onload = function () {
      Meteor.call(
        "uploadFile",
        fileExtension,
        reader.result,
        type,
        typeId,
        (err, result) => {
          if (err) {
            console.log(err);
          } else {
            setFileName(result);
          }
        }
      );
    };
    reader.readAsDataURL(file);
  };

  return (
    <div>
      <input name="Uploader" onChange={handleUpload} type="file" />
    </div>
  );
};

服务器端还有我的meteor方法:

Meteor.methods({
  uploadFile: async function (fileType, data, type, typeId) {
    let extension;
    let contentType = fileType;

      if (fileType.includes("jpeg") || fileType.includes("jpg")) {
        extension = "jpg";
      } else if (fileType.includes("png")) {
        extension = "png";
      } else if (fileType.includes("mp4")) {
        extension = "mp4";
      } else if (fileType.includes("audio/mpeg")) {
        contentType = "video/mp4";
        extension = "mp3";
      } else if (fileType.includes("pdf")) {
        extension = "pdf";
      } else {
        throw new Meteor.Error("format-error", "Only authorized format");
      }

      const random = Random.id();
      const key = `random.${extension}`;

      const buf =
        extension !== "mp4"
          ? Buffer.from(data.replace(/^data:image\/\w+;base64,/, ""), "base64")
          : data;

      const config = {
        Bucket: bucketName,
        Key: key,
        Body: buf,
        ContentType: contentType,
        ACL: "public-read",
      };

      if (extension !== "mp4") {
        config.ContentEncoding = "base64";
      }
      const uploadResult = await s3.upload(config).promise();
      return uploadResult.Location;

  },
});

我认为这可能是因为读者没有正确管理视频文件,但我有点迷路了。任何输入将不胜感激。谢谢。

【问题讨论】:

  • 文件不存在还是内容不好?
  • 内容显然很糟糕。这应该是一个 4 秒的视频,但我什么也得不到(0 秒)
  • 你确定onload回调在你认为的时候被触发了吗?如果你只是在加载数据后手动调用uploadFile 会发生什么?
  • 如前所述,代码适用于图像和 mp3,只是 mp4 无法正常工作。
  • @Exelian 我也可以使用 wget 获取文件,它的大小是正常的,但可以在本地播放。

标签: node.js reactjs amazon-s3 meteor aws-sdk


【解决方案1】:

我想问一下,因为我看到您的代码非常复杂。为什么要通过服务器上传文件?

我认为将文件从客户端直接推送到 S3 更有效。如果您有兴趣了解这个概念,请查看我正在维护的这个包 (https://github.com/activitree/s3up-meta)。它是对多年前经过严格测试的旧包的重写。上传由 Meteor 服务器签名,但由客户端上传。您不想让套接字/光纤忙于文件上传,同时每次上传都会输入大量数据(有关上传状态的数据)。您可能希望在用户/客户端拥有所有这些。

要注意的另一件事是在您的存储桶/管理/生命周期中设置AbortIncompleteMultipartUpload 的重要性。这是您的 S3 大小可能不受控制地增长的地方。

最后,当我上传视频时,我只是上传文件(从输入类型文件接收)。它看起来像这样:

video: File
   lastModified: 1573722339000
   lastModifiedDate: Thu Nov 14 2019 13:05:39 GMT+0400 (Gulf Standard Time) {}
   name: "IMG_7847.MOV"
   size: 20719894
   type: "video/quicktime"
   webkitRelativePath: ""

我确实使用其他帮助程序来确定文件(并限制允许上传的时间长度)和文件类型。

当您上传或/和激活 S3 端的 CloudWatch 时,您可以监控服务器端的错误,以查看失败的地方。

【讨论】:

  • 我会检查你的解决方案,我喜欢直接从客户端上传的想法,只需从服务器获得授权。
猜你喜欢
  • 2018-09-30
  • 1970-01-01
  • 1970-01-01
  • 2017-01-10
  • 2022-01-20
  • 2017-02-14
  • 2017-08-16
  • 2020-08-11
  • 2014-05-27
相关资源
最近更新 更多