Nightmare Js Evaluation 在多次求值后超时
Nightmare Js Evaluation timed out after multiple evaluations
我正在尝试设置我一直在开发的应用程序,该应用程序涉及录制 HTML 小部件(带动画)并将其转换为 mp4。在本地效果很好。我用 Nightmare Js 处理屏幕截图,并使用 FFMPEG 将屏幕截图转换为 mp4,这在我的 PC 上需要大约 90 秒。
我正在通过托管服务将其设置在 docker 容器中,但无法解决此问题。我的测试脚本现在看起来像这样:
const Nightmare = require('nightmare')
const Xvfb = require('xvfb')
module.exports = function(app) {
app.get('/api/nightmare', async (req, res) => {
console.log('GET request to /api/nightmare')
try {
// Start xvfb and create our nightmare object
const close = await xvfb()
const nightmare = Nightmare({ executionTimeout: 1000 })
const [err, result] = await poss(run(nightmare))
if (err) {
// Cleanup before throwing error
await nightmare.end()
await close()
throw err
}
// shut'er down
await nightmare.end()
await close()
res.status(200).send('Completed')
} catch (error) {
console.log(error)
res.status(500).send(error)
}
})
}
async function run(nightmare) {
var data = {
'id': '2OWBTMUL',
'somedata': 'blah'
// More data pulled from the database goes here
}
// Create folder to hold images
var procName = new Date().getTime() + '_testing_' + data.id
fs.mkdirSync(path.resolve(__dirname, '../processing/', procName))
// URL to inject into webpage so the webpage can access the data
var url = `http://example.com?` +
`id=${data.id}&` +
`somedata=${data.somedata}`
console.log('Starting NightmareJs')
await nightmare
.viewport(1920, 1080)
.goto('file:///' + path.resolve(__dirname, '../templates/example.html'))
.evaluate(newUrl => {
// Set url and get the page ready for recording
url = new URL(newUrl)
initiate()
start()
timeline.pause()
}, url)
.catch(error => { console.log(error) })
// Take 200 screenshots (8s @ 25fps)
var frames = 200
for (var i = 0; i < frames; i++) {
console.log('Taking screenshot ' + i)
await nightmare
.screenshot(path.resolve(__dirname, '../processing/', procName, 'screen_' + i + '.png'))
.evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
.catch(error => { console.log(error) })
}
console.log('Done.')
}
// xvfb wrapper
function xvfb(options) {
var xvfb = new Xvfb(options)
function close() {
return new Promise((resolve, reject) => {
xvfb.stop(err => (err ? reject(err) : resolve()))
})
}
return new Promise((resolve, reject) => {
xvfb.start(err => (err ? reject(err) : resolve(close)))
})
}
// try/catch helper
async function poss(promise) {
try {
const result = await promise
return [null, result]
} catch (err) {
return [err, null]
}
}
一些环境细节:
Ubuntu 18.04.1
主管
节点 8.12.0(DEBUG=* 设置)
问题:
在大约 17 个循环之后,Nightmare 会抛出两个不同的错误。
在我的 nodejs-stderr.log 文件中,我得到了这个
Taking screenshot x
Error: Evaluation timed out after 1000msec. Are you calling done() or resolving your promises?
在评估中使用 done() 回调或承诺进行测试没有改变任何东西,所以我保持简单
在我的 nodejs-stdout.log 文件中,每次成功的循环我都会得到这个
Mon, 19 Nov 2018 09:37:06 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log Highlighting page to trigger rendering.
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot() captured with length 1092963
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:07 GMT nightmare running
然后在 17 个左右的循环之后,我得到:
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log Highlighting page to trigger rendering.
Tue, 20 Nov 2018 02:11:43 GMT nightmare:log crashed [{},false]
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log FrameManager timing out after 1000 ms with no new rendered frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .screenshot() captured with length 0
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:13 GMT nightmare running
其余的都失败了,没有 crashed [{},false]
消息。
在循环中删除 .evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
解决了问题,但我需要它,否则它只是一个静止的视频!我尝试过单独调用(不链接评估和屏幕截图),将 .wait(200) 放在东西之间,但我无法弄清楚或找不到有关此问题的任何帮助。
原来是共享内存太小了。我假设当图像全部加载时它超过了内存限制并且 Electron 崩溃了。将共享内存从64MB增加到128MB后,问题解决。
我正在尝试设置我一直在开发的应用程序,该应用程序涉及录制 HTML 小部件(带动画)并将其转换为 mp4。在本地效果很好。我用 Nightmare Js 处理屏幕截图,并使用 FFMPEG 将屏幕截图转换为 mp4,这在我的 PC 上需要大约 90 秒。
我正在通过托管服务将其设置在 docker 容器中,但无法解决此问题。我的测试脚本现在看起来像这样:
const Nightmare = require('nightmare')
const Xvfb = require('xvfb')
module.exports = function(app) {
app.get('/api/nightmare', async (req, res) => {
console.log('GET request to /api/nightmare')
try {
// Start xvfb and create our nightmare object
const close = await xvfb()
const nightmare = Nightmare({ executionTimeout: 1000 })
const [err, result] = await poss(run(nightmare))
if (err) {
// Cleanup before throwing error
await nightmare.end()
await close()
throw err
}
// shut'er down
await nightmare.end()
await close()
res.status(200).send('Completed')
} catch (error) {
console.log(error)
res.status(500).send(error)
}
})
}
async function run(nightmare) {
var data = {
'id': '2OWBTMUL',
'somedata': 'blah'
// More data pulled from the database goes here
}
// Create folder to hold images
var procName = new Date().getTime() + '_testing_' + data.id
fs.mkdirSync(path.resolve(__dirname, '../processing/', procName))
// URL to inject into webpage so the webpage can access the data
var url = `http://example.com?` +
`id=${data.id}&` +
`somedata=${data.somedata}`
console.log('Starting NightmareJs')
await nightmare
.viewport(1920, 1080)
.goto('file:///' + path.resolve(__dirname, '../templates/example.html'))
.evaluate(newUrl => {
// Set url and get the page ready for recording
url = new URL(newUrl)
initiate()
start()
timeline.pause()
}, url)
.catch(error => { console.log(error) })
// Take 200 screenshots (8s @ 25fps)
var frames = 200
for (var i = 0; i < frames; i++) {
console.log('Taking screenshot ' + i)
await nightmare
.screenshot(path.resolve(__dirname, '../processing/', procName, 'screen_' + i + '.png'))
.evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
.catch(error => { console.log(error) })
}
console.log('Done.')
}
// xvfb wrapper
function xvfb(options) {
var xvfb = new Xvfb(options)
function close() {
return new Promise((resolve, reject) => {
xvfb.stop(err => (err ? reject(err) : resolve()))
})
}
return new Promise((resolve, reject) => {
xvfb.start(err => (err ? reject(err) : resolve(close)))
})
}
// try/catch helper
async function poss(promise) {
try {
const result = await promise
return [null, result]
} catch (err) {
return [err, null]
}
}
一些环境细节:
Ubuntu 18.04.1
主管
节点 8.12.0(DEBUG=* 设置)
问题: 在大约 17 个循环之后,Nightmare 会抛出两个不同的错误。 在我的 nodejs-stderr.log 文件中,我得到了这个
Taking screenshot x
Error: Evaluation timed out after 1000msec. Are you calling done() or resolving your promises?
在评估中使用 done() 回调或承诺进行测试没有改变任何东西,所以我保持简单
在我的 nodejs-stdout.log 文件中,每次成功的循环我都会得到这个
Mon, 19 Nov 2018 09:37:06 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log Highlighting page to trigger rendering.
Mon, 19 Nov 2018 09:37:06 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot() captured with length 1092963
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:07 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:07 GMT nightmare running
然后在 17 个左右的循环之后,我得到:
Mon, 19 Nov 2018 09:37:07 GMT nightmare:actions .screenshot()
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log subscribing to browser window frames
Mon, 19 Nov 2018 09:37:07 GMT nightmare:log Highlighting page to trigger rendering.
Tue, 20 Nov 2018 02:11:43 GMT nightmare:log crashed [{},false]
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log FrameManager timing out after 1000 ms with no new rendered frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:log unsubscribing from browser window frames
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .screenshot() captured with length 0
Mon, 19 Nov 2018 09:37:12 GMT nightmare:actions .evaluate() fn on the page
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "screenshot"
Mon, 19 Nov 2018 09:37:13 GMT nightmare queueing action "evaluate"
Mon, 19 Nov 2018 09:37:13 GMT nightmare running
其余的都失败了,没有 crashed [{},false]
消息。
在循环中删除 .evaluate(shot => { timeline.seek((8 / 200) * shot) }, i)
解决了问题,但我需要它,否则它只是一个静止的视频!我尝试过单独调用(不链接评估和屏幕截图),将 .wait(200) 放在东西之间,但我无法弄清楚或找不到有关此问题的任何帮助。
原来是共享内存太小了。我假设当图像全部加载时它超过了内存限制并且 Electron 崩溃了。将共享内存从64MB增加到128MB后,问题解决。