capture.ts 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import type { CDPSession, Page } from "@playwright/test"
  2. import type { CapturedFrame } from "./model"
  3. export type VisualCapture = {
  4. session: CDPSession
  5. frames: CapturedFrame[]
  6. startedAtEpoch: number
  7. running: boolean
  8. capture: Promise<void>
  9. }
  10. export async function startVisualCapture(page: Page, startedAtEpoch: number) {
  11. if (process.env.OPENCODE_STABILITY_CAPTURE !== "1") return
  12. const session = await page.context().newCDPSession(page)
  13. await session.send("Page.enable")
  14. const recording: VisualCapture = {
  15. session,
  16. frames: [],
  17. startedAtEpoch,
  18. running: true,
  19. capture: Promise.resolve(),
  20. }
  21. recording.capture = (async () => {
  22. try {
  23. while (recording.running && recording.frames.length < 900) {
  24. const frame = await session.send("Page.captureScreenshot", {
  25. format: "jpeg",
  26. quality: 80,
  27. captureBeyondViewport: false,
  28. optimizeForSpeed: true,
  29. })
  30. recording.frames.push({ at: Date.now() - recording.startedAtEpoch, data: frame.data })
  31. await new Promise((resolve) => setTimeout(resolve, 50))
  32. }
  33. } catch {
  34. recording.running = false
  35. }
  36. })()
  37. return recording
  38. }
  39. export async function stopVisualCapture(recording: VisualCapture | undefined) {
  40. if (!recording) return []
  41. recording.running = false
  42. try {
  43. await recording.capture
  44. } finally {
  45. await recording.session.detach().catch(() => undefined)
  46. }
  47. return recording.frames
  48. }