p5.js can't handle moderate size videos

Created on 25 Sep 2018  路  2Comments  路  Source: processing/p5.js

Nature of issue?

  • [x] Found a bug
  • [x] Existing feature enhancement
  • [ ] New feature request

Most appropriate sub-area of p5.js?

  • [ ] Color
  • [ ] Core/Environment/Rendering
  • [x] Data
  • [ ] Events
  • [ ] Image
  • [ ] IO
  • [ ] Math
  • [ ] Typography
  • [ ] Utilities
  • [ ] WebGL
  • [x] Other (specify if possible)

Which platform were you using when you encountered this?

  • [ ] Mobile/Tablet (touch devices)
  • [x] Desktop/Laptop
  • [ ] Others (specify if possible)

Details about the bug:

  • p5.js version: v0.7.2
  • Web browser and version: Firefox 62
  • Operating System: Linux Mint 18.3
  • Steps to reproduce this:
    I get:
    allocation size overflow p5.dom.js:...

This bug also happens if the video is loaded from assets. In my case, it happens with video files around or over 200MB. I would understand if the video file was 2GB or even 1GB... but 200MB is real limit.

var film;
var fx,fy,fw,fh;

function setup() {
  createCanvas(windowWidth, windowHeight);
  input = createFileInput(handleFile);
  input.position(0, 0);
  noLoop();
}

function draw() {
  background(0);
  image(film,fx,fy,fw,fh);
}

function vidLoad() {
  film.play();
  var ratio = width/height;
  var fratio = film.width/film.height;
  if(ratio > fratio)//screen is more wide
  {
    fh = height;
    fw = film.width * (height/film.height);
    fy = 0;
    fx = width/2-fw/2;
  }
  else //film is wider
  {
    fw = width;
    fh = film.height * (width/film.width);
    fy = height/2-fh/2;
    fx = 0;
  }
  input.hide();
  loop()
}

function handleFile(file) { 
  print(file.type); 
  if (file.type === 'video') 
  { 
    film = createVideo(file.data,vidLoad); 
    film.hide(); 
  } 
} 

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  var ratio = width/height;
  var fratio = film.width/film.height;
  if(ratio > fratio)//screen is more wide
  {
    fh = height;
    fw = film.width * (height/film.height);
    fy = 0;
    fx = width/2-fw/2;
  }
  else //film is wider
  {
    fw = width;
    fh = film.height * (width/film.width);
    fy = height/2-fh/2;
    fx = 0;
  }
  scaleX = width/100;
  scaleY = height/100;
  trackW = width;
  trackH = height;
}

Most helpful comment

the reason it's crashing here is that p5 is trying to load the whole video into memory before creating a base64-encoded string version of it to play.

it's not directly supported (and it may not work on all browsers), but here's a way to pass an abstract url to the video element so that it will stream instead:

var film;
var fx, fy, fw, fh;

function setup() {
  createCanvas(windowWidth, windowHeight);
  input = createInput('', 'file');
  input.changed(handleFile);
  input.position(0, 0);
  noLoop();
}

function draw() {
  background(0);
  if (film) {
    image(film, fx, fy, fw, fh);
  }
}

function vidLoad() {
  film.play();
  var ratio = width / height;
  var fratio = film.width / film.height;
  if (ratio > fratio) //screen is more wide
  {
    fh = height;
    fw = film.width * (height / film.height);
    fy = 0;
    fx = width / 2 - fw / 2;
  } else //film is wider
  {
    fw = width;
    fh = film.height * (width / film.width);
    fy = height / 2 - fh / 2;
    fx = 0;
  }
  input.hide();
  loop()
}

function handleFile(event) {
  for (var file of event.target.files) {
    print(file.type);
    if (file.type.startsWith('video/')) {
      film = createVideo([URL.createObjectURL(file)], vidLoad);
      film.hide();
    }
  }
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  var ratio = width / height;
  var fratio = film.width / film.height;
  if (ratio > fratio) //screen is more wide
  {
    fh = height;
    fw = film.width * (height / film.height);
    fy = 0;
    fx = width / 2 - fw / 2;
  } else //film is wider
  {
    fw = width;
    fh = film.height * (width / film.width);
    fy = height / 2 - fh / 2;
    fx = 0;
  }
  scaleX = width / 100;
  scaleY = height / 100;
  trackW = width;
  trackH = height;
}

All 2 comments

the reason it's crashing here is that p5 is trying to load the whole video into memory before creating a base64-encoded string version of it to play.

it's not directly supported (and it may not work on all browsers), but here's a way to pass an abstract url to the video element so that it will stream instead:

var film;
var fx, fy, fw, fh;

function setup() {
  createCanvas(windowWidth, windowHeight);
  input = createInput('', 'file');
  input.changed(handleFile);
  input.position(0, 0);
  noLoop();
}

function draw() {
  background(0);
  if (film) {
    image(film, fx, fy, fw, fh);
  }
}

function vidLoad() {
  film.play();
  var ratio = width / height;
  var fratio = film.width / film.height;
  if (ratio > fratio) //screen is more wide
  {
    fh = height;
    fw = film.width * (height / film.height);
    fy = 0;
    fx = width / 2 - fw / 2;
  } else //film is wider
  {
    fw = width;
    fh = film.height * (width / film.width);
    fy = height / 2 - fh / 2;
    fx = 0;
  }
  input.hide();
  loop()
}

function handleFile(event) {
  for (var file of event.target.files) {
    print(file.type);
    if (file.type.startsWith('video/')) {
      film = createVideo([URL.createObjectURL(file)], vidLoad);
      film.hide();
    }
  }
}

function windowResized() {
  resizeCanvas(windowWidth, windowHeight);
  var ratio = width / height;
  var fratio = film.width / film.height;
  if (ratio > fratio) //screen is more wide
  {
    fh = height;
    fw = film.width * (height / film.height);
    fy = 0;
    fx = width / 2 - fw / 2;
  } else //film is wider
  {
    fw = width;
    fh = film.height * (width / film.width);
    fy = height / 2 - fh / 2;
    fx = 0;
  }
  scaleX = width / 100;
  scaleY = height / 100;
  trackW = width;
  trackH = height;
}

I'm very grateful for your response. It has helped me a lot.

I've fairly new to javascript, and I normally code in Java. p5.js is a great tool but I don't feel that the documentation in the reference and tutorials is as complete as the Java mode. Having examples for loading videos, here, which will cause an error if a moderate size video is loaded seems incomplete. The examples and other documentation should be more user-friendly or we should include a premade object/function to handle these events in the library.

Thank you

Was this page helpful?
0 / 5 - 0 ratings