I have Vue Storefront system + Magento 2. I need to get links to videos that are on the Magento side. The file code that I attach below is responsible for getting the images. How can it be modified so that it can receive links to mp4 videos?
import {downloadImage, fit, identify, resize} from '../lib/image';
import mime from 'mime-types';
import URL from 'url';
import Redis from '../lib/redis';
const SUPPORTED_ACTIONS = ['fit', 'resize', 'identify'];
const SUPPORTED_MIMETYPES = ['image/gif', 'image/png', 'image/jpeg', 'image/webp', 'image/svg+xml'];
const ONE_YEAR = 31557600000;
const client = new Redis({ expire: process.env.REDIS_CACHE_EXPIRE_IMAGE || 1800 });
const asyncMiddleware = fn => (req, res, next) => {
Promise.resolve(fn(req, res, next)).catch(next);
};
export default ({ config, db }) =>
asyncMiddleware(async (req, res, body) => {
if (!(req.method == 'GET')) {
res.set('Allow', 'GET');
return res.status(405).send('Method Not Allowed');
}
req.socket.setMaxListeners(config.imageable.maxListeners || 50);
let width
let height
let action
let imgUrl
if (req.query.url) { // url provided as the query param
imgUrl = decodeURIComponent(req.query.url)
width = parseInt(req.query.width)
height = parseInt(req.query.height)
action = req.query.action
} else {
let urlParts = req.url.split('/');
width = parseInt(urlParts[1]);
height = parseInt(urlParts[2]);
action = urlParts[3];
imgUrl = `${config[config.platform].imgUrl}/${urlParts.slice(4).join('/')}`; // full original image url
if (urlParts.length < 4) {
return res.status(400).send({
code: 400,
result: 'Please provide following parameters: /img/<width>/<height>/<action:fit,resize,identify>/<relative_url>'
});
}
}
if (isNaN(width) || isNaN(height) || !SUPPORTED_ACTIONS.includes(action)) {
return res.status(400).send({
code: 400,
result: 'Please provide following parameters: /img/<width>/<height>/<action:fit,resize,identify>/<relative_url> OR ?url=&width=&height=&action='
});
}
if (width > config.imageable.imageSizeLimit || width < 0 || height > config.imageable.imageSizeLimit || height < 0) {
return res.status(400).send({
code: 400,
result: `Width and height must have a value between 0 and ${config.imageable.imageSizeLimit}`
});
}
if (!isImageSourceHostAllowed(imgUrl, config.imageable.whitelist)) {
return res.status(400).send({
code: 400,
result: `Host is not allowed`
});
}
const mimeType = mime.lookup(imgUrl);
if (mimeType === false || !SUPPORTED_MIMETYPES.includes(mimeType)) {
return res.status(400).send({
code: 400,
result: 'Unsupported file type'
});
}
console.log(`[URL]: ${imgUrl} - [ACTION]: ${action} - [WIDTH]: ${width} - [HEIGHT]: ${height}`);
const key = `${imgUrl}/${width}/${height}/${action}`
let cachedImage = ''
if (client.isConnected()) {
client.get(key)
.then(img => {
if (img !== null) {
cachedImage = Buffer.from(img, 'base64')
return sendImage(res, mimeType, cachedImage)
}
})
}
getImageBuffer(res, req, imgUrl).then(buffer => {
if (res.statusCode !== 400 && !cachedImage) {
imagePrepare(buffer, res, action, width, height)
.then(img => {
if (client.isConnected()) {
client.set(key, img.toString('base64'))
}
return sendImage(res, mimeType, img)
})
}
})
});
function sendImage (res, mimeType, img) {
return res
.type(mimeType)
.set({'Cache-Control': `max-age=${ONE_YEAR}`})
.send(img)
}
async function getImageBuffer (res, req, imgUrl) {
try {
return await downloadImage(imgUrl);
} catch (err) {
try {
if(/.webp/?$/.test(imgUrl) && req.body.beforeImageFormat) {
const newImgUrl = imgUrl.replace(/.webp/, req.body.beforeImageFormat)
return await downloadImage(newImgUrl)
} else {
throw new Error(err)
}
} catch (error) {
return res.status(400).send({
code: 400,
result: `Unable to download the requested image ${imgUrl}`
});
}
}
}
async function imagePrepare(buffer, res, action, width, height) {
try {
switch (action) {
case 'resize':
return resize(buffer, width, height)
case 'fit':
return fit(buffer, width, height)
case 'identify':
return identify(buffer)
default:
return Promise.reject(new Error('Unknown action'))
}
} catch (e) {
return Promise.reject(new Error(e.message))
}
}
function _isUrlWhitelisted(url, whitelistType, defaultValue, whitelist) {
if (arguments.length != 4) throw new Error('params are not optional!');
if (whitelist && whitelist.hasOwnProperty(whitelistType)) {
const requestedHost = URL.parse(url).host;
const matches = whitelist[whitelistType].map(allowedHost => {
allowedHost = allowedHost instanceof RegExp ? allowedHost : new RegExp(allowedHost);
return !!requestedHost.match(allowedHost);
});
return matches.indexOf(true) > -1;
} else {
return defaultValue;
}
}
function isImageSourceHostAllowed(url, whitelist) {
return _isUrlWhitelisted(url, 'allowedHosts', true, whitelist);
}
If I add type in SUPPORTED_MIMETYPES:
const SUPPORTED_MIMETYPES = ['image/gif', 'image/png', 'image/jpeg', 'image/webp', 'image/svg+xml', 'video/mp4'];
The system issues an errors:
UnhandledPromiseRejectionWarning: Error: Input buffer contains unsupported image format
UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.