11import { setTimeout } from 'node:timers/promises' ;
2+ import { exec } from 'node:child_process' ;
23
34export async function screencast ( page , options ) {
45 const { scale, output, selector, windowWidth, windowHeight } = options ;
56
67 await page . setViewport ( {
78 width : windowWidth ,
89 height : windowHeight ,
10+ defaultScaleFactor : scale
911 } ) ;
1012
11- const clip = await page . evaluate ( selector => {
13+ const crop = await page . evaluate ( selector => {
1214 const element = document . querySelector ( selector ) ;
1315 if ( element ) {
1416 const { width, height, x, y } = element . getBoundingClientRect ( ) ;
@@ -27,18 +29,34 @@ export async function screencast(page, options) {
2729 }
2830 } , selector ) ;
2931
30- await page . setViewport ( {
31- width : Math . ceil ( clip . width ) || windowWidth ,
32- height : Math . ceil ( clip . height ) || windowHeight ,
33- } ) ;
34-
3532 const recorder = await page . screencast ( {
3633 path : output ,
37- scale,
38- clip,
34+ crop,
3935 } ) ;
4036
4137 await setTimeout ( options . time ) ;
4238 await recorder . stop ( ) ;
39+
40+ if ( options . mp4 ) {
41+ try {
42+ return await webmToMp4 ( output ) ;
43+ } catch ( e ) {
44+ throw e ;
45+ }
46+ }
47+
4348 return output ;
4449}
50+
51+ function webmToMp4 ( input ) {
52+ const output = input . replace ( '.webm' , '.mp4' ) ;
53+ return new Promise ( ( resolve , reject ) => {
54+ exec ( `echo -y | ffmpeg -i ${ input } -c:v copy ${ output } ` , ( err , stdout , stderr ) => {
55+ if ( err ) {
56+ reject ( err ) ;
57+ } else {
58+ resolve ( output ) ;
59+ }
60+ } ) ;
61+ } ) ;
62+ }
0 commit comments