#node.js #reactjs #amazon-s3 #meteor #aws-sdk
#node.js #reactjs #amazon-s3 #метеор #aws-sdk
Вопрос:
У меня возникла проблема с загрузкой файлов mp4 в мою корзину s3 в моем проекте react / meteor. Это работает для файлов другого типа (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;
},
});
Я думаю, что это может быть связано с тем, что читатель неправильно управляет видеофайлами, но я немного заблудился. Любой вклад будет оценен. Спасибо.
Комментарии:
1. Файл отсутствует или содержимое плохое?
2. контент, по-видимому, плохой. Предполагается, что это 4-секундное видео, и я ничего не получаю (0 секунд)
3. Вы уверены
onload
, что обратный вызов запускается, когда вы думаете, что это так? Что произойдет, если вы просто вручную вызоветеuploadFile
после загрузки данных?4. как уже упоминалось, код работает для изображений и mp3, только mp4 как-то не работает.
5. @Exelian также я могу получить файл с помощью wget, и его размер нормальный, но он может воспроизводиться локально.
Ответ №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: ""
Я использую другие помощники для определения файла (и ограничения продолжительности разрешенных загрузок) и типа файла.
Вы можете отслеживать ошибки на стороне вашего сервера при загрузке или / и активировать CloudWatch на стороне S3, чтобы увидеть, где что-то не работает.
Комментарии:
1. Я проверю ваше решение, мне нравится идея загружать напрямую с клиента, просто получив авторизацию с сервера.