justadudewhohacks/face-api.js
在 GitHub 查看Fetching external videos in browser (fetchImage for <video>)
Open
#392 建立於 2019年8月24日
enhancementgood first issuehelp wanted
描述
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();