tungs / timecut

Node.js program to record smooth movies of web pages with JavaScript animations
BSD 3-Clause "New" or "Revised" License
623 stars 72 forks source link

[BUG] Errors with data attribute or normal id selectors when screen record as a video html element content from server or local files #67

Open florinvirdol opened 2 years ago

florinvirdol commented 2 years ago

Describe the bug

From a Node.js script with puppeteer and timecut libraries i'm trying to screen record as a video specific html element content based on CSS selector from a web page headless mode. Page is hosted on server or loaded locally from filesystem from the same folder as the script.

Still, i'm unable to do that, because i receive different errors:

  1. Error when trying to use an data attribute selector like selector: '[data-lpid="posterContainer"]' error is: Error: Evaluation failed: TypeError: Cannot read properties of null (reading 'getBoundingClientRect')
  2. Also, when trying to use an id selector like selector: '#some-existing-id ' i get this error: Error: Evaluation failed: DOMException: Failed to execute 'querySelector' on 'Document': '#some-existing-id is not a valid selector.
  3. On same simple pages from local servers with div and video element inside, i receive Error: Execution context was destroyed, most likely because of a navigation
  4. When trying to load local index.html file from the same folder, i tried without path as normal index.html or with full path file:///C:/zFVStuff/cms/poc-cms-video-poster-render-download/basic-puppeteer/test-local-lpac-files/index.html but i'm receiving: TimeoutError: Navigation timeout of 30000 ms exceeded at C:\zFVStuff\DentsuSRC\liveposter\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\LifecycleWatcher.js:142:21

    To Reproduce

Please List: From Windows 10 (or Ubuntu), through Node.js script (the official basic example script) fails when trying use selector like the ones from above.

Expected behavior A video recorded only with that element content i expected to see.

Attachments and Screenshots If applicable to a local, publicly unavailable web site, upload a minimal reproducible example. Also if applicable, add screenshots to help explain your problem.

Desktop (please complete the following information):

Additional context Add any other context about the problem here.

My code:

const timecut = require('timecut');
timecut({
    // url: 'https://tungs.github.io/amuse/truchet-tiles/#autoplay=true&switchStyle=random',
    //  // url: 'http://127.0.0.1:5500/puppeteer-timecut-element-screen-recorder.html',
    // https://www.pexels.com/video/drone-footage-of-a-surfer-barrelling-a-wave-12715991,
    // url: 'https://www.youtube.com/watch?v=t8ljgrq0YEk',
    url: 'http://localhost:3000',
    viewport: {
        width: 1920,               // sets the viewport (window size) to 800x600
        height: 1080
    },
    // selector: '#container',     // crops each frame to the bounding box of '#container'
    selector: '[data-lpid="posterContainer"]',     // crops each frame to the bounding box of '#container'
    // selector: '#some-existing-id',     
    // selector: '#player-theater-container', // for youtube.com    
    // selector: '#player',     // for pexels.com
    left: 20, top: 40,          // further crops the left by 20px, and the top by 40px
    right: 6, bottom: 30,       // and the right by 6px, and the bottom by 30px
    fps: 30,                    // saves 30 frames for each virtual second
    // duration: 20,               // for 20 virtual seconds 
    duration: 10,               // for 20 virtual seconds 
    output: 'video-timecut.mp4',         // to video.mp4 of the current working directory
    // headless: false,
    executablePath: 'C:/Program Files (x86)/Google/Chrome/Application/chrome.exe',
}).then(function () {
    console.log('Done!');
});

Example of html code that i want to record:

// html... head... body... (removed for brevity)...

<div id="some-existing-id" data-lpid="posterContainer">
    <video crossorigin="" src="/some-video.mp4" preload="auto" autoplay="" muted
        style="width: 100%; height: 100%;"></video>
    <div class="css-animated-text">
        some CSS animated text
    </div>
</div>

// ... removed for brevity

Detailed errors:

Page loaded
Capturing Frame 1 to C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\timecut-temp-1661987464345\image-000000001.png...
Capturing Frame 2 to C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\timecut-temp-1661987464345\image-000000002.png...
Capturing Frame 3 to C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\timecut-temp-1661987464345\image-000000003.png...
Capturing Frame 4 to C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\timecut-temp-1661987464345\image-000000004.png...
Error: Execution context was destroyed, most likely because of a navigation.
    at rewriteError (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:167:15)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ExecutionContext._evaluateInternal (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:120:56)
    at async ExecutionContext.evaluate (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:48:12)
    at async runInAllFrames (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\utils.js:49:7)
    at async run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:253:9)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
Page loaded
Error: Evaluation failed: TypeError: Cannot read properties of null (reading 'getBoundingClientRect')
    at __puppeteer_evaluation_script__:3:18
    at ExecutionContext._evaluateInternal (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:122:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ExecutionContext.evaluate (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:48:12)
    at async Object.beforeCapture (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\capture-screenshot.js:45:22)
    at async run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:277:9)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
  -- ASYNC --
    at ExecutionContext.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:111:15)
    at DOMWorld.evaluate (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\DOMWorld.js:112:20)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
  -- ASYNC --
    at Frame.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:111:15)
    at Page.evaluate (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\Page.js:860:43)
    at Page.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:112:23)
    at getSelectorDimensions (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\utils.js:87:15)
    at Object.beforeCapture (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\capture-screenshot.js:45:28)
    at Object.fn (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:199:29)
    at run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:277:27)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
Error: Evaluation failed: TypeError: Cannot read properties of null (reading 'getBoundingClientRect')
    at __puppeteer_evaluation_script__:3:18
    at ExecutionContext._evaluateInternal (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:122:13)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async ExecutionContext.evaluate (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\ExecutionContext.js:48:12)
    at async Object.beforeCapture (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\capture-screenshot.js:45:22)
    at async run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:277:9)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
  -- ASYNC --
imesnap\node_modules\puppeteer\lib\helper.js:111:15)
e_modules\puppeteer\lib\DOMWorld.js:112:20)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
  -- ASYNC --
    at Frame.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:111:15)
    at Page.evaluate (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\Page.js:860:43)
    at Page.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:112:23)
    at getSelectorDimensions (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\utils.js:87:15)
    at Object.beforeCapture (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\lib\capture-screenshot.js:45:28)
    at Object.fn (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:199:29)
    at run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:277:27)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
node:fs:1390
  handleErrorFromBinding(ctx);
  ^

Error: ENOENT: no such file or directory, scandir 'C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\timecut-temp-1661963724406'
    at Object.readdirSync (node:fs:1390:3)
    at deleteFolder (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:54:6)
    at module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:244:5)
    at processTicksAndRejections (node:internal/process/task_queues:96:5) {
  errno: -4058,
  syscall: 'scandir',
  code: 'ENOENT',
  path: 'C:\\zFVStuff\\DentsuSRC\\liveposter\\cms\\poc-cms-video-poster-render-download\\basic-puppeteer\\timecut-temp-1661963724406'
}
DevTools listening on ws://127.0.0.1:58924/devtools/browser/026aedc3-de58-47d6-b2f7-283c6c427d05
Capture Mode: Screenshot
Going to file://C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\test-local-lpac-files\index.html...
[0901/193102.224:INFO:CONSOLE(45)] "[object Object] [object Object]", source: file:///C:/zFVStuff/DentsuSRC/liveposter/cms/poc-cms-video-poster-render-download/basic-puppeteer/test-local-lpac-files/bundle.js (45)
TimeoutError: Navigation timeout of 30000 ms exceeded
    at C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\LifecycleWatcher.js:142:21
  -- ASYNC --
    at Frame.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:111:15)
    at Page.goto (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\Page.js:672:49)
    at Page.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:112:23)
    at run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:175:18)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
TimeoutError: Navigation timeout of 30000 ms exceeded
    at C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\LifecycleWatcher.js:142:21
  -- ASYNC --
    at Frame.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:111:15)
    at Page.goto (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\Page.js:672:49)
    at Page.<anonymous> (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\node_modules\puppeteer\lib\helper.js:112:23)
    at run (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:175:18)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timesnap\index.js:287:5)
    at async module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:210:7)
node:fs:1390
  handleErrorFromBinding(ctx);
  ^

0107'
    at deleteFolder (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:54:6)
    at module.exports (C:\zFVStuff\cms\poc-cms-video-poster-render-download\basic-puppeteer\node_modules\timecut\index.js:244:5) {
  errno: -4058,
  syscall: 'scandir',
  code: 'ENOENT',
  path: 'C:\\zFVStuff\\cms\\poc-cms-video-poster-render-download\\basic-puppeteer\\test-local-lpac-files\\recorded-videos\\timecut-temp-1662049860107'
}

Great job with the library!!!

Thank you very much in advance for any help!

tungs commented 2 years ago

I tried to recreate this issue, and once I got a working setup, I didn't see those issues. I used your sample setup page (though with Ubuntu 22.04, though I don't think that makes much of a difference), and could select using both the data attribute and #some-existing-id.

However, along the way, I did get some of the same errors, though that's from errors in my testing setup. Maybe you're running into the same issues.

So just to verify:

Aside: CSS Animations

From your example page, you have a div for CSS animated text. timeweb / timesnap / timecut doesn't handle CSS animations, so that part may not render as intended.