Skip to content

Conversation

@devin-ai-integration
Copy link
Contributor

@devin-ai-integration devin-ai-integration bot commented Jan 9, 2026

feat: add camera utility with Picture-in-Picture support

Summary

Adds a new camera utility at /utilities/cam that allows users to access their webcam and enable Picture-in-Picture mode for a floating camera overlay that stays on top of all applications.

Key features:

  • Single "Turn Camera On" button for clean initial state
  • Camera preview with mirrored video (selfie-style)
  • Picture-in-Picture mode via browser API with auto-hiding controls
  • Comprehensive error handling with user-friendly instructions for permission denied, unsupported browsers, camera in use, etc.
  • Proper cleanup of media streams on unmount

Note: As requested, this utility is NOT added to the tools list - it's only accessible via direct URL.

Updates since last revision

  • Fixed Prettier formatting issue (minor whitespace adjustment)
  • Fixed black screen bug: Resolved race condition where video stream wasn't displaying despite camera being accessed. Added a useEffect that connects the stream to the video element after the element is rendered.
  • Fixed PIP mirroring: The page preview was mirrored (via CSS transform) but PIP showed the raw unmirrored stream. Now uses Canvas API to create a mirrored stream at the source, so both page preview and PIP show the same mirrored view.
  • Clean PIP window: Switched to standard video PIP API which has no title bar and auto-hiding controls (scrub timeline, LIVE badge appear on hover, hide when not hovering).
  • Text balance: Added text-balance to intro paragraph for nicer text wrapping.

Review & Testing Checklist for Human

  • Verify camera stream displays - After granting permission, confirm the video preview shows your camera feed (not a black rectangle)
  • Test PIP mirroring - Enable PIP, move your head left/right, verify the movement direction matches in both the page preview and PIP window
  • Test PIP controls behavior - PIP window should have no title bar; controls (scrub timeline, LIVE badge) should appear on hover and hide when not hovering
  • Test PIP functionality - Enable PIP, verify floating window appears, exit via browser X button and via "Exit Picture-in-Picture" button
  • Test error states - Deny camera permission (check error message), try with no camera connected

Recommended test plan:

  1. Navigate to /utilities/cam
  2. Click "Turn Camera On" and grant permission
  3. Verify camera preview appears mirrored (move head left, image should move left)
  4. Click "Enable Picture-in-Picture"
  5. Verify PIP window has no title bar
  6. Hover over PIP window - controls should appear; move mouse away - controls should hide
  7. Move head left/right - verify PIP mirrors the same as page preview
  8. Close PIP window, verify state returns to "active"
  9. Click "Turn Camera Off" and verify stream stops

Notes

  • The video is mirrored using Canvas API (not CSS transform) so PIP also shows mirrored view
  • Standard video PIP API provides auto-hiding controls (visible on hover) with no permanent title bar
  • No camera selection UI if user has multiple cameras (uses default/user-facing camera)
  • This feature cannot be fully tested in CI - requires manual browser testing with camera hardware

Link to Devin run: https://app.devin.ai/sessions/94a7f5eed2c040b5a8b27f3ee7efacee
Requested by: @peckz

Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
@devin-ai-integration
Copy link
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@cloudflare-workers-and-pages
Copy link

cloudflare-workers-and-pages bot commented Jan 9, 2026

Deploying jam-dev-utilities with  Cloudflare Pages  Cloudflare Pages

Latest commit: a1875f0
Status: ✅  Deploy successful!
Preview URL: https://797b3a93.jam-dev-utilities.pages.dev
Branch Preview URL: https://devin-1767949829-camera-pip.jam-dev-utilities.pages.dev

View logs

devin-ai-integration bot and others added 6 commits January 9, 2026 09:14
Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
The video element was not rendered when startCamera ran (status was 'requesting'),
so videoRef.current was null when trying to set srcObject. Added a useEffect that
connects the stream to the video element after the element is rendered.

Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
- Use Canvas API to create a mirrored video stream
- Both page preview and PIP now show the same mirrored view
- Remove CSS transform since stream is now mirrored at source
- Add proper cleanup for canvas and animation frame resources

Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
- Use Document PIP API when available (Chrome 116+)
- Creates a clean PIP window without scrub timeline or LIVE badge
- Falls back to standard PIP API for other browsers
- Add proper cleanup for Document PIP window

Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
- Switch back to standard video.requestPictureInPicture() API
- Controls (scrub timeline, LIVE badge) now auto-hide and only show on hover
- No permanent title bar like Document PIP API had
- Remove unused Document PIP code and refs

Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
Co-Authored-By: petar@jam.dev <pekiseven@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant