p5 Video

Resources

Shiffman - 11.1: Live Video and createCapture() - p5.js
Shiffman - 11.3: The Pixel Array - p5.js
p5 Reference: Image Filter

Additional Resources:
Shiffman - 11.2: Video Photobooth - p5.js
Shiffman - 11.4: Brightness Mirror - p5.js
Shiffman - 11.5: Checkbox Mirror - p5.js
Shiffman - 11.6: Painting with Pixels - p5.js
Shiffman - 11.7: Slit-Scan Video - p5.js
Shiffman - 11.8: Video Effects with Seriously.js - p5.js

Working with Video

There is no additional p5 video library like there is for audio. Much of what we'll cover doesn't require anything other than standard p5 functionality. However, we will need the p5 DOM library in order to access the feed from the webcam, etc. So we can continue to use the following index.html file. We'll still need to be running a local server. You can download this movie file for the following demos.

<!DOCTYPE html>
<html>
  <head>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/p5.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/addons/p5.dom.min.js"></script>
   <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.0/addons/p5.sound.min.js"></script>
   <script src="sketch.js"></script>
  </head>
  <body>
   
  </body>
</html> 

Play a Video

The basic functionality for loading a video file from your assets folder and playing it in the browser is given by the createVideo() method. The first argument should contain an array of video files (best practice for cross-browser compatibility. More info on file formats here). Optionally, a callback function can be passed as the second argument. The video is shown by default, but can be hidden with .hide() and drawn into canvas using image(). Appends to the container node if one is specified, otherwise appends to body.


let fingers;

function preload() {
  // specify multiple formats for different browsers
  fingers = createVideo(['assets/fingers.mov',
                         'assets/fingers.webm']);
}

function setup() {
    fingers.loop();
}

We can pause and play by adding a button, using the .pause() and .play() methods like we did with audio.


let playing = false;
let fingers;
let button;


function setup() {
  // specify multiple formats for different browsers
  fingers = createVideo(['assets/fingers.mov',
                         'assets/fingers.webm']);
  button = createButton('play');
  button.mousePressed(toggleVid); // attach button listener
}

// plays or pauses the video depending on current state
function toggleVid() {
  if (playing) {
    fingers.pause();
    button.html('play');
  } else {
    fingers.loop();
    button.html('pause');
  }
  playing = !playing;
}

Capture Webcam

The webcam can be accessed using the createCapture() in the setup() function. This function creates a new <video> element that contains the audio/video feed from a webcam. This can be drawn onto the canvas using image().


let capture;

function setup() {
  createCanvas(320, 240);
  capture = createCapture();
  // capture.hide();
}

function draw() {
  image(capture, 0, 0, width, height);
}

Filters

The p5.Image class contains a method to assign default filters. These include THRESHOLD, GRAY, OPAQUE, INVERT, POSTERIZE, BLUR, ERODE, DILATE and BLUR


let capture;

function setup() {
  createCanvas(400, 400);
  capture = createCapture();
  capture.hide();
}

function draw() {
  image(capture, 0, 0, width, width * capture.height / capture.width);
  filter('INVERT');
}

Loading Pixels

Just like working with static images, we can access individual pixels for finer control. The pixelDensity() function sets the pixel scaling for high pixel density displays. By default pixel density is set to match display density, call pixelDensity(1) to turn this off. Calling pixelDensity() with no arguments returns the current pixel density of the sketch.


let fingers;

function setup() {
  createCanvas(320, 240);
  // specify multiple formats for different browsers
  fingers = createVideo(['assets/fingers.mov',
                         'assets/fingers.webm']);
  fingers.loop();
  fingers.hide();
  noStroke();
  fill(0);
}

function draw() {
  background(255);
  fingers.loadPixels();
  let stepSize = 8;
  // let stepSize = round(constrain(mouseX / 8, 6, 32));
  for (let y = 0; y < height; y += stepSize) {
    for (let x = 0; x < width; x += stepSize) {
      let i = y * width + x;
      let darkness = (255 - fingers.pixels[i*4]) / 255;
      let radius = stepSize * darkness;
      ellipse(x, y, radius, radius);
    }
  }
}

Other Libraries

If you wish to go beyond the default video editing functionality of p5, there are a number of JS libraries dedicated to this. One example is Seriously.js. Shiffman has a tutorial showing you how to use these effects here.