Transformers

Last updated:

Media Transformers

Visulima storage provides transformers for images, videos, and audio files. Transformers support both URL-based query parameters and programmatic APIs.

Overview

Three transformer types are available:

  • ImageTransformer: Image processing with Sharp
  • VideoTransformer: Video processing with Mediabunny
  • AudioTransformer: Audio processing with Mediabunny
  • MediaTransformer: Unified transformer that automatically detects media type

Image Transformer

Transform images with resizing, cropping, format conversion, and more.

Basic Usage

import { LRUCache } from "lru-cache";
import { DiskStorage } from "@visulima/storage";
import ImageTransformer from "@visulima/storage/transformer/image";

const storage = new DiskStorage({ directory: "./uploads" });
const cache = new LRUCache({ max: 1000, ttl: 3600000 });

const transformer = new ImageTransformer(storage, {
    cache,
    maxImageSize: 10 * 1024 * 1024, // 10MB
    cacheTtl: 3600, // 1 hour
});

Resize Images

// Resize with fit mode
const result = await transformer.resize("image-id", {
    width: 800,
    height: 600,
    fit: "cover", // cover, contain, fill, inside, outside
    quality: 85,
    format: "jpeg",
});

// URL-based: GET /files/image-id?width=800&height=600&fit=cover&quality=85

Crop Images

const cropped = await transformer.crop("image-id", {
    width: 400,
    height: 300,
    left: 100,
    top: 50,
});

Convert Formats

// Convert to WebP
const webp = await transformer.convertFormat("image-id", "webp", {
    quality: 85,
    lossless: false,
});

// Convert to AVIF
const avif = await transformer.convertFormat("image-id", "avif", {
    quality: 80,
    effort: 4,
});

Advanced Transformations

// Rotate
const rotated = await transformer.rotate("image-id", {
    angle: 90,
    background: { r: 255, g: 255, b: 255 },
});

// Apply effects
const processed = await transformer.transform("image-id", {
    blur: true,
    sharpen: true,
    greyscale: true,
    gamma: 2.2,
});

Video Transformer

Transform videos with resizing, format conversion, and codec changes.

Basic Usage

import { DiskStorage } from "@visulima/storage";
import VideoTransformer from "@visulima/storage/transformer/video";

const storage = new DiskStorage({ directory: "./uploads" });

const transformer = new VideoTransformer(storage, {
    maxVideoSize: 100 * 1024 * 1024, // 100MB
    defaultCodec: "avc",
    defaultBitrate: 2_000_000, // 2 Mbps
});

Resize Videos

const result = await transformer.resize("video-id", {
    width: 1920,
    height: 1080,
    fit: "contain",
    codec: "avc",
    bitrate: 2_000_000,
});

// URL-based: GET /files/video-id?width=1920&height=1080&codec=avc&bitrate=2000000

Convert Formats

const webm = await transformer.transform("video-id", {
    format: "webm",
    codec: "vp9",
    bitrate: 1_500_000,
});

Video Codecs

Supported codecs:

  • avc - H.264/AVC
  • hevc - H.265/HEVC
  • vp8 - VP8
  • vp9 - VP9
  • av1 - AV1

Audio Transformer

Transform audio with resampling, format conversion, and codec changes.

Basic Usage

import { DiskStorage } from "@visulima/storage";
import AudioTransformer from "@visulima/storage/transformer/audio";

const storage = new DiskStorage({ directory: "./uploads" });

const transformer = new AudioTransformer(storage, {
    maxAudioSize: 50 * 1024 * 1024, // 50MB
    defaultCodec: "aac",
    defaultBitrate: 128_000, // 128 kbps
});

Resample Audio

const result = await transformer.resample("audio-id", {
    sampleRate: 44100,
    numberOfChannels: 2,
});

// URL-based: GET /files/audio-id?sampleRate=44100&numberOfChannels=2

Convert Formats

const mp3 = await transformer.transform("audio-id", {
    format: "mp3",
    codec: "mp3",
    bitrate: 192_000,
});

Audio Codecs

Supported codecs:

  • aac - AAC
  • opus - Opus
  • mp3 - MP3
  • vorbis - Vorbis
  • flac - FLAC

Media Transformer

Unified transformer that automatically detects and processes any media type.

Basic Usage

import { DiskStorage } from "@visulima/storage";
import { MediaTransformer } from "@visulima/storage/transformer";
import ImageTransformer from "@visulima/storage/transformer/image";
import VideoTransformer from "@visulima/storage/transformer/video";
import AudioTransformer from "@visulima/storage/transformer/audio";

const storage = new DiskStorage({ directory: "./uploads" });

const transformer = new MediaTransformer(storage, {
    ImageTransformer: ImageTransformer,
    VideoTransformer: VideoTransformer,
    AudioTransformer: AudioTransformer,
    cache: new LRUCache({ max: 1000, ttl: 3600000 }),
    saveTransformedFiles: true, // Persist transformed files
});

Automatic Detection

// Automatically detects media type and routes to appropriate transformer
const result = await transformer.handle("file-id", {
    width: 800,
    height: 600,
    format: "webp",
    quality: 85,
});

// Or use URL query string
const result = await transformer.fetch("file-id", "width=800&height=600&format=webp&quality=85");

URL-Based Transformations

// Image: GET /files/image-id?width=800&height=600&fit=cover&quality=85
// Video: GET /files/video-id?width=1920&height=1080&codec=avc&bitrate=2000000
// Audio: GET /files/audio-id?sampleRate=44100&codec=aac&bitrate=128000

Query Parameters

Common Parameters

ParameterTypeDescriptionExample
formatstringOutput formatjpeg, webp, mp4, mp3
qualitynumberQuality/bitrate80 (images), 2000000 (video/audio)

Image Parameters

ParameterTypeDescriptionValues
widthnumberWidth in pixels1-10000
heightnumberHeight in pixels1-10000
fitstringResize fit modecover, contain, fill, inside, outside
positionstringPosition for cover/containcentre, top, right, bottom, left
losslessbooleanLossless compression (WebP)true, false
effortnumberCPU effort (AVIF)0-10

Video Parameters

ParameterTypeDescriptionValues
widthnumberWidth in pixels1-10000
heightnumberHeight in pixels1-10000
codecstringVideo codecavc, hevc, vp8, vp9, av1
bitratenumberBitrate in bps1000000+
frameRatenumberFrame rate in Hz24, 30, 60

Audio Parameters

ParameterTypeDescriptionValues
sampleRatenumberSample rate in Hz8000, 16000, 44100, 48000
numberOfChannelsnumberNumber of channels1, 2
codecstringAudio codecaac, opus, mp3, vorbis, flac
bitratenumberBitrate in bps64000+

Caching Transformed Files

Enable persistent caching of transformed files:

const transformer = new MediaTransformer(storage, {
    ImageTransformer: ImageTransformer,
    saveTransformedFiles: true, // Save to storage
    cache: new LRUCache({ max: 1000, ttl: 3600000 }), // In-memory cache
});

Best Practices

  1. Use caching - Cache transformed files to avoid reprocessing
  2. Choose appropriate formats - WebP/AVIF for images, VP9/AV1 for videos
  3. Set quality/bitrate - Balance file size and quality
  4. Monitor processing time - Large files take longer to process
  5. Handle errors - Transformations can fail for invalid files
Support

Contribute to our work and keep us going

Community is the heart of open source. The success of our packages wouldn't be possible without the incredible contributions of users, testers, and developers who collaborate with us every day.Want to get involved? Here are some tips on how you can make a meaningful impact on our open source projects.

Ready to help us out?

Be sure to check out the package's contribution guidelines first. They'll walk you through the process on how to properly submit an issue or pull request to our repositories.

Submit a pull request

Found something to improve? Fork the repo, make your changes, and open a PR. We review every contribution and provide feedback to help you get merged.

Good first issues

Simple issues suited for people new to open source development, and often a good place to start working on a package.
View good first issues