Search code examples
javascriptfirefox-os

Taking picture using FirefoxOS Camera API


I'm having some issues using the Camera API in FirefoxOS. I'm trying to take a picture like so:

var options = {
    mode: 'picture',
    recorderProfile: 'jpg',
    previewSize: {
        width: 352,
        height: 288
    }
};
function successCamera(newCamera) {
    console.log("Succeeded loading camera");
    function successPicture(pictureBlob){
        console.log("Took picture");
    }
    function errorPicture(error) { console.log("Issue taking picture " + error); }
    var picture = newCamera.takePicture(options, successPicture, errorPicture);
}
function errorCamera(error) {
    console.log("Error loading camera. " + error);
    console.warn(error);
}
navigator.mozCameras.getCamera("back", options, successCamera, errorCamera);

It's giving an error called: HardwareClosed. I can't find much about this error, so I just wanted to check on StackOverflow here and see if anyone has had issues with it / know what the problem is here.

Thanks for any help you can give!


Solution

  • HardwareClosed (maps to NS_ERROR_NOT_INITIALIZED internally) can be returned by both the getCamera and the takePicture call.

    If it is the getCamera call failing, it is likely because the camera is already opened (in this application, or in another), and it needs to be released first. In future releases of Firefox OS, this will be fixed by https://bugzilla.mozilla.org/show_bug.cgi?id=1073017 so that the new application can "take" the camera from the old.

    If it is the takePicture call failing (probably not in your case), it is because the camera was already released before you called takePicture. That would be you called release or some driver error forced the camera closed.

    Some other (unrelated) suggestions:

    Note that recorderProfile is invalid. Something like this would be more appropriate:

    var options = {
        mode: 'picture',
        recorderProfile: 'high',
        previewSize: {
            width: 352,
            height: 288
        }
    };
    

    Later versions of Firefox OS (latest 2.2, master) verify the recorderProfile and would reject the configuration if you supplied 'jpg'.

    The callback syntax was removed in later versions of the camera API, and was switched to promises and events. If you are able to upgrade your version of 2.2 to the latest (something from this year), it automatically selects the best configuration for you, i.e.:

    navigator.mozCameras.getCamera("back").then(successCamera, errorCamera);
    

    would select the closest matching preview size to your window size and the highest aspect ratio matching picture size to the chosen preview size available. This is the same way the stock camera application works.

    takePicture and getCamera use different options (some overlapping) but since you aren't using any of them for takePicture, null should suffice:

    var picture = newCamera.takePicture().then(successPicture, errorPicture);
    

    or

    var picture = newCamera.takePicture(null, successPicture, errorPicture);
    

    If you want to support both the promise and the callback API versions, you can do a trick like this application to check the Firefox OS version: https://github.com/texthtml/torch/blob/master/src/index.js#L69