使用 Multer Storage Cloudinary 从同一表单上传音频和图像
Upload audio and image from the same form using Multer Storage Cloudinary
我必须创建一个路由,使用 Multer Storage Cloudinary 将 1 个音频文件和 1 个图像(调整大小)上传到 Cloudinary,并将 url 和名称保存在我的 mongo 数据库中。
当我尝试上传音频文件时出现错误“无效图像文件”(即使我删除 transformation
并在 allowedFormats
.
中添加“mp3”
云端代码:
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_KEY,
api_secret: process.env.CLOUDINARY_SECRET
});
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: 'nono',
// transformation: [
// {width: 500, height: 500, crop: "fill"}
// // ],
// allowedFormats: ['jpeg', 'png', 'jpg', 'mp3']
}
});
module.exports = { cloudinary, storage }
路线代码:
router.route("/")
.get(catchAsync(sounds.index));
.post(isLoggedIn, upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]), joiValidationSounds, catchAsync(sounds.newSound));
module.exports.newSound = async (req, res) => {
const sound = new Sound(req.body.sound);
console.log(req.files)
sound.image.url = req.files["sound[image]"][0].path;
sound.image.filename = req.files["sound[image]"][0].filename;
sound.audio.url = req.files["sound[audio]"][0].path;
sound.audio.filename = req.files["sound[audio]"][0].filename;
sound.author = req.user._id;
await sound.save();
req.flash("success", "Se ha añadido un nuevo sonido.");
res.redirect(`/sounds/categories/:category/${sound._id}`);
}
表单代码:
<form action="/sounds" method="POST" novalidate class="validated-form" enctype="multipart/form-data">
<div class="row mb-3">
<label for="audio" class="col-sm-2 col-form-label">Audio:</label>
<div class="col-sm-10">
<input type="file" name="sound[audio]" id="audio">
</div>
</div>
<div class="row mb-3">
<label for="image" class="col-sm-2 col-form-label">Imagen:</label>
<div class="col-sm-10">
<input type="file" name="sound[image]" id="image">
</div>
</div>
<button type="submit" class="btn btn-success">Crear</button>
<button type="reset" class="btn btn-success">Limpiar</button>
</form>
我可以上传 2 张图片而不会有问题。我还检查了 Cloudinary 是否支持 mp3 文件。
编辑:我成功上传了带有 resource_type: 'video', allowedFormats: ['mp3'],
和 2 个不同存储的音频。
但是现在当我尝试上传两者时出现错误“意外字段”。
新密码:
const storageAudio = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'nono',
format: 'mp3',
resource_type: 'video',
allowedFormats: ['mp3'],
}
});
const storageImage = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'nono',
transformation: [
{width: 500, height: 500, crop: "fill"}
],
format: 'jpg',
resource_type: 'image',
allowedFormats: ['jpeg', 'png', 'jpg']
}
});
module.exports = { cloudinary, storageImage, storageAudio };
const multer = require("multer");
const { storageImage, storageAudio } = require("../cloudinary");
const uploadAudio = multer({ storage: storageAudio });
const uploadImage = multer({ storage: storageImage });
router.route("/")
.get(catchAsync(sounds.index))
.post(isLoggedIn,
// uploadAudio.fields([{ name: 'sound[audio]', maxCount: 1 }]), uploadImage.fields([{ name: 'sound[image]', maxCount: 1 }]),
uploadAudio.single("sound[audio]"),
uploadImage.single("sound[image]"),
// upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]),
joiValidationSounds, catchAsync(sounds.newSound)
);
向Cloudinary上传文件时,其中一个上传参数是resource_type
,告诉Cloudinary如何处理传入的文件。可能的值为 'image'、'video'、'raw'(非图像、非视频)或 'auto'(上传后将打开文件以检查类型)
如果您在上传视频时遇到 Invalid image file
错误,很可能意味着上传调用中的 resource_type 设置为 'image',并查看您正在使用的插件的回购协议,似乎是这样的:https://github.com/affanshahid/multer-storage-cloudinary/issues/13
您可能需要联系插件维护者,看看他们是否可以在未来的版本中允许覆盖资源类型,或者分叉插件以允许在配置中覆盖资源类型
或者,您可以直接使用 Cloudinary 的 SDK 来执行上传,而使用 multer
只是为了让上传的文件可用于您的代码。在这种情况下,Cloudinary SDK 在上传时默认使用 resource_type "auto",如果需要,您可以在自己的代码中覆盖该值
终于找到了一个图片和音频同时上传的方案(一存一表):
1) 将参数设置为 resource_type: 'auto',
并将 allowedFormats
设置为您要上传的所有格式。
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: 'nono',
resource_type: 'auto',
allowedFormats: ['jpeg', 'png', 'jpg', 'mp3'],
transformation: [
{width: 500, height: 500, crop: "fill"}
]
}
});
2)使用upload.fields
upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]),
我必须创建一个路由,使用 Multer Storage Cloudinary 将 1 个音频文件和 1 个图像(调整大小)上传到 Cloudinary,并将 url 和名称保存在我的 mongo 数据库中。
当我尝试上传音频文件时出现错误“无效图像文件”(即使我删除 transformation
并在 allowedFormats
.
云端代码:
const cloudinary = require('cloudinary').v2;
const { CloudinaryStorage } = require('multer-storage-cloudinary');
cloudinary.config({
cloud_name: process.env.CLOUDINARY_CLOUD_NAME,
api_key: process.env.CLOUDINARY_KEY,
api_secret: process.env.CLOUDINARY_SECRET
});
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: 'nono',
// transformation: [
// {width: 500, height: 500, crop: "fill"}
// // ],
// allowedFormats: ['jpeg', 'png', 'jpg', 'mp3']
}
});
module.exports = { cloudinary, storage }
路线代码:
router.route("/")
.get(catchAsync(sounds.index));
.post(isLoggedIn, upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]), joiValidationSounds, catchAsync(sounds.newSound));
module.exports.newSound = async (req, res) => {
const sound = new Sound(req.body.sound);
console.log(req.files)
sound.image.url = req.files["sound[image]"][0].path;
sound.image.filename = req.files["sound[image]"][0].filename;
sound.audio.url = req.files["sound[audio]"][0].path;
sound.audio.filename = req.files["sound[audio]"][0].filename;
sound.author = req.user._id;
await sound.save();
req.flash("success", "Se ha añadido un nuevo sonido.");
res.redirect(`/sounds/categories/:category/${sound._id}`);
}
表单代码:
<form action="/sounds" method="POST" novalidate class="validated-form" enctype="multipart/form-data">
<div class="row mb-3">
<label for="audio" class="col-sm-2 col-form-label">Audio:</label>
<div class="col-sm-10">
<input type="file" name="sound[audio]" id="audio">
</div>
</div>
<div class="row mb-3">
<label for="image" class="col-sm-2 col-form-label">Imagen:</label>
<div class="col-sm-10">
<input type="file" name="sound[image]" id="image">
</div>
</div>
<button type="submit" class="btn btn-success">Crear</button>
<button type="reset" class="btn btn-success">Limpiar</button>
</form>
我可以上传 2 张图片而不会有问题。我还检查了 Cloudinary 是否支持 mp3 文件。
编辑:我成功上传了带有 resource_type: 'video', allowedFormats: ['mp3'],
和 2 个不同存储的音频。
但是现在当我尝试上传两者时出现错误“意外字段”。
新密码:
const storageAudio = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'nono',
format: 'mp3',
resource_type: 'video',
allowedFormats: ['mp3'],
}
});
const storageImage = new CloudinaryStorage({
cloudinary: cloudinary,
params: {
folder: 'nono',
transformation: [
{width: 500, height: 500, crop: "fill"}
],
format: 'jpg',
resource_type: 'image',
allowedFormats: ['jpeg', 'png', 'jpg']
}
});
module.exports = { cloudinary, storageImage, storageAudio };
const multer = require("multer");
const { storageImage, storageAudio } = require("../cloudinary");
const uploadAudio = multer({ storage: storageAudio });
const uploadImage = multer({ storage: storageImage });
router.route("/")
.get(catchAsync(sounds.index))
.post(isLoggedIn,
// uploadAudio.fields([{ name: 'sound[audio]', maxCount: 1 }]), uploadImage.fields([{ name: 'sound[image]', maxCount: 1 }]),
uploadAudio.single("sound[audio]"),
uploadImage.single("sound[image]"),
// upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]),
joiValidationSounds, catchAsync(sounds.newSound)
);
向Cloudinary上传文件时,其中一个上传参数是resource_type
,告诉Cloudinary如何处理传入的文件。可能的值为 'image'、'video'、'raw'(非图像、非视频)或 'auto'(上传后将打开文件以检查类型)
如果您在上传视频时遇到 Invalid image file
错误,很可能意味着上传调用中的 resource_type 设置为 'image',并查看您正在使用的插件的回购协议,似乎是这样的:https://github.com/affanshahid/multer-storage-cloudinary/issues/13
您可能需要联系插件维护者,看看他们是否可以在未来的版本中允许覆盖资源类型,或者分叉插件以允许在配置中覆盖资源类型
或者,您可以直接使用 Cloudinary 的 SDK 来执行上传,而使用 multer
只是为了让上传的文件可用于您的代码。在这种情况下,Cloudinary SDK 在上传时默认使用 resource_type "auto",如果需要,您可以在自己的代码中覆盖该值
终于找到了一个图片和音频同时上传的方案(一存一表):
1) 将参数设置为 resource_type: 'auto',
并将 allowedFormats
设置为您要上传的所有格式。
const storage = new CloudinaryStorage({
cloudinary,
params: {
folder: 'nono',
resource_type: 'auto',
allowedFormats: ['jpeg', 'png', 'jpg', 'mp3'],
transformation: [
{width: 500, height: 500, crop: "fill"}
]
}
});
2)使用upload.fields
upload.fields([{ name: 'sound[audio]', maxCount: 1 }, { name: 'sound[image]', maxCount: 1 }]),