You are browsing as a guest. Sign up (or log in) to start making projects!

10h 44m 2s logged

I met with some friends to discuss my app…and realized I gotta lock in with the features. Among the various topics we discussed like the difficult UI or lack of automatic updates, they really wanted remote control features. So, I set out to make the remote display something I can actually touch, click, and type into. And patching some other bugs along the way.


9. Remote input

This is the main headline feature. Streaming pixels one way was solved; now the client had to send input back up the wire and have the host replay it as if it came from real hardware.

Host side (Windows). A new input backend injects events through a synthetic pointer device, so mouse, touch, and pen all seem real as opposed to faked mouse moves. The synthetic device can execute touch or mouse movements from the tablet client. macOS and Linux backends are stubbed and will come later (trust me bro).

The wire. This side had to be optimized for dead-low latency like the rest of the project. Instead of passing strings or using some wrapper library, I made my own binary protocol (a dedicated protocol module) serialized over WebRTC data channels, not the media path. Client-side input.js captures keyboard, mouse, pointer (touch/pen), wheel, clipboard, and drag-drop and ships them across. The code basically catches every single frontend input event and forwards all those events (20+)! The routing is latency-first, same as everything else, with three different paths. fast-path events (pointer moves, wheel) take an unreliable channel, where a dropped packet is cheaper than a late one, while clicks, keys, and clipboard take the reliable channel where every event must land exactly once. It’s not that big of a deal if one small mouse delta doesn’t go through, but it definitely is a big deal if a click doesn’t go through.


10. Browser compatibility detections

Not every browser can do WebCodecs, secure contexts, or the input paths above. Rather than fail silently, I added a compatibility check on both the browser and client up front. It shows compatibility modals with per-feature lists to ensure the user knows what’s going on.


11. Some more small fixes

I added two quality-of-life additions: avatars (upload custom profile pictures) and zoom controls (ctrl/cmd +/-).


12. Encoders that don’t explode when funny stuff happens

Oh my god…one of the biggest issues by far. When I ran the NVIDIA encoder at high FPS, it didn’t crash. However, the Intel Quick Sync encoder would arbitrarily crash at high FPS and wouldn’t give a reason why. I audited a buncha different parts of my code and eventually found that FPS was the issue, not resolution or low-latency flags.

Hence, I added a binary search that probes the hardware for its true maximum supported fps and clamps to it before the encoder can choke. Essentially, I ask the encoder “can you do 1920x1080 at 240 fps?” –> “no” –> “what about 120 fps?” –> “yes” –> “what about 180 fps?”. This keeps repeating till the max FPS is found and streamed to the client.

Rounding out the release, I made a variety of different UI fixes like the modal fixes, backdrop overlap, a stray uninstall-modal backdrop, and cloud reconfig errors. More progress to come!

0
3

Comments 0

No comments yet. Be the first!