npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

editly-faster

v1.0.0

Published

fork from mifi/editly 0.6.3 version

Downloads

7

Readme

editly 🏄‍♀️

demo

This GIF / YouTube was created with this command: "editly commonFeatures.json5". See more examples here.

Editly is a tool and framework for declarative NLE (non-linear video editing) using Node.js and ffmpeg. Editly allows you to easily and programmatically create a video from a set of clips, images, audio and titles, with smooth transitions and music overlaid.

Editly has a simple CLI for quickly assembling a video from a set of clips or images, or you can use its more flexible JavaScript API.

Inspired by ffmpeg-concat, editly is much faster and doesn't require much storage because it uses streaming editing. Editly aims to be very extensible and feature rich with a pluggable interface for adding new dynamic content.

Features

  • Edit videos with code! Declarative API with fun defaults
  • Create colorful videos with random colors generated from aesthetically pleasing palettes and random effects
  • Supports any input size, e.g. 4K video and DSLR photos
  • Can output to any dimensions and aspect ratio, e.g. Instagram post (1:1), Instagram story (9:16), YouTube (16:9), or any other dimensions you like.
  • Content is scaled and letterboxed automatically, even if the input aspect ratio is not the same and the framerate will be converted.
  • Speed up / slow down videos automatically to match the cutFrom/cutTo segment length with each clip's duration
  • Overlay text and subtitles on videos, images or backgrounds
  • Accepts custom HTML5 Canvas / Fabric.js JavaScript code for custom screens or dynamic overlays
  • Render custom GL shaders (for example from shadertoy)
  • Can output GIF
  • Preserve audio sources or mix multiple
  • Overlay transparent images or videos
  • Show different sub-clips for parts of a clips duration (B-roll)

Use cases

  • Create a slideshow from a set of pictures with text overlay
  • Create a fast-paced trailer or promo video
  • Create a tutorial video with help text
  • Create news stories
  • Simply convert a video to a GIF
  • Resize video to any size or framerate and with automatic letterboxing/cropping (e.g. if you need to upload a video somewhere but the site complains Video must be 1337x1000 30fps)

See examples

Requirements

  • Node.js installed (Use of the latest stable version is recommended)
  • Should work on Windows, MacOS and Linux. Needs at least Node.js v12.16.2 on MacOS (see issue). See also: https://github.com/stackgl/headless-gl#system-dependencies
  • (Linux) may require some extra steps. See headless-gl.

Make sure you have ffmpeg and ffprobe installed and available in PATH

Installing

npm i -g editly

Usage: Command line video editor

Run editly --help for usage

Create a simple randomized video edit from videos, images and text with an audio track:

editly \
  title:'My video' \
  clip1.mov \
  clip2.mov \
  title:'My slideshow' \
  img1.jpg \
  img2.jpg \
  title:'THE END' \
  --fast \
  --audio-file-path /path/to/music.mp3

Or create an MP4 (or GIF) from a JSON or JSON5 edit spec (JSON5 is just a more friendly JSON format):

editly my-editly.json5 --fast --out output.gif

For examples of how to make a JSON edit spec, see below or https://github.com/mifi/editly/tree/master/examples

When you run with --fast or fast: true, it will render a much quicker low-resolution preview ⏩

Without --fast it will default to using the width, height and frame rate from the first input video. All other clips will be converted to these dimensions. You can of course override any or all of these parameters.

TIP: Use this tool in conjunction with LosslessCut

TIP: If you need catchy music for your video, have a look at this YouTube or the YouTube audio library. Then use youtube-dl to download the video, and then point --audio-file-path at the video file. Be sure to respect their license!

JavaScript library

const editly = require('editly');

// See editSpec documentation
await editly(editSpec)
  .catch(console.error);

Edit spec

Edit specs are JavaScript / JSON objects describing the whole edit operation with the following structure:

{
  outPath,
  width,
  height,
  fps,
  defaults: {
    duration: 4,
    transition: {
      duration: 0.5,
      name: 'random',
    },
    layer: {
      fontPath,
      // ...more layer defaults
    },
    layerType: {
      'fill-color': {
        color: '#ff6666',
      }
      // ...more per-layer-type defaults
    },
  },
  audioFilePath,
  loopAudio: false,
  keepSourceAudio: false,
  allowRemoteRequests: false,
  clips: [
    {
      transition,
      duration,
      layers: [
        {
          type,
          // ...more layer-specific options
        }
        // ...more layers
      ],
    }
    // ...more clips
  ],

  // Testing options:
  enableFfmpegLog: false,
  verbose: false,
  fast: false,
}

Parameters

| Parameter | CLI equivalent | Description | Default | | |-|-|-|-|-| | outPath | --out | Output path (mp4, mkv), can also be a .gif | | | | width | --width | Width which all media will be converted to | 640 | | | height | --height | Height which all media will be converted to | auto based on width and aspect ratio of first video | | | fps | --fps | FPS which all videos will be converted to | First video FPS or 25 | | | audioFilePath | --audio-file-path | Set an audio track for the whole video | | | | loopAudio | --loop-audio | Loop the audio track if it is shorter than video? | false | | | keepSourceAudio | --keep-source-audio | Keep audio from source files | false | | | allowRemoteRequests | --allow-remote-requests | Allow remote URLs as paths | false | | | fast | --fast, -f | Fast mode (low resolution and FPS, useful for getting a quick preview) | false | | | defaults.layer.fontPath | --font-path | Set default font to a .ttf | System font | | | defaults.layer.* | | Set any layer parameter that all layers will inherit | | | | defaults.duration | --clip-duration | Set default clip duration for clips that don't have an own duration | 4 | sec | | defaults.transition | | An object { name, duration } describing the default transition. Set to null to disable transitions | | | | defaults.transition.duration | --transition-duration | Default transition duration | 0.5 | sec | | defaults.transition.name | --transition-name | Default transition type. See Transition types | random | | | clips[] | | List of clip objects that will be played in sequence. Each clip can have one or more layers. | | | | clips[].duration | | Clip duration. See defaults.duration. If unset, the clip duration will be that of the first video layer. | defaults.duration | | | clips[].transition | | Specify transition at the end of this clip. See defaults.transition | defaults.transition | | | clips[].layers[] | | List of layers within the current clip that will be overlaid in their natural order (final layer on top) | | | | clips[].layers[].type | | Layer type, see below | | | | clips[].layers[].visibleFrom | | What time into the clip should this layer start | | sec | | clips[].layers[].visibleUntil | | What time into the clip should this layer stop | | sec |

Transition types

transition.name can be any of gl-transitions, or any of the following: directional-left, directional-right, directional-up, directional-down and random.

Layer types

See examples and commonFeatures.json5

Layer type 'video'

For video layers, if parent clip.duration is specified, the video will be slowed/sped-up to match clip.duration. If cutFrom/cutTo is set, the resulting segment (cutTo-cutFrom) will be slowed/sped-up to fit clip.duration. If the layer has audio, it will be kept (and mixed with other audio layers if present.)

| Parameter | Description | Default | | |-|-|-|-| | path | Path to video file | | | | resizeMode | See Resize modes | | | | cutFrom | Time value to cut from | 0 | sec | | cutTo | Time value to cut to | end of video | sec | | backgroundColor | Background of letterboxing | #000000 | | | mixVolume | Relative volume when mixing this video's audio track with others | 1 | |

Layer type 'audio'

Audio layers will be mixed together. If cutFrom/cutTo is set, the resulting segment (cutTo-cutFrom) will be slowed/sped-up to fit clip.duration. The slow down/speed-up operation is limited to values between 0.5x and 100x.

| Parameter | Description | Default | | |-|-|-|-| | path | Path to audio file | | | | cutFrom | Time value to cut from | 0 | sec | | cutTo | Time value to cut to | clip.duration | sec | | mixVolume | Relative volume when mixing this audio track with others | 1 | |

Layer type 'image'

Full screen image

| Parameter | Description | Default | | |-|-|-|-| | path | Path to image file | | | | resizeMode | See Resize modes | | |

See also See Ken Burns parameters.

Layer type 'image-overlay'

Image overlay with a custom position and size on the screen.

| Parameter | Description | Default | | |-|-|-|-| | path | Path to image file | | | | position | See Position parameter | | | | width | Width (from 0 to 1) where 1 is screen width | | | | height | Height (from 0 to 1) where 1 is screen height | | |

See also Ken Burns parameters.

Layer type 'title'

  • fontPath - See defaults.layer.fontPath
  • text - Title text to show, keep it short
  • textColor - default #ffffff
  • position - See Position parameter

See also Ken Burns parameters

Layer type 'subtitle'

  • fontPath - See defaults.layer.fontPath
  • text - Subtitle text to show
  • textColor - default #ffffff

Layer type 'title-background'

Title with background

  • text - See type title
  • textColor - See type title
  • background - { type, ... } - See type radial-gradient, linear-gradient or fill-color
  • fontPath - See type title

Layer type 'news-title'

  • fontPath - See defaults.layer.fontPath
  • text
  • textColor - default #ffffff
  • backgroundColor - default #d02a42
  • position - See Position parameter

Layer type 'slide-in-text'

  • fontPath - See defaults.layer.fontPath
  • text
  • fontSize
  • charSpacing
  • color
  • position - See Position parameter

Layer type 'fill-color', 'pause'

  • color - Color to fill background, default: randomize

Layer type 'radial-gradient'

  • colors - Array of two colors, default: randomize

Layer type 'linear-gradient'

  • colors - Array of two colors, default: randomize

Layer type 'rainbow-colors'

🌈🌈🌈

Layer type 'canvas'

See customCanvas.js

  • func - Custom JavaScript function

Layer type 'fabric'

See customFabric.js

  • func - Custom JavaScript function

Layer type 'gl'

Loads a GLSL shader. See gl.json5 and rainbow-colors.frag

  • fragmentPath
  • vertexPath (optional)

Resize modes

resizeMode - How to fit image to screen. Can be one of contain, contain-blur, cover, stretch. Default contain-blur.

See image.json5

Position parameter

Certain layers support the position parameter

position can be one of either:

  • top, bottom center, top-left, top-right, center-left, center-right, bottom-left, bottom-right
  • An object { x, y, originX = 'left', originY = 'top' }, where { x: 0, y: 0 } is the upper left corner of the screen, and { x: 1, y: 1 } is the lower right corner, x is relative to video width, y to video height. originX and originY are optional, and specify the position's origin (anchor position) of the object.

See position.json5

Ken Burns parameters

| Parameter | Description | Default | | |-|-|-|-| | zoomDirection | Zoom direction for Ken Burns effect: in, out or null to disable | | | | zoomAmount | Zoom amount for Ken Burns effect | 0.1 | |

Troubleshooting

  • If you get Error: The specified module could not be found., try: npm un -g editly && npm i -g --build-from-source editly (see #15)
  • If you get an error about gl returning null, see Requirements.
  • If you get an error /bin/sh: pkg-config: command not found, try to use newest Node.js LTS version

Donate 🙏

This project is maintained by me alone. The project will always remain free and open source, but if it's useful for you, consider supporting me. :) It will give me extra motivation to improve it.

Paypal

See also

  • https://github.com/transitive-bullshit/awesome-ffmpeg
  • https://github.com/h2non/videoshow
  • https://github.com/transitive-bullshit/ffmpeg-concat
  • https://github.com/sjfricke/awesome-webgl
  • https://www.mltframework.org/docs/melt/

Made with ❤️ in 🇳🇴

More apps by mifi.no

Follow me on GitHub, YouTube, IG, Twitter for more awesome content!