5

Is there a callback function for p5.js’ createCapture function fails? (i.e. when user permission is denied or video camera stream is unsupported by user browser).

I notice in the src there is a success callback, but can’t seem to find one for failure. In the browser console, p5 also reports ‘DOMException: Permission denied’, however, I would like to handle this in a more user-friendly fashion.

If there is no callback, what is the best practice for handling media failure with createCapture as it doesn’t seem to be discussed in the docs.

Ryan Achten
  • 495
  • 4
  • 21
  • OP poses a good question. P5 continues to run while it's waiting for user permission or if user permission is denied, this seems detrimental to the design of programs. An example might include a slitscan app waiting for video - positioning of video in slitscan will start moving even thought there is no video displayed. When user does give permission, video will appear to start in the wrong position. – garrettlynchirl Sep 12 '19 at 13:49
  • @garrettlynch a issue for this was raised on the p5 Github repo. https://github.com/processing/p5.js/issues/2706 Unsure of the status for this, but I believe the later releases of p5 solved my particular scenario (hard to remember as this was a while ago now) – Ryan Achten Sep 14 '19 at 06:15
  • perhaps I'm missing something, are you sure that issue is the same issue? image() and createImage() don't trigger a browser permissions request (the cause of the delay) and if createImage() is being populated with loadImage() that can be fired within a preload() function to ensure it's loaded before setup() and draw(). Anyway posted a solution as the issue is still present in latest builds. – garrettlynchirl Sep 15 '19 at 08:25
  • @garrettlynch I'm not 100% sure, to be honest as I can't remember the context for this issue. Your solution looks like it would do the job. Will mark as the answer to this question for others to use until p5 implements a proper callback. – Ryan Achten Sep 16 '19 at 20:51
  • A hacky solution is to intercept `console.log` to watch for the message – Andrew Mar 15 '21 at 17:52

2 Answers2

1

Ok so this answer is more than a year late but posting this as it may be useful for others stuck on the same issue. Rather than error testing the capture itself as suggested in comments below or perhaps reworking createCapture() (best done through opening an issue request if you feel it should be changed) I suggest testing the pixels array of the capture and only if it has been set then proceeding with doing whatever your script does. This could be done simply like so:

//load pixel data of webcam capture
cap.loadPixels();

//all values in the pixel array start as zero so just test if they are 
//greater than zero 
if (cap.pixels[1] > 0)
{
    //put the rest of your script here
}

A full example of this in action is below:

var canvas;
var cap;
var xpos = 0;

function setup()
{
    canvas = createCanvas(windowWidth, windowHeight);
    canvas.style("display", "block");
    background("#666666");

    //create an instance of the webcam
    cap = createCapture(VIDEO);

    cap.size(640, 480);
    cap.hide();
}


function draw()
{
    //load pixel data of webcam capture
    cap.loadPixels();

    //if the first pixel's R value is set continue with the rest of the script
    if (cap.pixels[1] > 0)
    {
        var w = cap.width;
        var h = cap.height;

        copy(cap, w/2, 0, 10, h, xpos, (height / 2) - (h / 2), 10, h);

        xpos = xpos + 1;

        if (xpos > width) xpos = 0;
    }
}
garrettlynchirl
  • 790
  • 8
  • 23
-1

I believe you can use a try and catch to detect when you get an error. Something like this:

try{
  capture = createCapture(VIDEO);
}
catch(error){
  // error handling here
}

More info on W3Schools and MDN.

Kevin Workman
  • 41,537
  • 9
  • 68
  • 107
  • Hmm perhaps it’s because I’m using p5 in instance mode, however, try/catch doesn’t to work for me in this circumstance - the catch block never gets executed. i.e. `let video; try{ video = myP5.createCapture(myP5.VIDEO); } catch(error){ console.log('err', error); }` – Ryan Achten Apr 30 '18 at 21:45
  • @RyanAchten Upon further inspection of [the source](https://raw.githubusercontent.com/lmccart/p5.js/master/lib/addons/p5.dom.js), I realize that this will only catch the case when `getUserMedia` is not supported by the browser. – Kevin Workman Apr 30 '18 at 22:03
  • Ah, OK. It seems strange that p5 has no provision for this, since the function uses getUserMedia() which itself has an error callback. Any other thoughts on how to handle this properly? – Ryan Achten Apr 30 '18 at 22:32
  • @RyanAchten You could take the source for `createCapture()` and modify it to include an error callback. – Kevin Workman Apr 30 '18 at 22:36