gpt4 book ai didi

javascript - 尝试使用 PhantomJS 让 Affectiva 在 Node.js 上运行

转载 作者:太空宇宙 更新时间:2023-11-04 01:46:55 25 4
gpt4 key购买 nike

Affectiva有a JavaScript SDK for the web ,但没有 Node.js 的模块。我试图让它们与 headless 浏览器一起工作,比如 PhantomJS。 (注意:有 a third-party Affectiva module on npm ,但那是针对 their REST API 的,而不是我要使用的 SDK。)

我已经设置了一个测试页面,这样我就可以在 PhantomJS 和 Chrome 67 中测试相同的代码。但是我在 PhantomJS 端遇到了一个错误,我似乎无法调试。 答案是否像“PhantomJS 不完全支持 Image、ImageData 或 Uint8ClampedArray 类?” 我能找到的唯一线索是 Object.keys() 在 Chrome 和 PhantomJS 之间为这些类提供了不同的结果。也许 Affectiva 的 SDK 依赖于 Object.keys() 并且错误就是由此导致的?

预先感谢您提供任何有用的见解。

客户端:

<!DOCTYPE html>
<html>
<body>
<canvas id='canvas' width='640' height='800'></canvas>

<script src='https://download.affectiva.com/js/3.2/affdex.js'></script>

<script>

function startProcessing() {
console.log('initialized');
if (typeof window.callPhantom === 'function') {
window.callPhantom('initialized');
}
}

function saveResults(faces, image, timestamp) {
console.log('timestamp:', timestamp);
if (typeof window.callPhantom === 'function') {
window.callPhantom(faces);
}
}

function catchError(image, timestamp, err_detail) {
if (typeof window.callPhantom === 'function') {
window.callPhantom({error: err_detail});
}
}

function processFrame(imgUrl) {

var img = new Image(); // Create new img element
img.addEventListener('load', function() {
console.log('img:', img);
// In Chrome: img: object <img crossorigin scr="https://example.com/face.jpg">
// In PhantomJS: img: [object HTMLImageElement]

context.drawImage(img, 0, 0);

// Get imageData object.
var imageData = context.getImageData(0, 0, 640, 800);
console.log('imageData:', typeof(imageData), imageData, Object.keys(imageData));
// In Chrome: imageData: object ImageData{data: Uint8ClampedArray(2048000), width: 640, height: 800} ["data"]
// In PhantomJS: imageData: object [object ImageData] height,width,data

// Remove prototype attributes that PhantomJS includes in Object.keys() (DOESN'T HELP)
delete imageData.data.length;
delete imageData.data.byteOffset;
delete imageData.data.byteLength;
delete imageData.data.buffer;
var uint8caKeys = Object.keys(imageData.data).sort().reverse();

console.log('imageData.data:', typeof(imageData.data), imageData.data, uint8caKeys.length, uint8caKeys.slice(0,6), imageData.data[1985161]);
// In Chrome: imageData.data: object Uint8ClampedArray(2048000) [42, 36, 25, 255...] 2048000 ["999999", "999998", "999997", "999996", "999995", "999994"] 232
// In PhantomJS: imageData.data: object [object Uint8ClampedArray] 2048004 length,byteOffset,byteLength,buffer,999999,999998,999997,999996,999995,999994 230
// Extra whitespace added by me

//Process the frame
detector.process(imageData, 0);
// In Chrome: saveResults() triggered with expected data
// In PhantomJS: catchError() triggered with CALLBACK: "worker code reported an exceptionTypeError: Cannot convert \"undefined\" to int"

}, false);
img.setAttribute('crossOrigin', '');
img.src = imgUrl;

}

var aCanvas = document.getElementById("canvas");
var context = aCanvas.getContext('2d');
var detector = new affdex.PhotoDetector(affdex.FaceDetectorMode.LARGE_FACES);
detector.detectAllEmotions();
detector.detectAllAppearance();
detector.addEventListener('onInitializeSuccess', startProcessing);
detector.addEventListener('onInitializeFailure', catchError);
detector.addEventListener('onImageResultsSuccess', saveResults);
detector.addEventListener('onImageResultsFailure', catchError);
detector.start();

</script>

</body>
</html>

服务器端:

const instance = await phantom.create();
const page = await instance.createPage();
await page.on('onResourceRequested', (requestData) => {
console.info('Requesting', requestData.url);
// PhantomJS seems to be downloading all the correct scripts
});

page.on('onConsoleMessage', msg => {
console.log('CONSOLE: ' + msg);
});

page.on('onCallback', data => {
console.log('CALLBACK: ' + JSON.stringify(data));

if (data==='initialized') {

page.evaluate(function(imgUrl){
processFrame(imgUrl);
}, 'https://example.com/face.jpg');

}
});

const openStatus = await page.open('http://localhost:1337/affectiva-test');
if (openStatus==='success') {
exits.success();
} else {
exits.error(openStatus);
}

最佳答案

寻找替代的 headless 浏览器似乎就是答案。正如@Vaviloff 建议的那样,我切换到 Puppeteer 。最大的变化是数据无法像 window.callPhantom() 那样简单地从客户端页面传递回 Node.js 应用程序。在此示例中,我使用 console.log() 发送字符串化对象。 @Vaviloff 建议让客户端页面向服务器发出 AJAX 回调。我还不清楚哪个会表现更好。

客户端:

<!DOCTYPE html>
<html>
<body>
<canvas id='canvas' width='640' height='800'></canvas>
<script src='https://download.affectiva.com/js/3.2/affdex.js'></script>

<script>

function startProcessing() {
console.log('initialized');
}

function saveResults(faces, image, timestamp) {
delete faces[0].emojis;
console.log('result:', JSON.stringify(faces[0]));
}

function catchError(image, timestamp, err_detail) {
console.log(err_detail);
}

function processFrame(imgUrl, timestamp) {
var img = new Image();
img.addEventListener('load', function() {
context.drawImage(img, 0, 0);
var imageData = context.getImageData(0, 0, 640, 800);
detector.process(imageData, timestamp);

}, false);
img.setAttribute('crossOrigin', '');
img.src = imgUrl;
}

console.log('initializing');
var aCanvas = document.getElementById("canvas");
var context = aCanvas.getContext('2d');
var detector = new affdex.PhotoDetector(affdex.FaceDetectorMode.LARGE_FACES);
detector.detectAllEmotions();
detector.detectAllAppearance();
detector.addEventListener('onInitializeSuccess', startProcessing);
detector.addEventListener('onInitializeFailure', catchError);
detector.addEventListener('onImageResultsSuccess', saveResults);
detector.addEventListener('onImageResultsFailure', catchError);
detector.start();

</script>

</body>
</html>

服务器端:

// If you are analyzing video (instead of images), avoid the default, bundled Chromium browser, since it doesn't support MP4
// const browser = await puppeteer.launch({executablePath: '/path/to/Chrome'});

const browser = await puppeteer.launch();
const page = await browser.newPage();

page.on('console', msg => {
if (msg.text()==='initialized') {
page.evaluate(
(imgUrl, timestamp) => processFrame(imgUrl, timestamp),
'https://example.com/face.jpg',
0
);
}
console.log('PAGE LOG:', msg.text());
});
await page.goto('http://localhost:1337/affectiva-test');

exits.success();

关于javascript - 尝试使用 PhantomJS 让 Affectiva 在 Node.js 上运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51112509/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com