vendure-ecommerce / vendure

The commerce platform with customization in its DNA.
https://www.vendure.io
Other
5.77k stars 1.02k forks source link

Image, video and other binary file handling (Assets) #22

Closed michaelbromley closed 6 years ago

michaelbromley commented 6 years ago

Overview

Design

A Media entity would represent all types of binary files. It would have a type discriminator whose value would be a MediaType (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 and ProductVariant entities would have the existing image string property replaced by a media property which would be a collection of Media 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:

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

michaelbromley commented 6 years ago

Configurable preview function

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.

michaelbromley commented 6 years ago

Naming

What to call the entity which can represent and image, video, or any other kind of file?

Let's go with Asset