MCPcopy Create free account
hub / github.com/UsefulSoftwareCo/executor / recordGuestScreen

Function recordGuestScreen

e2e/src/vm/desktop.ts:153–237  ·  view source on GitHub ↗
(
  ip: string,
  seconds: number,
  localMp4: string,
  os: "macos" | "linux" | "windows",
)

Source from the content-addressed store, hash-verified

151 * but a missing one shouldn't fail the run. Run it concurrently with the drive.
152 */
153export const recordGuestScreen = async (
154 ip: string,
155 seconds: number,
156 localMp4: string,
157 os: "macos" | "linux" | "windows",
158): Promise<void> => {
159 if (os === "windows") {
160 // Windows can't screenshot the interactive desktop from an SSH session, so
161 // we film the VM framebuffer directly via QEMU's `screendump` (the dockur
162 // host runs the loop + ffmpeg; we pull the mp4). Host/container/storage come
163 // from env (no baked-in host); best-effort, so skip filming if unconfigured.
164 const host = process.env.E2E_DESKTOP_WIN_HOST;
165 const storage = process.env.E2E_DESKTOP_WIN_STORAGE;
166 if (!host || !storage) return;
167 const container = process.env.E2E_DESKTOP_WIN_CONTAINER ?? "exec-win";
168 const frames = Math.max(8, seconds * 4);
169 const py = `import socket,time
170s=socket.socket(socket.AF_UNIX); s.connect("/run/shm/monitor.sock"); time.sleep(0.2); s.recv(65536)
171for i in range(${frames}):
172 s.sendall(("screendump /storage/frames/f%03d.ppm\\n"%i).encode()); time.sleep(0.2)
173 try: s.recv(65536)
174 except Exception: pass`;
175 const b64 = Buffer.from(py).toString("base64");
176 const remote =
177 `S=${storage}; rm -rf "$S/frames"; mkdir -p "$S/frames"; ` +
178 `docker exec ${container} python3 -c "import base64;exec(base64.b64decode('${b64}'))"; ` +
179 `ffmpeg -y -framerate 4 -i "$S/frames/f%03d.ppm" -pix_fmt yuv420p -movflags +faststart "$S/win.mp4" >/dev/null 2>&1`;
180 await execFileP("ssh", ["-o", "ConnectTimeout=10", host, remote], {
181 maxBuffer: 16 * 1024 * 1024,
182 }).catch(() => undefined);
183 await execFileP("scp", [
184 "-o",
185 "ConnectTimeout=10",
186 `${host}:${storage}/win.mp4`,
187 localMp4,
188 ]).catch(() => undefined);
189 return;
190 }
191
192 if (os === "linux") {
193 const remote = "/tmp/executor-desktop-vm.mp4";
194 await guestSsh(
195 ip,
196 `rm -f ${remote}; DISPLAY=:99 ffmpeg -y -f x11grab -video_size 1280x800 -framerate 15 ` +
197 `-i :99 -t ${seconds} -pix_fmt yuv420p ${remote} >/tmp/ffmpeg.log 2>&1`,
198 ).catch(() => undefined);
199 // The mostly-flat console compresses small under x264 — a real capture is
200 // ~30-60KB, a blank/failed one only a few KB.
201 if ((await guestFileSize(ip, remote)) > 12_000) {
202 await guestScpFrom(ip, remote, localMp4).catch(() => undefined);
203 }
204 return;
205 }
206
207 const remoteMov = "/tmp/executor-desktop-vm.mov";
208 // Warm the capture subsystem — the first screencapture after the display comes
209 // up can produce nothing.
210 await guestSsh(ip, "screencapture -x /tmp/.warm.png 2>/dev/null; rm -f /tmp/.warm.png").catch(

Callers 1

runFunction · 0.90

Calls 4

guestSshFunction · 0.85
guestFileSizeFunction · 0.85
guestScpFromFunction · 0.85
toStringMethod · 0.80

Tested by 1

runFunction · 0.72