Closed michaelbromley closed 6 years ago
Use case I just came across:
Developer is building a shop selling audio clips (e.g. samples for musicians). Wants to attach an audio file to a Product, but wants the preview image to be a waveform of that audio file.
To allow this, we need to have a configurable generatePreview
function which takes the file as an argument and outputs an image.
The default function would be simple - it would resize the source image to some maximum-allowed resolution and for non-image files it would do something sensible like outputting a "file" image with the filename overlaid.
In the above use-case, the developer would be free to write his or her own generatePreview
function which is able to use whatever logic is needed for generating a waveform image.
What to call the entity which can represent and image, video, or any other kind of file?
Let's go with Asset
Overview
Design
A
Media
entity would represent all types of binary files. It would have atype
discriminator whose value would be aMediaType
(image, video, etc).Physical storage
The Media entity would have a pointer to the actual binary file somewhere on a disk. The physical storage location should be configurable - it should not have to reside on the same machine as the Vendure API server. (look into existing Node libs which abstract away the file system).
Previews / thumbnails
There should be a built-in way to generate different sizes of image whilst preserving the original. This could be generalized into a "preview" (or better name) property which would be a collection of one or more
MediaPreview
entities. This would also then handle the case for preview images of videos, pdfs and other file types.Another way would be to have a single "preview" image which can be resized on-the-fly with query parameters. These generated previews would then be cached so that the re-sampling only need take place for the initial call. This is much simpler but has performance implications.
Maybe the way to go would be to automatically generate a default set of previews (according to some config), and then further permutations can be generated on the fly.
It would be good to abstract the actual image-manipulation lib away so that the image processing capabilities can be extended by the developer, so in essence we pass through the query string to the configured "image plugin" which can then pass off the work to some library. For example, a developer may want to use ImageMagick rather than a JavaScript-based lib for improved performance.
Linking with other entities
The
Product
andProductVariant
entities would have the existingimage
string property replaced by amedia
property which would be a collection ofMedia
entities.Additionally, the custom fields API should be extended to allow Media fields with optional
type
filter.Where there is more than 1 Media entity, there must be a way to choose the "default" one, i.e. the image to show in a list view of Products, for example.
This could be done by:
defaultMedia
property which stores the id of one of the linked Media entities.I would tend to favour the first solution, since it is more explicit.
Media browser
A media browser is a UI component which is used in the admin-ui to select an existing Media entity. As a first implementation this would be akin to the media browser in WordPress - essentially a flat (no folders), filterable list of all Media entities.
For large shops this might become unwieldy - our reference shop has over 6,000 individual images. Therefore a future extension will have to address the issue of organizing large media collections, with folders or tags or something like that.
References