face-api.js icon indicating copy to clipboard operation
face-api.js copied to clipboard

Fetching external videos in browser (fetchImage for <video>)

Open pt-br opened this issue 5 years ago • 11 comments

I've ran into this issue for a couple hours and I ended up editing the dist library adding two new functions called fetchVideo and bufferToVideo that works pretty much like the fetchImage and bufferToImage functions.

I'll leave it here to help somebody else with the same issue and in case someone wants to include it on future releases.

face-api.js

...
exports.fetchVideo = fetchVideo;
...
function fetchVideo(uri) {
        return __awaiter(this, void 0, void 0, function () {
            var res, blob;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0: return [4 /*yield*/, fetchOrThrow(uri)];
                    case 1:
                        res = _a.sent();
                        return [4 /*yield*/, (res).blob()];
                    case 2:
                        blob = _a.sent();
                        if (!blob.type.startsWith('video/')) {
                            throw new Error("fetchVideo - expected blob type to be of type video/*, instead have: " + blob.type + ", for url: " + res.url);
                        }
                        return [2 /*return*/, bufferToVideo(blob)];
                }
            });
        });
    }

function bufferToVideo(buf) {
        return new Promise(function (resolve, reject) {
            if (!(buf instanceof Blob)) {
                return reject('bufferToVideo - expected buf to be of type: Blob');
            }
            var reader = new FileReader();
            reader.onload = function () {
                if (typeof reader.result !== 'string') {
                    return reject('bufferToVideo - expected reader.result to be a string, in onload');
                }
                var video = env.getEnv().createVideoElement();
                video.onloadstart = function () {
                    setTimeout(() => {
                        return resolve(video);
                    }, 100)
                };
                video.onerror = reject;
                video.type = "video/mp4";
                video.autoplay = true;
                video.src = reader.result;
            };
            reader.onerror = reject;
            reader.readAsDataURL(buf);
        });
    }

Usage example:

const videoElement = document.querySelector('video');
    const detections = await faceapi
      .detectAllFaces(await faceapi.fetchVideo(videoElement.src))
      .withFaceLandmarks()
      .withFaceDescriptors();

pt-br avatar Aug 24 '19 17:08 pt-br

@justadudewhohacks Feel free to close this issue if you want (idk if it should stay open or not)

pt-br avatar Aug 24 '19 17:08 pt-br

Thanks for your solution, if you want to open a PR contributing this method feel free :)

justadudewhohacks avatar Sep 13 '19 08:09 justadudewhohacks

is this code applicable to face-api.min.js and if so how can I implement it? Thank you!

Bea98 avatar Oct 28 '19 10:10 Bea98

@pt-br could you please tell me where to place the code properly.if i write it as stand alone methods.i am getting following error in react.Failed to compile. I changed the face-api.js still getting the below error Attempted import error: 'fetchVideo' is not exported from 'face-api.js' (imported as 'faceapi').

rajkishoreandia avatar Jan 31 '20 05:01 rajkishoreandia

Please add this feature, thanks!

msvargas avatar Jan 31 '20 15:01 msvargas

is this code applicable to face-api.min.js and if so how can I implement it? Thank you!

have u found the solution bro?

SathishSaminathan avatar Feb 12 '20 12:02 SathishSaminathan

@Bea98 @rajkishoreandia you guys need to apply this to the dist file directly, not the min. Then you can compress it if you need a .min version.

pt-br avatar Jun 19 '20 02:06 pt-br

You did do very good work, Thank you!

codepool867 avatar Nov 02 '20 12:11 codepool867

@pt-br how can you get results by frame or second?

bettysteger avatar May 21 '21 22:05 bettysteger

hello guys, pls can u explain to step by step how to apply and run this code on python app ??, pls guys , i am a new baby in python coding pls guide me, no harsh comments pls.

Ntambwe1 avatar Jan 21 '22 11:01 Ntambwe1

@Ntambwe1 hey, this is a JS plugin, so i don't know if you can run it in python?

bettysteger avatar Jan 21 '22 13:01 bettysteger