v8.48.3

Video Editor exported methods

The video editor extension isn't included in the Pintura image editor product package, it's available as an upgrade on the pricing page

The extension currently doesn't support annotations, decorations, redactions, and frame styles.

The clientside video encoding is aimed at encoding short videos, it's strongly advised to use server side encoding for video's longer than a couple minutes.

Live demo of Pintura with video editor extension

The functions, properties, and defaults related to video editing that are exported by the Pintura Video module.

These exports are available on the pinturavideo module.

Export Description
createDefaultVideoWriter(options) Creates a default video writer. This is the array of processes the editor uses to write video data.
createMediaStreamEncoder(options) Creates a video encoder that uses the native MediaStream API to generate a video file.
createFFmpegEncoder(options) Creates a video encoder that uses FFmpeg WASM to generate a video file.

createDefaultVideoWriter

The createDefaultVideoWriter function returns a default video writer array. This is an array of processes the editor runs to write the output video data.

import { imageStateToCanvas } from './pintura.js';

import {
    imageStateToCanvas,
    createDefaultVideoWriter,
    createMediaStreamEncoder,
} from './pinturavideo.js';

openDefaultEditor({
    imageWriter: createDefaultVideoWriter({
        // Resize image
        targetSize: {
            width: 512,
        },

        // Use media stream encoder
        encoder: createMediaStreamEncoder({
            // Required
            imageStateToCanvas,
        }),
    }),
});

createMediaStreamEncoder

This video encoder is based on the native browser MediaStream API.

At this time this technology has some limitations:

  • The duration of the save process is equal to the trimmed video time.
  • The browser tab needs to stay active for video creation process to work.
  • If the user device is very slow the created video can have missing frames.

This works well for smaller short video's but it's most likely not an option for longer videos. For longer video's using the FFmpegEncoder is probably a better idea.

import { imageStateToCanvas } from './pintura.js';
import { createMediaStreamEncoder } from './pinturavideo.js';

openDefaultEditor({
    imageWriter: createDefaultVideoWriter({
        // Resize image
        targetSize: {
            width: 512,
        },

        // Use media stream encoder
        encoder: createMediaStreamEncoder({
            // Required
            imageStateToCanvas,

            // Default output quality
            audioBitrate: 48 * 1024,
            videoBitrate: 384 * 1024,

            // Default FPS
            framesPerSecond: 24,

            // By default logging is disabled
            log: false,
        }),
    }),
});

createFFmpegEncoder

To use the FFmpeg encoder we need to download and install FFmpeg WASM.

Please make sure to read the FFmpeg GitHub page before proceeding.

Based on the example below the FFmpeg WASM package dist folder contents should be saved to ./ffmpeg/

The FFmpeg WASM Core package dist folder contents should be saved to ./ffmpeg/core/

Resulting in the following directory structure:

example
├─ index.html
├─ pintura
├─ pintura-video
└─ ffmpeg
   ├─ core
   │  ├─ ffmpeg-core.js
   │  ├─ ffmpeg-core.wasm
   │  └─ ffmpeg-core.worker.js
   ├─ ffmpeg.min.js
   └─ ffmpeg.min.js.map
import { openDefaultEditor } from './pintura/pintura.js';
import { createFFmpegEncoder } from './pintura-video/pinturavideo.js';

openDefaultEditor({
    imageWriter: createDefaultVideoWriter({
        // Resize image
        targetSize: {
            width: 512,
        },

        // Use FFmpeg encoder
        encoder: createFFmpegEncoder({
            scriptPath: './ffmpeg/ffmpeg.min.js',
            corePath: './ffmpeg/core/ffmpeg-core.js',
            log: true,
        }),
    }),
});

FFmpeg WASM makes use of SharedArrayBuffer which is only available on webpages that are cross-origin isolated. Your server needs to return these two headers Cross-Origin-Embedder-Policy: require-corp and Cross-Origin-Opener-Policy: same-origin for SharedArrayBuffer to be available.

To enabled SharedArrayBuffer for local testing with Chrome:

Windows:

chrome --enable-features=SharedArrayBuffer

MacOS:

/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --remote-debugging-port=9222 --enable-features=SharedArrayBuffer

The FFmpeg package clocks in at 25MB so please consider the user network connection before using.

Alternatively we can generate the output video on the server, that way we bypass both the FFmpeg WASM download size and the MediaStream API limitations. Please see the FFmpeg encoder function contained in pinturavideo.js for the FFmpeg commands used.